Add more support for UAVs and SRV miplevel access

Change-Id: Iefb44f59041c31d45db5c89131f70d6c76376622
Bug: skia:10446
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/396158
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Jim Van Verth 2021-04-13 14:03:28 -04:00 committed by Skia Commit-Bot
parent 532b799173
commit 4d10e4566c
8 changed files with 64 additions and 14 deletions

View File

@ -701,6 +701,10 @@ void GrD3DCaps::FormatInfo::InitFormatFlags(const D3D12_FEATURE_DATA_FORMAT_SUPP
if (SkToBool(D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RESOLVE & formatSupport.Support1)) {
*flags = *flags | kResolve_Flag;
}
if (SkToBool(D3D12_FORMAT_SUPPORT1_TYPED_UNORDERED_ACCESS_VIEW & formatSupport.Support1)) {
*flags = *flags | kUnorderedAccess_Flag;
}
}
static bool multisample_count_supported(ID3D12Device* device, DXGI_FORMAT format, int sampleCount) {
@ -814,6 +818,11 @@ bool GrD3DCaps::isFormatRenderable(DXGI_FORMAT format, int sampleCount) const {
return sampleCount <= this->maxRenderTargetSampleCount(format);
}
bool GrD3DCaps::isFormatUnorderedAccessible(DXGI_FORMAT format) const {
const FormatInfo& info = this->getFormatInfo(format);
return SkToBool(FormatInfo::kUnorderedAccess_Flag & info.fFlags);
}
int GrD3DCaps::getRenderTargetSampleCount(int requestedCount,
const GrBackendFormat& format) const {
DXGI_FORMAT dxgiFormat;

View File

@ -38,6 +38,8 @@ public:
bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const override;
bool isFormatRenderable(DXGI_FORMAT, int sampleCount) const;
bool isFormatUnorderedAccessible(DXGI_FORMAT) const;
int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat&) const override;
int getRenderTargetSampleCount(int requestedCount, DXGI_FORMAT) const;
@ -175,6 +177,7 @@ private:
kRenderable_Flag = 0x2, // Rendertarget and blendable
kMSAA_Flag = 0x4,
kResolve_Flag = 0x8,
kUnorderedAccess_Flag = 0x10,
};
uint16_t fFlags = 0;

View File

@ -110,6 +110,21 @@ void GrD3DCommandList::resourceBarrier(sk_sp<GrManagedResource> resource,
}
}
void GrD3DCommandList::uavBarrier(sk_sp<GrManagedResource> resource,
ID3D12Resource* uavResource) {
SkASSERT(fIsActive);
// D3D will apply barriers in order so we can just add onto the end
D3D12_RESOURCE_BARRIER& newBarrier = fResourceBarriers.push_back();
newBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
newBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
newBarrier.UAV.pResource = uavResource;
fHasWork = true;
if (resource) {
this->addResource(std::move(resource));
}
}
void GrD3DCommandList::submitResourceBarriers() {
SkASSERT(fIsActive);

View File

@ -49,12 +49,14 @@ public:
// GraphicsCommandList commands
////////////////////////////////////////////////////////////////////////////
// For the moment we only support Transition barriers
// All barriers should reference subresources of managedResource
void resourceBarrier(sk_sp<GrManagedResource> managedResource,
int numBarriers,
const D3D12_RESOURCE_TRANSITION_BARRIER* barriers);
void uavBarrier(sk_sp<GrManagedResource> managedResource,
ID3D12Resource* uavResource);
// Helper method that calls copyTextureRegion multiple times, once for each subresource
// The srcBuffer comes from a staging buffer so we don't need to take any refs to it. Instead,
// we ref the whole buffer during sumbit.

View File

@ -51,21 +51,36 @@ GrD3DDescriptorHeap::CPUHandle GrD3DCpuDescriptorManager::createConstantBufferVi
}
GrD3DDescriptorHeap::CPUHandle GrD3DCpuDescriptorManager::createShaderResourceView(
GrD3DGpu* gpu, ID3D12Resource* resource) {
GrD3DGpu* gpu, ID3D12Resource* resource,
unsigned int mostDetailedMip, unsigned int mipLevels) {
const GrD3DDescriptorHeap::CPUHandle& descriptor =
fShaderViewDescriptorPool.allocateHandle(gpu);
// TODO: for 4:2:0 YUV formats we'll need to map two different views, one for Y and one for UV.
// For now map the entire resource.
gpu->device()->CreateShaderResourceView(resource, nullptr, descriptor.fHandle);
D3D12_SHADER_RESOURCE_VIEW_DESC desc = {};
desc.Format = resource->GetDesc().Format;
desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
desc.Texture2D.MostDetailedMip = mostDetailedMip;
desc.Texture2D.MipLevels = mipLevels;
desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
gpu->device()->CreateShaderResourceView(resource, &desc, descriptor.fHandle);
return descriptor;
}
GrD3DDescriptorHeap::CPUHandle GrD3DCpuDescriptorManager::createUnorderedAccessView(
GrD3DGpu* gpu, ID3D12Resource* resource) {
GrD3DGpu* gpu, ID3D12Resource* resource, unsigned int mipSlice) {
const GrD3DDescriptorHeap::CPUHandle& descriptor =
fShaderViewDescriptorPool.allocateHandle(gpu);
// TODO: might need more granularity here for textures (specify miplevels, etc.)
gpu->device()->CreateUnorderedAccessView(resource, nullptr, nullptr, descriptor.fHandle);
if (resource->GetDesc().Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) {
// TODO: figure out buffer setup
gpu->device()->CreateUnorderedAccessView(resource, nullptr, nullptr, descriptor.fHandle);
} else {
D3D12_UNORDERED_ACCESS_VIEW_DESC desc = {};
desc.Format = resource->GetDesc().Format;
desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
desc.Texture2D.MipSlice = mipSlice;
gpu->device()->CreateUnorderedAccessView(resource, nullptr, &desc, descriptor.fHandle);
}
return descriptor;
}

View File

@ -29,9 +29,12 @@ public:
size_t offset,
size_t size);
GrD3DDescriptorHeap::CPUHandle createShaderResourceView(GrD3DGpu*,
ID3D12Resource* resource);
ID3D12Resource* resource,
unsigned int mostDetailedMip,
unsigned int mipLevels);
GrD3DDescriptorHeap::CPUHandle createUnorderedAccessView(GrD3DGpu*,
ID3D12Resource* resource);
ID3D12Resource* resource,
unsigned int mipSlice);
void recycleShaderView(const GrD3DDescriptorHeap::CPUHandle&);
GrD3DDescriptorHeap::CPUHandle createSampler(GrD3DGpu*,

View File

@ -105,13 +105,13 @@ GrD3DDescriptorHeap::CPUHandle GrD3DResourceProvider::createConstantBufferView(
}
GrD3DDescriptorHeap::CPUHandle GrD3DResourceProvider::createShaderResourceView(
ID3D12Resource* resource) {
return fCpuDescriptorManager.createShaderResourceView(fGpu, resource);
ID3D12Resource* resource, unsigned int highestMip, unsigned int mipLevels) {
return fCpuDescriptorManager.createShaderResourceView(fGpu, resource, highestMip, mipLevels);
}
GrD3DDescriptorHeap::CPUHandle GrD3DResourceProvider::createUnorderedAccessView(
ID3D12Resource* resource) {
return fCpuDescriptorManager.createUnorderedAccessView(fGpu, resource);
ID3D12Resource* resource, unsigned int mipSlice) {
return fCpuDescriptorManager.createUnorderedAccessView(fGpu, resource, mipSlice);
}
void GrD3DResourceProvider::recycleShaderView(

View File

@ -53,8 +53,11 @@ public:
GrD3DDescriptorHeap::CPUHandle createConstantBufferView(ID3D12Resource* bufferResource,
size_t offset,
size_t size);
GrD3DDescriptorHeap::CPUHandle createShaderResourceView(ID3D12Resource* resource);
GrD3DDescriptorHeap::CPUHandle createUnorderedAccessView(ID3D12Resource* resource);
GrD3DDescriptorHeap::CPUHandle createShaderResourceView(ID3D12Resource* resource,
unsigned int mostDetailedMip = 0,
unsigned int mipLevels = -1);
GrD3DDescriptorHeap::CPUHandle createUnorderedAccessView(ID3D12Resource* resource,
unsigned int mipSlice);
void recycleShaderView(const GrD3DDescriptorHeap::CPUHandle&);
D3D12_CPU_DESCRIPTOR_HANDLE findOrCreateCompatibleSampler(const GrSamplerState& params);