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)) { if (SkToBool(D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RESOLVE & formatSupport.Support1)) {
*flags = *flags | kResolve_Flag; *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) { 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); 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, int GrD3DCaps::getRenderTargetSampleCount(int requestedCount,
const GrBackendFormat& format) const { const GrBackendFormat& format) const {
DXGI_FORMAT dxgiFormat; DXGI_FORMAT dxgiFormat;

View File

@ -38,6 +38,8 @@ public:
bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const override; bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const override;
bool isFormatRenderable(DXGI_FORMAT, int sampleCount) const; bool isFormatRenderable(DXGI_FORMAT, int sampleCount) const;
bool isFormatUnorderedAccessible(DXGI_FORMAT) const;
int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat&) const override; int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat&) const override;
int getRenderTargetSampleCount(int requestedCount, DXGI_FORMAT) const; int getRenderTargetSampleCount(int requestedCount, DXGI_FORMAT) const;
@ -175,6 +177,7 @@ private:
kRenderable_Flag = 0x2, // Rendertarget and blendable kRenderable_Flag = 0x2, // Rendertarget and blendable
kMSAA_Flag = 0x4, kMSAA_Flag = 0x4,
kResolve_Flag = 0x8, kResolve_Flag = 0x8,
kUnorderedAccess_Flag = 0x10,
}; };
uint16_t fFlags = 0; 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() { void GrD3DCommandList::submitResourceBarriers() {
SkASSERT(fIsActive); SkASSERT(fIsActive);

View File

@ -49,12 +49,14 @@ public:
// GraphicsCommandList commands // GraphicsCommandList commands
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// For the moment we only support Transition barriers
// All barriers should reference subresources of managedResource // All barriers should reference subresources of managedResource
void resourceBarrier(sk_sp<GrManagedResource> managedResource, void resourceBarrier(sk_sp<GrManagedResource> managedResource,
int numBarriers, int numBarriers,
const D3D12_RESOURCE_TRANSITION_BARRIER* barriers); 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 // 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, // 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. // we ref the whole buffer during sumbit.

View File

@ -51,21 +51,36 @@ GrD3DDescriptorHeap::CPUHandle GrD3DCpuDescriptorManager::createConstantBufferVi
} }
GrD3DDescriptorHeap::CPUHandle GrD3DCpuDescriptorManager::createShaderResourceView( GrD3DDescriptorHeap::CPUHandle GrD3DCpuDescriptorManager::createShaderResourceView(
GrD3DGpu* gpu, ID3D12Resource* resource) { GrD3DGpu* gpu, ID3D12Resource* resource,
unsigned int mostDetailedMip, unsigned int mipLevels) {
const GrD3DDescriptorHeap::CPUHandle& descriptor = const GrD3DDescriptorHeap::CPUHandle& descriptor =
fShaderViewDescriptorPool.allocateHandle(gpu); 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. // 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. // 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; return descriptor;
} }
GrD3DDescriptorHeap::CPUHandle GrD3DCpuDescriptorManager::createUnorderedAccessView( GrD3DDescriptorHeap::CPUHandle GrD3DCpuDescriptorManager::createUnorderedAccessView(
GrD3DGpu* gpu, ID3D12Resource* resource) { GrD3DGpu* gpu, ID3D12Resource* resource, unsigned int mipSlice) {
const GrD3DDescriptorHeap::CPUHandle& descriptor = const GrD3DDescriptorHeap::CPUHandle& descriptor =
fShaderViewDescriptorPool.allocateHandle(gpu); fShaderViewDescriptorPool.allocateHandle(gpu);
// TODO: might need more granularity here for textures (specify miplevels, etc.) if (resource->GetDesc().Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) {
gpu->device()->CreateUnorderedAccessView(resource, nullptr, nullptr, descriptor.fHandle); // 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; return descriptor;
} }

View File

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

View File

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

View File

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