Change D3DAttachmentViewManager to handle all CPU descriptors

Change-Id: I6af3673a9dedf0a5acfbd588bfbbb447b5c68013
Bug: skia:9935
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/292576
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Jim Van Verth 2020-05-28 06:44:55 -04:00 committed by Skia Commit-Bot
parent 3ab9b1f8e9
commit afd4113bc3
6 changed files with 221 additions and 123 deletions

View File

@ -747,14 +747,14 @@ skia_direct3d_sources = [
"$_include/gpu/d3d/GrD3DTypes.h",
"$_include/gpu/d3d/GrD3DTypesMinimal.h",
"$_include/private/GrD3DTypesPriv.h",
"$_src/gpu/d3d/GrD3DAttachmentViewManager.cpp",
"$_src/gpu/d3d/GrD3DAttachmentViewManager.h",
"$_src/gpu/d3d/GrD3DBuffer.cpp",
"$_src/gpu/d3d/GrD3DBuffer.h",
"$_src/gpu/d3d/GrD3DCaps.cpp",
"$_src/gpu/d3d/GrD3DCaps.h",
"$_src/gpu/d3d/GrD3DCommandList.cpp",
"$_src/gpu/d3d/GrD3DCommandList.h",
"$_src/gpu/d3d/GrD3DCpuDescriptorManager.cpp",
"$_src/gpu/d3d/GrD3DCpuDescriptorManager.h",
"$_src/gpu/d3d/GrD3DDescriptorHeap.cpp",
"$_src/gpu/d3d/GrD3DDescriptorHeap.h",
"$_src/gpu/d3d/GrD3DGpu.cpp",

View File

@ -1,110 +0,0 @@
/*
* Copyright 2020 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/gpu/d3d/GrD3DAttachmentViewManager.h"
#include "src/gpu/d3d/GrD3DGpu.h"
GrD3DAttachmentViewManager::GrD3DAttachmentViewManager(GrD3DGpu* gpu)
: fRTVDescriptorPool(gpu, D3D12_DESCRIPTOR_HEAP_TYPE_RTV)
, fDSVDescriptorPool(gpu, D3D12_DESCRIPTOR_HEAP_TYPE_DSV) {}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DAttachmentViewManager::createRenderTargetView(
GrD3DGpu* gpu, ID3D12Resource* textureResource) {
D3D12_CPU_DESCRIPTOR_HANDLE descriptor = fRTVDescriptorPool.allocateHandle(gpu);
gpu->device()->CreateRenderTargetView(textureResource, nullptr, descriptor);
return descriptor;
}
void GrD3DAttachmentViewManager::recycleRenderTargetView(
D3D12_CPU_DESCRIPTOR_HANDLE* rtvDescriptor) {
fRTVDescriptorPool.releaseHandle(rtvDescriptor);
}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DAttachmentViewManager::createDepthStencilView(
GrD3DGpu* gpu, ID3D12Resource* textureResource) {
D3D12_CPU_DESCRIPTOR_HANDLE descriptor = fDSVDescriptorPool.allocateHandle(gpu);
gpu->device()->CreateDepthStencilView(textureResource, nullptr, descriptor);
return descriptor;
}
void GrD3DAttachmentViewManager::recycleDepthStencilView(
D3D12_CPU_DESCRIPTOR_HANDLE* dsvDescriptor) {
fDSVDescriptorPool.releaseHandle(dsvDescriptor);
}
////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<GrD3DAttachmentViewManager::Heap> GrD3DAttachmentViewManager::Heap::Make(
GrD3DGpu* gpu, D3D12_DESCRIPTOR_HEAP_TYPE type, unsigned int numDescriptors) {
std::unique_ptr<GrD3DDescriptorHeap> heap =
GrD3DDescriptorHeap::Make(gpu, type, numDescriptors, D3D12_DESCRIPTOR_HEAP_FLAG_NONE);
if (!heap) {
return nullptr;
}
return std::unique_ptr<Heap>(new Heap(heap, numDescriptors));
}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DAttachmentViewManager::Heap::allocateCPUHandle() {
SkBitSet::OptionalIndex freeBlock = fFreeBlocks.findFirst();
SkASSERT(freeBlock);
fFreeBlocks.reset(*freeBlock);
--fFreeCount;
return fHeap->getCPUHandle(*freeBlock);
}
bool GrD3DAttachmentViewManager::Heap::freeCPUHandle(D3D12_CPU_DESCRIPTOR_HANDLE* handle) {
size_t index;
if (!fHeap->getIndex(*handle, &index)) {
return false;
}
fFreeBlocks.set(index);
++fFreeCount;
handle->ptr = 0;
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////
GrD3DAttachmentViewManager::HeapPool::HeapPool(GrD3DGpu* gpu, D3D12_DESCRIPTOR_HEAP_TYPE heapType)
: fMaxAvailableDescriptors(32)
, fHeapType(heapType) {
std::unique_ptr<GrD3DAttachmentViewManager::Heap> heap =
GrD3DAttachmentViewManager::Heap::Make(gpu, fHeapType, fMaxAvailableDescriptors);
fDescriptorHeaps.push_back(std::move(heap));
}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DAttachmentViewManager::HeapPool::allocateHandle(GrD3DGpu* gpu) {
for (unsigned int i = 0; i < fDescriptorHeaps.size(); ++i) {
if (fDescriptorHeaps[i]->canAllocate()) {
D3D12_CPU_DESCRIPTOR_HANDLE handle = fDescriptorHeaps[i]->allocateCPUHandle();
return handle;
}
}
// need to allocate more space
std::unique_ptr<GrD3DAttachmentViewManager::Heap> heap =
GrD3DAttachmentViewManager::Heap::Make(gpu, fHeapType, fMaxAvailableDescriptors);
fDescriptorHeaps.push_back(std::move(heap));
fMaxAvailableDescriptors *= 2;
D3D12_CPU_DESCRIPTOR_HANDLE handle =
fDescriptorHeaps[fDescriptorHeaps.size() - 1]->allocateCPUHandle();
return handle;
}
void GrD3DAttachmentViewManager::HeapPool::releaseHandle(
D3D12_CPU_DESCRIPTOR_HANDLE* dsvDescriptor) {
for (unsigned int i = 0; i < fDescriptorHeaps.size(); ++i) {
if (fDescriptorHeaps[i]->freeCPUHandle(dsvDescriptor)) {
return;
}
}
SkASSERT(false);
}

View File

@ -0,0 +1,158 @@
/*
* Copyright 2020 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/gpu/d3d/GrD3DCpuDescriptorManager.h"
#include "src/gpu/d3d/GrD3DGpu.h"
GrD3DCpuDescriptorManager::GrD3DCpuDescriptorManager(GrD3DGpu* gpu)
: fRTVDescriptorPool(gpu, D3D12_DESCRIPTOR_HEAP_TYPE_RTV)
, fDSVDescriptorPool(gpu, D3D12_DESCRIPTOR_HEAP_TYPE_DSV)
, fCBVSRVDescriptorPool(gpu, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)
, fSamplerDescriptorPool(gpu, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER) {}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DCpuDescriptorManager::createRenderTargetView(
GrD3DGpu* gpu, ID3D12Resource* textureResource) {
D3D12_CPU_DESCRIPTOR_HANDLE descriptor = fRTVDescriptorPool.allocateHandle(gpu);
gpu->device()->CreateRenderTargetView(textureResource, nullptr, descriptor);
return descriptor;
}
void GrD3DCpuDescriptorManager::recycleRenderTargetView(
D3D12_CPU_DESCRIPTOR_HANDLE* rtvDescriptor) {
fRTVDescriptorPool.releaseHandle(rtvDescriptor);
}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DCpuDescriptorManager::createDepthStencilView(
GrD3DGpu* gpu, ID3D12Resource* textureResource) {
D3D12_CPU_DESCRIPTOR_HANDLE descriptor = fDSVDescriptorPool.allocateHandle(gpu);
gpu->device()->CreateDepthStencilView(textureResource, nullptr, descriptor);
return descriptor;
}
void GrD3DCpuDescriptorManager::recycleDepthStencilView(
D3D12_CPU_DESCRIPTOR_HANDLE* dsvDescriptor) {
fDSVDescriptorPool.releaseHandle(dsvDescriptor);
}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DCpuDescriptorManager::createConstantBufferView(
GrD3DGpu* gpu, ID3D12Resource* bufferResource, size_t offset, size_t size) {
D3D12_CPU_DESCRIPTOR_HANDLE descriptor = fCBVSRVDescriptorPool.allocateHandle(gpu);
D3D12_CONSTANT_BUFFER_VIEW_DESC desc = {};
desc.BufferLocation = bufferResource->GetGPUVirtualAddress() + offset;
desc.SizeInBytes = size;
gpu->device()->CreateConstantBufferView(&desc, descriptor);
return descriptor;
}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DCpuDescriptorManager::createShaderResourceView(
GrD3DGpu* gpu, ID3D12Resource* resource) {
D3D12_CPU_DESCRIPTOR_HANDLE descriptor = fCBVSRVDescriptorPool.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);
return descriptor;
}
void GrD3DCpuDescriptorManager::recycleConstantOrShaderView(D3D12_CPU_DESCRIPTOR_HANDLE* view) {
fCBVSRVDescriptorPool.releaseHandle(view);
}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DCpuDescriptorManager::createSampler(
GrD3DGpu* gpu, D3D12_FILTER filter, D3D12_TEXTURE_ADDRESS_MODE addressModeU,
D3D12_TEXTURE_ADDRESS_MODE addressModeV) {
D3D12_CPU_DESCRIPTOR_HANDLE descriptor = fSamplerDescriptorPool.allocateHandle(gpu);
D3D12_SAMPLER_DESC desc = {};
desc.Filter = filter;
desc.AddressU = addressModeU;
desc.AddressV = addressModeV;
desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
desc.MipLODBias = 0;
desc.MaxAnisotropy = 1;
desc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
// desc.BorderColor initialized to { 0, 0, 0, 0 } by default initializer, above.
desc.MinLOD = 0;
desc.MaxLOD = SK_ScalarMax;
gpu->device()->CreateSampler(&desc, descriptor);
return descriptor;
}
void GrD3DCpuDescriptorManager::recycleSampler(D3D12_CPU_DESCRIPTOR_HANDLE* samplerDescriptor) {
fSamplerDescriptorPool.releaseHandle(samplerDescriptor);
}
////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<GrD3DCpuDescriptorManager::Heap> GrD3DCpuDescriptorManager::Heap::Make(
GrD3DGpu* gpu, D3D12_DESCRIPTOR_HEAP_TYPE type, unsigned int numDescriptors) {
std::unique_ptr<GrD3DDescriptorHeap> heap =
GrD3DDescriptorHeap::Make(gpu, type, numDescriptors, D3D12_DESCRIPTOR_HEAP_FLAG_NONE);
if (!heap) {
return nullptr;
}
return std::unique_ptr<Heap>(new Heap(heap, numDescriptors));
}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DCpuDescriptorManager::Heap::allocateCPUHandle() {
SkBitSet::OptionalIndex freeBlock = fFreeBlocks.findFirst();
SkASSERT(freeBlock);
fFreeBlocks.reset(*freeBlock);
--fFreeCount;
return fHeap->getCPUHandle(*freeBlock);
}
bool GrD3DCpuDescriptorManager::Heap::freeCPUHandle(D3D12_CPU_DESCRIPTOR_HANDLE* handle) {
size_t index;
if (!fHeap->getIndex(*handle, &index)) {
return false;
}
fFreeBlocks.set(index);
++fFreeCount;
handle->ptr = 0;
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////
GrD3DCpuDescriptorManager::HeapPool::HeapPool(GrD3DGpu* gpu, D3D12_DESCRIPTOR_HEAP_TYPE heapType)
: fMaxAvailableDescriptors(32)
, fHeapType(heapType) {
std::unique_ptr<GrD3DCpuDescriptorManager::Heap> heap =
GrD3DCpuDescriptorManager::Heap::Make(gpu, fHeapType, fMaxAvailableDescriptors);
fDescriptorHeaps.push_back(std::move(heap));
}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DCpuDescriptorManager::HeapPool::allocateHandle(GrD3DGpu* gpu) {
for (unsigned int i = 0; i < fDescriptorHeaps.size(); ++i) {
if (fDescriptorHeaps[i]->canAllocate()) {
D3D12_CPU_DESCRIPTOR_HANDLE handle = fDescriptorHeaps[i]->allocateCPUHandle();
return handle;
}
}
// need to allocate more space
std::unique_ptr<GrD3DCpuDescriptorManager::Heap> heap =
GrD3DCpuDescriptorManager::Heap::Make(gpu, fHeapType, fMaxAvailableDescriptors);
fDescriptorHeaps.push_back(std::move(heap));
fMaxAvailableDescriptors *= 2;
D3D12_CPU_DESCRIPTOR_HANDLE handle =
fDescriptorHeaps[fDescriptorHeaps.size() - 1]->allocateCPUHandle();
return handle;
}
void GrD3DCpuDescriptorManager::HeapPool::releaseHandle(
D3D12_CPU_DESCRIPTOR_HANDLE* dsvDescriptor) {
for (unsigned int i = 0; i < fDescriptorHeaps.size(); ++i) {
if (fDescriptorHeaps[i]->freeCPUHandle(dsvDescriptor)) {
return;
}
}
SkASSERT(false);
}

View File

@ -5,16 +5,16 @@
* found in the LICENSE file.
*/
#ifndef GrD3DAttachmentViewManager_DEFINED
#define GrD3DAttachmentViewManager_DEFINED
#ifndef GrD3DCpuDescriptorManager_DEFINED
#define GrD3DCpuDescriptorManager_DEFINED
#include "src/gpu/d3d/GrD3DDescriptorHeap.h"
class GrD3DGpu;
class GrD3DAttachmentViewManager {
class GrD3DCpuDescriptorManager {
public:
GrD3DAttachmentViewManager(GrD3DGpu*);
GrD3DCpuDescriptorManager(GrD3DGpu*);
D3D12_CPU_DESCRIPTOR_HANDLE createRenderTargetView(GrD3DGpu*, ID3D12Resource* textureResource);
void recycleRenderTargetView(D3D12_CPU_DESCRIPTOR_HANDLE*);
@ -22,6 +22,19 @@ public:
D3D12_CPU_DESCRIPTOR_HANDLE createDepthStencilView(GrD3DGpu*, ID3D12Resource* textureResource);
void recycleDepthStencilView(D3D12_CPU_DESCRIPTOR_HANDLE*);
D3D12_CPU_DESCRIPTOR_HANDLE createConstantBufferView(GrD3DGpu*,
ID3D12Resource* bufferResource,
size_t offset,
size_t size);
D3D12_CPU_DESCRIPTOR_HANDLE createShaderResourceView(GrD3DGpu*,
ID3D12Resource* resource);
void recycleConstantOrShaderView(D3D12_CPU_DESCRIPTOR_HANDLE*);
D3D12_CPU_DESCRIPTOR_HANDLE createSampler(GrD3DGpu*, D3D12_FILTER filter,
D3D12_TEXTURE_ADDRESS_MODE addressModeU,
D3D12_TEXTURE_ADDRESS_MODE addressModeV);
void recycleSampler(D3D12_CPU_DESCRIPTOR_HANDLE*);
private:
class Heap {
public:
@ -63,6 +76,8 @@ private:
HeapPool fRTVDescriptorPool;
HeapPool fDSVDescriptorPool;
HeapPool fCBVSRVDescriptorPool;
HeapPool fSamplerDescriptorPool;
};
#endif

View File

@ -16,7 +16,7 @@
GrD3DResourceProvider::GrD3DResourceProvider(GrD3DGpu* gpu)
: fGpu(gpu)
, fAttachmentViewManager(gpu)
, fCpuDescriptorManager(gpu)
, fPipelineStateCache(new PipelineStateCache(gpu)) {
}
@ -54,20 +54,44 @@ sk_sp<GrD3DRootSignature> GrD3DResourceProvider::findOrCreateRootSignature(int n
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DResourceProvider::createRenderTargetView(
ID3D12Resource* textureResource) {
return fAttachmentViewManager.createRenderTargetView(fGpu, textureResource);
return fCpuDescriptorManager.createRenderTargetView(fGpu, textureResource);
}
void GrD3DResourceProvider::recycleRenderTargetView(D3D12_CPU_DESCRIPTOR_HANDLE* rtvDescriptor) {
fAttachmentViewManager.recycleRenderTargetView(rtvDescriptor);
fCpuDescriptorManager.recycleRenderTargetView(rtvDescriptor);
}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DResourceProvider::createDepthStencilView(
ID3D12Resource* textureResource) {
return fAttachmentViewManager.createDepthStencilView(fGpu, textureResource);
return fCpuDescriptorManager.createDepthStencilView(fGpu, textureResource);
}
void GrD3DResourceProvider::recycleDepthStencilView(D3D12_CPU_DESCRIPTOR_HANDLE* dsvDescriptor) {
fAttachmentViewManager.recycleDepthStencilView(dsvDescriptor);
fCpuDescriptorManager.recycleDepthStencilView(dsvDescriptor);
}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DResourceProvider::createConstantBufferView(
ID3D12Resource* bufferResource, size_t offset, size_t size) {
return fCpuDescriptorManager.createConstantBufferView(fGpu, bufferResource, offset, size);
}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DResourceProvider::createShaderResourceView(
ID3D12Resource* resource) {
return fCpuDescriptorManager.createShaderResourceView(fGpu, resource);
}
void GrD3DResourceProvider::recycleConstantOrShaderView(D3D12_CPU_DESCRIPTOR_HANDLE* view) {
fCpuDescriptorManager.recycleConstantOrShaderView(view);
}
D3D12_CPU_DESCRIPTOR_HANDLE GrD3DResourceProvider::createSampler(
D3D12_FILTER filter, D3D12_TEXTURE_ADDRESS_MODE addressModeU,
D3D12_TEXTURE_ADDRESS_MODE addressModeV) {
return fCpuDescriptorManager.createSampler(fGpu, filter, addressModeU, addressModeV);
}
void GrD3DResourceProvider::recycleSampler(D3D12_CPU_DESCRIPTOR_HANDLE* sampler) {
fCpuDescriptorManager.recycleSampler(sampler);
}
sk_sp<GrD3DPipelineState> GrD3DResourceProvider::findOrCreateCompatiblePipelineState(

View File

@ -12,7 +12,7 @@
#include "include/private/SkTArray.h"
#include "src/core/SkLRUCache.h"
#include "src/gpu/GrProgramDesc.h"
#include "src/gpu/d3d/GrD3DAttachmentViewManager.h"
#include "src/gpu/d3d/GrD3DCpuDescriptorManager.h"
#include "src/gpu/d3d/GrD3DRootSignature.h"
#include <memory>
@ -37,6 +37,17 @@ public:
D3D12_CPU_DESCRIPTOR_HANDLE createDepthStencilView(ID3D12Resource* textureResource);
void recycleDepthStencilView(D3D12_CPU_DESCRIPTOR_HANDLE*);
D3D12_CPU_DESCRIPTOR_HANDLE createConstantBufferView(ID3D12Resource* bufferResource,
size_t offset,
size_t size);
D3D12_CPU_DESCRIPTOR_HANDLE createShaderResourceView(ID3D12Resource* resource);
void recycleConstantOrShaderView(D3D12_CPU_DESCRIPTOR_HANDLE*);
D3D12_CPU_DESCRIPTOR_HANDLE createSampler(D3D12_FILTER filter,
D3D12_TEXTURE_ADDRESS_MODE addressModeU,
D3D12_TEXTURE_ADDRESS_MODE addressModeV);
void recycleSampler(D3D12_CPU_DESCRIPTOR_HANDLE*);
sk_sp<GrD3DPipelineState> findOrCreateCompatiblePipelineState(GrRenderTarget*,
const GrProgramInfo&);
@ -76,7 +87,7 @@ private:
SkSTArray<4, std::unique_ptr<GrD3DDirectCommandList>> fAvailableDirectCommandLists;
SkSTArray<4, sk_sp<GrD3DRootSignature>> fRootSignatures;
GrD3DAttachmentViewManager fAttachmentViewManager;
GrD3DCpuDescriptorManager fCpuDescriptorManager;
std::unique_ptr<PipelineStateCache> fPipelineStateCache;
};