From 7434b2c67d9a4cb9bfbf50304d6af42d2195df4d Mon Sep 17 00:00:00 2001 From: Bryan Bernhart Date: Wed, 22 Apr 2020 23:57:30 +0000 Subject: [PATCH] D3D12: Enable sub-allocation for RTV/DSV heaps. Uses the staging descriptor allocator to enable sub-allocation for RTV/DSVs. This change also simplifies CPU descriptor heap management for render-passes: - Allocating slot-by-slot removes extra attachment pass. - No need for the slower direct allocation allocator. - Move RP creation of view handles into RP builder. BUG=dawn:155 Change-Id: I508492a2e56a897bf8c85f9a45cd13f62fa0a2ef Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/20042 Commit-Queue: Bryan Bernhart Reviewed-by: Austin Eng --- src/dawn_native/BUILD.gn | 2 - src/dawn_native/CMakeLists.txt | 2 - src/dawn_native/d3d12/CommandBufferD3D12.cpp | 94 +++++------- src/dawn_native/d3d12/CommandBufferD3D12.h | 14 +- .../d3d12/DescriptorHeapAllocator.cpp | 134 ------------------ .../d3d12/DescriptorHeapAllocator.h | 81 ----------- src/dawn_native/d3d12/DeviceD3D12.cpp | 33 +++-- src/dawn_native/d3d12/DeviceD3D12.h | 10 +- .../d3d12/RenderPassBuilderD3D12.cpp | 23 +-- .../d3d12/RenderPassBuilderD3D12.h | 10 +- .../d3d12/StagingDescriptorAllocatorD3D12.cpp | 21 ++- .../d3d12/StagingDescriptorAllocatorD3D12.h | 7 + src/dawn_native/d3d12/TextureD3D12.cpp | 24 ++-- 13 files changed, 130 insertions(+), 325 deletions(-) delete mode 100644 src/dawn_native/d3d12/DescriptorHeapAllocator.cpp delete mode 100644 src/dawn_native/d3d12/DescriptorHeapAllocator.h diff --git a/src/dawn_native/BUILD.gn b/src/dawn_native/BUILD.gn index d11afca9d7..42511960bb 100644 --- a/src/dawn_native/BUILD.gn +++ b/src/dawn_native/BUILD.gn @@ -301,8 +301,6 @@ source_set("dawn_native_sources") { "d3d12/D3D12Info.h", "d3d12/DescriptorHeapAllocationD3D12.cpp", "d3d12/DescriptorHeapAllocationD3D12.h", - "d3d12/DescriptorHeapAllocator.cpp", - "d3d12/DescriptorHeapAllocator.h", "d3d12/DeviceD3D12.cpp", "d3d12/DeviceD3D12.h", "d3d12/Forward.h", diff --git a/src/dawn_native/CMakeLists.txt b/src/dawn_native/CMakeLists.txt index ff46a74f3c..9d78325508 100644 --- a/src/dawn_native/CMakeLists.txt +++ b/src/dawn_native/CMakeLists.txt @@ -182,8 +182,6 @@ if (DAWN_ENABLE_D3D12) "d3d12/D3D12Info.h" "d3d12/DescriptorHeapAllocationD3D12.cpp" "d3d12/DescriptorHeapAllocationD3D12.h" - "d3d12/DescriptorHeapAllocator.cpp" - "d3d12/DescriptorHeapAllocator.h" "d3d12/DeviceD3D12.cpp" "d3d12/DeviceD3D12.h" "d3d12/Forward.h" diff --git a/src/dawn_native/d3d12/CommandBufferD3D12.cpp b/src/dawn_native/d3d12/CommandBufferD3D12.cpp index 14d0f95e2a..2726e5cc42 100644 --- a/src/dawn_native/d3d12/CommandBufferD3D12.cpp +++ b/src/dawn_native/d3d12/CommandBufferD3D12.cpp @@ -24,7 +24,6 @@ #include "dawn_native/d3d12/BufferD3D12.h" #include "dawn_native/d3d12/CommandRecordingContext.h" #include "dawn_native/d3d12/ComputePipelineD3D12.h" -#include "dawn_native/d3d12/DescriptorHeapAllocator.h" #include "dawn_native/d3d12/DeviceD3D12.h" #include "dawn_native/d3d12/PipelineLayoutD3D12.h" #include "dawn_native/d3d12/PlatformFunctions.h" @@ -32,6 +31,7 @@ #include "dawn_native/d3d12/RenderPipelineD3D12.h" #include "dawn_native/d3d12/SamplerD3D12.h" #include "dawn_native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.h" +#include "dawn_native/d3d12/StagingDescriptorAllocatorD3D12.h" #include "dawn_native/d3d12/TextureCopySplitter.h" #include "dawn_native/d3d12/TextureD3D12.h" #include "dawn_native/d3d12/UtilsD3D12.h" @@ -296,53 +296,6 @@ namespace dawn_native { namespace d3d12 { }; namespace { - - // TODO(jiawei.shao@intel.com): use hash map as - // cache to avoid redundant RTV and DSV memory allocations. - ResultOrError GetSubpassOMSetRenderTargetArgs( - BeginRenderPassCmd* renderPass, - Device* device) { - OMSetRenderTargetArgs args = {}; - - uint32_t rtvCount = static_cast( - renderPass->attachmentState->GetColorAttachmentsMask().count()); - DescriptorHeapAllocator* allocator = device->GetDescriptorHeapAllocator(); - DescriptorHeapHandle rtvHeap; - DAWN_TRY_ASSIGN(rtvHeap, - allocator->AllocateCPUHeap(D3D12_DESCRIPTOR_HEAP_TYPE_RTV, rtvCount)); - ASSERT(rtvHeap.Get() != nullptr); - ID3D12Device* d3dDevice = device->GetD3D12Device(); - unsigned int rtvIndex = 0; - for (uint32_t i : - IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) { - ASSERT(rtvIndex < rtvCount); - TextureView* view = ToBackend(renderPass->colorAttachments[i].view).Get(); - D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = rtvHeap.GetCPUHandle(rtvIndex); - D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = view->GetRTVDescriptor(); - d3dDevice->CreateRenderTargetView(ToBackend(view->GetTexture())->GetD3D12Resource(), - &rtvDesc, rtvHandle); - args.RTVs[rtvIndex] = rtvHandle; - - ++rtvIndex; - } - args.numRTVs = rtvCount; - - if (renderPass->attachmentState->HasDepthStencilAttachment()) { - DescriptorHeapHandle dsvHeap; - DAWN_TRY_ASSIGN(dsvHeap, - allocator->AllocateCPUHeap(D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1)); - ASSERT(dsvHeap.Get() != nullptr); - TextureView* view = ToBackend(renderPass->depthStencilAttachment.view).Get(); - D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = dsvHeap.GetCPUHandle(0); - D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = view->GetDSVDescriptor(); - d3dDevice->CreateDepthStencilView(ToBackend(view->GetTexture())->GetD3D12Resource(), - &dsvDesc, dsvHandle); - args.dsv = dsvHandle; - } - - return args; - } - class VertexBufferTracker { public: void OnSetVertexBuffer(uint32_t slot, Buffer* buffer, uint64_t offset) { @@ -839,13 +792,29 @@ namespace dawn_native { namespace d3d12 { return {}; } - void CommandBuffer::SetupRenderPass(CommandRecordingContext* commandContext, - BeginRenderPassCmd* renderPass, - RenderPassBuilder* renderPassBuilder) { + MaybeError CommandBuffer::SetupRenderPass(CommandRecordingContext* commandContext, + BeginRenderPassCmd* renderPass, + RenderPassBuilder* renderPassBuilder) { + Device* device = ToBackend(GetDevice()); + for (uint32_t i : IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) { RenderPassColorAttachmentInfo& attachmentInfo = renderPass->colorAttachments[i]; TextureView* view = ToBackend(attachmentInfo.view.Get()); + // Set view attachment. + CPUDescriptorHeapAllocation rtvAllocation; + DAWN_TRY_ASSIGN( + rtvAllocation, + device->GetRenderTargetViewAllocator()->AllocateTransientCPUDescriptors()); + + const D3D12_RENDER_TARGET_VIEW_DESC viewDesc = view->GetRTVDescriptor(); + const D3D12_CPU_DESCRIPTOR_HANDLE baseDescriptor = rtvAllocation.GetBaseDescriptor(); + + device->GetD3D12Device()->CreateRenderTargetView( + ToBackend(view->GetTexture())->GetD3D12Resource(), &viewDesc, baseDescriptor); + + renderPassBuilder->SetRenderTargetView(i, baseDescriptor); + // Set color load operation. renderPassBuilder->SetRenderTargetBeginningAccess( i, attachmentInfo.loadOp, attachmentInfo.clearColor, view->GetD3D12Format()); @@ -871,6 +840,20 @@ namespace dawn_native { namespace d3d12 { renderPass->depthStencilAttachment; TextureView* view = ToBackend(renderPass->depthStencilAttachment.view.Get()); + // Set depth attachment. + CPUDescriptorHeapAllocation dsvAllocation; + DAWN_TRY_ASSIGN( + dsvAllocation, + device->GetDepthStencilViewAllocator()->AllocateTransientCPUDescriptors()); + + const D3D12_DEPTH_STENCIL_VIEW_DESC viewDesc = view->GetDSVDescriptor(); + const D3D12_CPU_DESCRIPTOR_HANDLE baseDescriptor = dsvAllocation.GetBaseDescriptor(); + + device->GetD3D12Device()->CreateDepthStencilView( + ToBackend(view->GetTexture())->GetD3D12Resource(), &viewDesc, baseDescriptor); + + renderPassBuilder->SetDepthStencilView(baseDescriptor); + const bool hasDepth = view->GetTexture()->GetFormat().HasDepth(); const bool hasStencil = view->GetTexture()->GetFormat().HasStencil(); @@ -894,6 +877,8 @@ namespace dawn_native { namespace d3d12 { } else { renderPassBuilder->SetDepthStencilNoAccess(); } + + return {}; } void CommandBuffer::EmulateBeginRenderPass(CommandRecordingContext* commandContext, @@ -958,17 +943,14 @@ namespace dawn_native { namespace d3d12 { BeginRenderPassCmd* renderPass, const bool passHasUAV) { Device* device = ToBackend(GetDevice()); - OMSetRenderTargetArgs args; - DAWN_TRY_ASSIGN(args, GetSubpassOMSetRenderTargetArgs(renderPass, device)); - const bool useRenderPass = device->IsToggleEnabled(Toggle::UseD3D12RenderPass); // renderPassBuilder must be scoped to RecordRenderPass because any underlying // D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_SUBRESOURCE_PARAMETERS structs must remain // valid until after EndRenderPass() has been called. - RenderPassBuilder renderPassBuilder(args, passHasUAV); + RenderPassBuilder renderPassBuilder(passHasUAV); - SetupRenderPass(commandContext, renderPass, &renderPassBuilder); + DAWN_TRY(SetupRenderPass(commandContext, renderPass, &renderPassBuilder)); // Use D3D12's native render pass API if it's available, otherwise emulate the // beginning and ending access operations. diff --git a/src/dawn_native/d3d12/CommandBufferD3D12.h b/src/dawn_native/d3d12/CommandBufferD3D12.h index b49882b7b0..cc53fd54cf 100644 --- a/src/dawn_native/d3d12/CommandBufferD3D12.h +++ b/src/dawn_native/d3d12/CommandBufferD3D12.h @@ -19,9 +19,7 @@ #include "dawn_native/CommandAllocator.h" #include "dawn_native/CommandBuffer.h" #include "dawn_native/Error.h" - #include "dawn_native/d3d12/Forward.h" -#include "dawn_native/d3d12/d3d12_platform.h" #include @@ -31,12 +29,6 @@ namespace dawn_native { namespace dawn_native { namespace d3d12 { - struct OMSetRenderTargetArgs { - unsigned int numRTVs = 0; - std::array RTVs = {}; - D3D12_CPU_DESCRIPTOR_HANDLE dsv = {}; - }; - class BindGroupStateTracker; class CommandRecordingContext; class Device; @@ -58,9 +50,9 @@ namespace dawn_native { namespace d3d12 { BindGroupStateTracker* bindingTracker, BeginRenderPassCmd* renderPass, bool passHasUAV); - void SetupRenderPass(CommandRecordingContext* commandContext, - BeginRenderPassCmd* renderPass, - RenderPassBuilder* renderPassBuilder); + MaybeError SetupRenderPass(CommandRecordingContext* commandContext, + BeginRenderPassCmd* renderPass, + RenderPassBuilder* renderPassBuilder); void EmulateBeginRenderPass(CommandRecordingContext* commandContext, const RenderPassBuilder* renderPassBuilder) const; diff --git a/src/dawn_native/d3d12/DescriptorHeapAllocator.cpp b/src/dawn_native/d3d12/DescriptorHeapAllocator.cpp deleted file mode 100644 index facc307b26..0000000000 --- a/src/dawn_native/d3d12/DescriptorHeapAllocator.cpp +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2017 The Dawn Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "dawn_native/d3d12/DescriptorHeapAllocator.h" - -#include "common/Assert.h" -#include "dawn_native/d3d12/D3D12Error.h" -#include "dawn_native/d3d12/DeviceD3D12.h" - -namespace dawn_native { namespace d3d12 { - - DescriptorHeapHandle::DescriptorHeapHandle() - : mDescriptorHeap(nullptr), mSizeIncrement(0), mOffset(0) { - } - - DescriptorHeapHandle::DescriptorHeapHandle(ComPtr descriptorHeap, - uint32_t sizeIncrement, - uint64_t offset) - : mDescriptorHeap(descriptorHeap), mSizeIncrement(sizeIncrement), mOffset(offset) { - } - - ID3D12DescriptorHeap* DescriptorHeapHandle::Get() const { - return mDescriptorHeap.Get(); - } - - D3D12_CPU_DESCRIPTOR_HANDLE DescriptorHeapHandle::GetCPUHandle(uint32_t index) const { - ASSERT(mDescriptorHeap); - auto handle = mDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); - handle.ptr += mSizeIncrement * (index + mOffset); - return handle; - } - - D3D12_GPU_DESCRIPTOR_HANDLE DescriptorHeapHandle::GetGPUHandle(uint32_t index) const { - ASSERT(mDescriptorHeap); - auto handle = mDescriptorHeap->GetGPUDescriptorHandleForHeapStart(); - handle.ptr += mSizeIncrement * (index + mOffset); - return handle; - } - - DescriptorHeapAllocator::DescriptorHeapAllocator(Device* device) - : mDevice(device), - mSizeIncrements{ - device->GetD3D12Device()->GetDescriptorHandleIncrementSize( - D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV), - device->GetD3D12Device()->GetDescriptorHandleIncrementSize( - D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER), - device->GetD3D12Device()->GetDescriptorHandleIncrementSize( - D3D12_DESCRIPTOR_HEAP_TYPE_RTV), - device->GetD3D12Device()->GetDescriptorHandleIncrementSize( - D3D12_DESCRIPTOR_HEAP_TYPE_DSV), - } { - } - - ResultOrError DescriptorHeapAllocator::Allocate( - D3D12_DESCRIPTOR_HEAP_TYPE type, - uint32_t count, - uint32_t allocationSize, - DescriptorHeapInfo* heapInfo, - D3D12_DESCRIPTOR_HEAP_FLAGS flags) { - const Serial pendingSerial = mDevice->GetPendingCommandSerial(); - uint64_t startOffset = (heapInfo->heap == nullptr) - ? RingBufferAllocator::kInvalidOffset - : heapInfo->allocator.Allocate(count, pendingSerial); - if (startOffset != RingBufferAllocator::kInvalidOffset) { - return DescriptorHeapHandle{heapInfo->heap, mSizeIncrements[type], startOffset}; - } - - // If the pool has no more space, replace the pool with a new one of the specified size - - D3D12_DESCRIPTOR_HEAP_DESC heapDescriptor; - heapDescriptor.Type = type; - heapDescriptor.NumDescriptors = allocationSize; - heapDescriptor.Flags = flags; - heapDescriptor.NodeMask = 0; - ComPtr heap; - DAWN_TRY(CheckHRESULT( - mDevice->GetD3D12Device()->CreateDescriptorHeap(&heapDescriptor, IID_PPV_ARGS(&heap)), - "ID3D12Device::CreateDescriptorHeap")); - - mDevice->ReferenceUntilUnused(heap); - - *heapInfo = {heap, RingBufferAllocator(allocationSize)}; - - startOffset = heapInfo->allocator.Allocate(count, pendingSerial); - - ASSERT(startOffset != RingBufferAllocator::kInvalidOffset); - - return DescriptorHeapHandle(heap, mSizeIncrements[type], startOffset); - } - - ResultOrError DescriptorHeapAllocator::AllocateCPUHeap( - D3D12_DESCRIPTOR_HEAP_TYPE type, - uint32_t count) { - return Allocate(type, count, count, &mCpuDescriptorHeapInfos[type], - D3D12_DESCRIPTOR_HEAP_FLAG_NONE); - } - - ResultOrError DescriptorHeapAllocator::AllocateGPUHeap( - D3D12_DESCRIPTOR_HEAP_TYPE type, - uint32_t count) { - ASSERT(type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || - type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); - unsigned int heapSize = (type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV - ? D3D12_MAX_SHADER_VISIBLE_DESCRIPTOR_HEAP_SIZE_TIER_1 - : D3D12_MAX_SHADER_VISIBLE_SAMPLER_HEAP_SIZE); - return Allocate(type, count, heapSize, &mGpuDescriptorHeapInfos[type], - D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE); - } - - void DescriptorHeapAllocator::Deallocate(uint64_t lastCompletedSerial) { - for (uint32_t i = 0; i < mCpuDescriptorHeapInfos.size(); i++) { - if (mCpuDescriptorHeapInfos[i].heap != nullptr) { - mCpuDescriptorHeapInfos[i].allocator.Deallocate(lastCompletedSerial); - } - } - - for (uint32_t i = 0; i < mGpuDescriptorHeapInfos.size(); i++) { - if (mGpuDescriptorHeapInfos[i].heap != nullptr) { - mGpuDescriptorHeapInfos[i].allocator.Deallocate(lastCompletedSerial); - } - } - } -}} // namespace dawn_native::d3d12 diff --git a/src/dawn_native/d3d12/DescriptorHeapAllocator.h b/src/dawn_native/d3d12/DescriptorHeapAllocator.h deleted file mode 100644 index bcb6ff5f01..0000000000 --- a/src/dawn_native/d3d12/DescriptorHeapAllocator.h +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2017 The Dawn Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef DAWNNATIVE_D3D12_DESCRIPTORHEAPALLOCATOR_H_ -#define DAWNNATIVE_D3D12_DESCRIPTORHEAPALLOCATOR_H_ - -#include "dawn_native/d3d12/d3d12_platform.h" - -#include -#include -#include "common/SerialQueue.h" - -#include "dawn_native/Error.h" -#include "dawn_native/RingBufferAllocator.h" - -namespace dawn_native { namespace d3d12 { - - class Device; - - class DescriptorHeapHandle { - public: - DescriptorHeapHandle(); - DescriptorHeapHandle(ComPtr descriptorHeap, - uint32_t sizeIncrement, - uint64_t offset); - - ID3D12DescriptorHeap* Get() const; - D3D12_CPU_DESCRIPTOR_HANDLE GetCPUHandle(uint32_t index) const; - D3D12_GPU_DESCRIPTOR_HANDLE GetGPUHandle(uint32_t index) const; - - private: - ComPtr mDescriptorHeap; - uint32_t mSizeIncrement; - uint64_t mOffset; - }; - - class DescriptorHeapAllocator { - public: - DescriptorHeapAllocator(Device* device); - - ResultOrError AllocateGPUHeap(D3D12_DESCRIPTOR_HEAP_TYPE type, - uint32_t count); - ResultOrError AllocateCPUHeap(D3D12_DESCRIPTOR_HEAP_TYPE type, - uint32_t count); - void Deallocate(uint64_t lastCompletedSerial); - - private: - struct DescriptorHeapInfo { - ComPtr heap; - RingBufferAllocator allocator; - }; - - ResultOrError Allocate(D3D12_DESCRIPTOR_HEAP_TYPE type, - uint32_t count, - uint32_t allocationSize, - DescriptorHeapInfo* heapInfo, - D3D12_DESCRIPTOR_HEAP_FLAGS flags); - - Device* mDevice; - - std::array mSizeIncrements; - std::array - mCpuDescriptorHeapInfos; - std::array - mGpuDescriptorHeapInfos; - }; - -}} // namespace dawn_native::d3d12 - -#endif // DAWNNATIVE_D3D12_DESCRIPTORHEAPALLOCATOR_H_ diff --git a/src/dawn_native/d3d12/DeviceD3D12.cpp b/src/dawn_native/d3d12/DeviceD3D12.cpp index 97c09d79a6..41895b3f8d 100644 --- a/src/dawn_native/d3d12/DeviceD3D12.cpp +++ b/src/dawn_native/d3d12/DeviceD3D12.cpp @@ -26,7 +26,6 @@ #include "dawn_native/d3d12/CommandBufferD3D12.h" #include "dawn_native/d3d12/ComputePipelineD3D12.h" #include "dawn_native/d3d12/D3D12Error.h" -#include "dawn_native/d3d12/DescriptorHeapAllocator.h" #include "dawn_native/d3d12/PipelineLayoutD3D12.h" #include "dawn_native/d3d12/PlatformFunctions.h" #include "dawn_native/d3d12/QueueD3D12.h" @@ -43,8 +42,9 @@ namespace dawn_native { namespace d3d12 { - // TODO(dawn:155): Figure out this value. - static constexpr uint16_t kStagingDescriptorHeapSize = 1024; + // TODO(dawn:155): Figure out these values. + static constexpr uint16_t kShaderVisibleDescriptorHeapSize = 1024; + static constexpr uint8_t kAttachmentDescriptorHeapSize = 64; // static ResultOrError Device::Create(Adapter* adapter, const DeviceDescriptor* descriptor) { @@ -81,7 +81,6 @@ namespace dawn_native { namespace d3d12 { // Initialize backend services mCommandAllocatorManager = std::make_unique(this); - mDescriptorHeapAllocator = std::make_unique(this); mShaderVisibleDescriptorAllocator = std::make_unique(this); @@ -91,13 +90,20 @@ namespace dawn_native { namespace d3d12 { for (uint32_t countIndex = 1; countIndex < kNumOfStagingDescriptorAllocators; countIndex++) { mViewAllocators[countIndex] = std::make_unique( - this, countIndex, kStagingDescriptorHeapSize, + this, countIndex, kShaderVisibleDescriptorHeapSize, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); mSamplerAllocators[countIndex] = std::make_unique( - this, countIndex, kStagingDescriptorHeapSize, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + this, countIndex, kShaderVisibleDescriptorHeapSize, + D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); } + mRenderTargetViewAllocator = std::make_unique( + this, 1, kAttachmentDescriptorHeapSize, D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + + mDepthStencilViewAllocator = std::make_unique( + this, 1, kAttachmentDescriptorHeapSize, D3D12_DESCRIPTOR_HEAP_TYPE_DSV); + mMapRequestTracker = std::make_unique(this); mResidencyManager = std::make_unique(this); mResourceAllocatorManager = std::make_unique(this); @@ -159,10 +165,6 @@ namespace dawn_native { namespace d3d12 { return mDrawIndexedIndirectSignature; } - DescriptorHeapAllocator* Device::GetDescriptorHeapAllocator() const { - return mDescriptorHeapAllocator.get(); - } - ComPtr Device::GetFactory() const { return ToBackend(GetAdapter())->GetBackend()->GetFactory(); } @@ -211,6 +213,8 @@ namespace dawn_native { namespace d3d12 { mResourceAllocatorManager->Tick(mCompletedSerial); DAWN_TRY(mCommandAllocatorManager->Tick(mCompletedSerial)); mShaderVisibleDescriptorAllocator->Tick(mCompletedSerial); + mRenderTargetViewAllocator->Tick(mCompletedSerial); + mDepthStencilViewAllocator->Tick(mCompletedSerial); mMapRequestTracker->Tick(mCompletedSerial); mUsedComObjectRefs.ClearUpTo(mCompletedSerial); DAWN_TRY(ExecutePendingCommandContext()); @@ -482,4 +486,13 @@ namespace dawn_native { namespace d3d12 { ASSERT(descriptorCount < kNumOfStagingDescriptorAllocators); return mSamplerAllocators[descriptorCount].get(); } + + StagingDescriptorAllocator* Device::GetRenderTargetViewAllocator() const { + return mRenderTargetViewAllocator.get(); + } + + StagingDescriptorAllocator* Device::GetDepthStencilViewAllocator() const { + return mDepthStencilViewAllocator.get(); + } + }} // namespace dawn_native::d3d12 diff --git a/src/dawn_native/d3d12/DeviceD3D12.h b/src/dawn_native/d3d12/DeviceD3D12.h index a5bff18148..f7298b5a31 100644 --- a/src/dawn_native/d3d12/DeviceD3D12.h +++ b/src/dawn_native/d3d12/DeviceD3D12.h @@ -67,7 +67,6 @@ namespace dawn_native { namespace d3d12 { ComPtr GetDrawIndirectSignature() const; ComPtr GetDrawIndexedIndirectSignature() const; - DescriptorHeapAllocator* GetDescriptorHeapAllocator() const; MapRequestTracker* GetMapRequestTracker() const; CommandAllocatorManager* GetCommandAllocatorManager() const; ResidencyManager* GetResidencyManager() const; @@ -110,6 +109,10 @@ namespace dawn_native { namespace d3d12 { StagingDescriptorAllocator* GetSamplerStagingDescriptorAllocator( uint32_t descriptorCount) const; + StagingDescriptorAllocator* GetRenderTargetViewAllocator() const; + + StagingDescriptorAllocator* GetDepthStencilViewAllocator() const; + TextureBase* WrapSharedHandle(const ExternalImageDescriptor* descriptor, HANDLE sharedHandle, uint64_t acquireMutexKey, @@ -173,7 +176,6 @@ namespace dawn_native { namespace d3d12 { SerialQueue> mUsedComObjectRefs; std::unique_ptr mCommandAllocatorManager; - std::unique_ptr mDescriptorHeapAllocator; std::unique_ptr mMapRequestTracker; std::unique_ptr mResourceAllocatorManager; std::unique_ptr mResidencyManager; @@ -187,6 +189,10 @@ namespace dawn_native { namespace d3d12 { std::array, kNumOfStagingDescriptorAllocators> mSamplerAllocators; + + std::unique_ptr mRenderTargetViewAllocator; + + std::unique_ptr mDepthStencilViewAllocator; }; }} // namespace dawn_native::d3d12 diff --git a/src/dawn_native/d3d12/RenderPassBuilderD3D12.cpp b/src/dawn_native/d3d12/RenderPassBuilderD3D12.cpp index c6846a06ca..19657849a1 100644 --- a/src/dawn_native/d3d12/RenderPassBuilderD3D12.cpp +++ b/src/dawn_native/d3d12/RenderPassBuilderD3D12.cpp @@ -102,19 +102,24 @@ namespace dawn_native { namespace d3d12 { } } // anonymous namespace - RenderPassBuilder::RenderPassBuilder(const OMSetRenderTargetArgs& args, bool hasUAV) - : mColorAttachmentCount(args.numRTVs), mRenderTargetViews(args.RTVs.data()) { - for (uint32_t i = 0; i < mColorAttachmentCount; i++) { - mRenderPassRenderTargetDescriptors[i].cpuDescriptor = args.RTVs[i]; - } - - mRenderPassDepthStencilDesc.cpuDescriptor = args.dsv; - + RenderPassBuilder::RenderPassBuilder(bool hasUAV) { if (hasUAV) { mRenderPassFlags = D3D12_RENDER_PASS_FLAG_ALLOW_UAV_WRITES; } } + void RenderPassBuilder::SetRenderTargetView(uint32_t attachmentIndex, + D3D12_CPU_DESCRIPTOR_HANDLE baseDescriptor) { + ASSERT(mColorAttachmentCount < kMaxColorAttachments); + mRenderTargetViews[attachmentIndex] = baseDescriptor; + mRenderPassRenderTargetDescriptors[attachmentIndex].cpuDescriptor = baseDescriptor; + mColorAttachmentCount++; + } + + void RenderPassBuilder::SetDepthStencilView(D3D12_CPU_DESCRIPTOR_HANDLE baseDescriptor) { + mRenderPassDepthStencilDesc.cpuDescriptor = baseDescriptor; + } + uint32_t RenderPassBuilder::GetColorAttachmentCount() const { return mColorAttachmentCount; } @@ -138,7 +143,7 @@ namespace dawn_native { namespace d3d12 { } const D3D12_CPU_DESCRIPTOR_HANDLE* RenderPassBuilder::GetRenderTargetViews() const { - return mRenderTargetViews; + return mRenderTargetViews.data(); } void RenderPassBuilder::SetRenderTargetBeginningAccess(uint32_t attachment, diff --git a/src/dawn_native/d3d12/RenderPassBuilderD3D12.h b/src/dawn_native/d3d12/RenderPassBuilderD3D12.h index 1ecd87e3ce..aadb2e8226 100644 --- a/src/dawn_native/d3d12/RenderPassBuilderD3D12.h +++ b/src/dawn_native/d3d12/RenderPassBuilderD3D12.h @@ -25,8 +25,6 @@ namespace dawn_native { namespace d3d12 { class TextureView; - struct OMSetRenderTargetArgs; - // RenderPassBuilder stores parameters related to render pass load and store operations. // When the D3D12 render pass API is available, the needed descriptors can be fetched // directly from the RenderPassBuilder. When the D3D12 render pass API is not available, the @@ -34,7 +32,7 @@ namespace dawn_native { namespace d3d12 { // operations is extracted from the descriptors. class RenderPassBuilder { public: - RenderPassBuilder(const OMSetRenderTargetArgs& args, bool hasUAV); + RenderPassBuilder(bool hasUAV); uint32_t GetColorAttachmentCount() const; @@ -72,6 +70,10 @@ namespace dawn_native { namespace d3d12 { DXGI_FORMAT format); void SetStencilNoAccess(); + void SetRenderTargetView(uint32_t attachmentIndex, + D3D12_CPU_DESCRIPTOR_HANDLE baseDescriptor); + void SetDepthStencilView(D3D12_CPU_DESCRIPTOR_HANDLE baseDescriptor); + private: uint32_t mColorAttachmentCount = 0; bool mHasDepth = false; @@ -79,7 +81,7 @@ namespace dawn_native { namespace d3d12 { D3D12_RENDER_PASS_DEPTH_STENCIL_DESC mRenderPassDepthStencilDesc; std::array mRenderPassRenderTargetDescriptors; - const D3D12_CPU_DESCRIPTOR_HANDLE* mRenderTargetViews; + std::array mRenderTargetViews; std::array mSubresourceParams; diff --git a/src/dawn_native/d3d12/StagingDescriptorAllocatorD3D12.cpp b/src/dawn_native/d3d12/StagingDescriptorAllocatorD3D12.cpp index d7e0653a1b..84fd7880ca 100644 --- a/src/dawn_native/d3d12/StagingDescriptorAllocatorD3D12.cpp +++ b/src/dawn_native/d3d12/StagingDescriptorAllocatorD3D12.cpp @@ -29,8 +29,6 @@ namespace dawn_native { namespace d3d12 { mBlockSize(descriptorCount * mSizeIncrement), mHeapSize(RoundUp(heapSize, descriptorCount)), mHeapType(heapType) { - ASSERT(heapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || - heapType == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); ASSERT(descriptorCount <= heapSize); } @@ -98,6 +96,8 @@ namespace dawn_native { namespace d3d12 { } void StagingDescriptorAllocator::Deallocate(CPUDescriptorHeapAllocation* allocation) { + ASSERT(allocation->IsValid()); + const uint32_t heapIndex = allocation->GetHeapIndex(); ASSERT(heapIndex < mPool.size()); @@ -132,4 +132,21 @@ namespace dawn_native { namespace d3d12 { return ((mHeapSize * mSizeIncrement) / mBlockSize); } + ResultOrError + StagingDescriptorAllocator::AllocateTransientCPUDescriptors() { + CPUDescriptorHeapAllocation allocation; + DAWN_TRY_ASSIGN(allocation, AllocateCPUDescriptors()); + mAllocationsToDelete.Enqueue(allocation, mDevice->GetPendingCommandSerial()); + return allocation; + } + + void StagingDescriptorAllocator::Tick(Serial completedSerial) { + for (CPUDescriptorHeapAllocation& allocation : + mAllocationsToDelete.IterateUpTo(completedSerial)) { + Deallocate(&allocation); + } + + mAllocationsToDelete.ClearUpTo(completedSerial); + } + }} // namespace dawn_native::d3d12 \ No newline at end of file diff --git a/src/dawn_native/d3d12/StagingDescriptorAllocatorD3D12.h b/src/dawn_native/d3d12/StagingDescriptorAllocatorD3D12.h index 292fb10109..eebbe2a164 100644 --- a/src/dawn_native/d3d12/StagingDescriptorAllocatorD3D12.h +++ b/src/dawn_native/d3d12/StagingDescriptorAllocatorD3D12.h @@ -45,10 +45,15 @@ namespace dawn_native { namespace d3d12 { ResultOrError AllocateCPUDescriptors(); + // Will call Deallocate when the serial is passed. + ResultOrError AllocateTransientCPUDescriptors(); + void Deallocate(CPUDescriptorHeapAllocation* allocation); uint32_t GetSizeIncrement() const; + void Tick(Serial completedSerial); + private: using Index = uint16_t; @@ -71,6 +76,8 @@ namespace dawn_native { namespace d3d12 { uint32_t mHeapSize; // Size of the heap (in number of descriptors). D3D12_DESCRIPTOR_HEAP_TYPE mHeapType; + + SerialQueue mAllocationsToDelete; }; }} // namespace dawn_native::d3d12 diff --git a/src/dawn_native/d3d12/TextureD3D12.cpp b/src/dawn_native/d3d12/TextureD3D12.cpp index c9242c15ea..bbcd4e191c 100644 --- a/src/dawn_native/d3d12/TextureD3D12.cpp +++ b/src/dawn_native/d3d12/TextureD3D12.cpp @@ -21,11 +21,11 @@ #include "dawn_native/d3d12/BufferD3D12.h" #include "dawn_native/d3d12/CommandRecordingContext.h" #include "dawn_native/d3d12/D3D12Error.h" -#include "dawn_native/d3d12/DescriptorHeapAllocator.h" #include "dawn_native/d3d12/DeviceD3D12.h" #include "dawn_native/d3d12/HeapD3D12.h" #include "dawn_native/d3d12/ResourceAllocatorManagerD3D12.h" #include "dawn_native/d3d12/StagingBufferD3D12.h" +#include "dawn_native/d3d12/StagingDescriptorAllocatorD3D12.h" #include "dawn_native/d3d12/TextureCopySplitter.h" #include "dawn_native/d3d12/UtilsD3D12.h" @@ -622,7 +622,6 @@ namespace dawn_native { namespace d3d12 { ID3D12GraphicsCommandList* commandList = commandContext->GetCommandList(); Device* device = ToBackend(GetDevice()); - DescriptorHeapAllocator* descriptorHeapAllocator = device->GetDescriptorHeapAllocator(); uint8_t clearColor = (clearValue == TextureBase::ClearValue::Zero) ? 0 : 1; float fClearColor = (clearValue == TextureBase::ClearValue::Zero) ? 0.f : 1.f; @@ -642,13 +641,14 @@ namespace dawn_native { namespace d3d12 { continue; } - DescriptorHeapHandle dsvHeap; - DAWN_TRY_ASSIGN(dsvHeap, descriptorHeapAllocator->AllocateCPUHeap( - D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1)); - D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = dsvHeap.GetCPUHandle(0); + CPUDescriptorHeapAllocation dsvHandle; + DAWN_TRY_ASSIGN(dsvHandle, device->GetDepthStencilViewAllocator() + ->AllocateTransientCPUDescriptors()); + const D3D12_CPU_DESCRIPTOR_HANDLE baseDescriptor = + dsvHandle.GetBaseDescriptor(); D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = GetDSVDescriptor(level, layer, 1); device->GetD3D12Device()->CreateDepthStencilView(GetD3D12Resource(), - &dsvDesc, dsvHandle); + &dsvDesc, baseDescriptor); if (GetFormat().HasDepth()) { clearFlags |= D3D12_CLEAR_FLAG_DEPTH; @@ -657,7 +657,7 @@ namespace dawn_native { namespace d3d12 { clearFlags |= D3D12_CLEAR_FLAG_STENCIL; } - commandList->ClearDepthStencilView(dsvHandle, clearFlags, fClearColor, + commandList->ClearDepthStencilView(baseDescriptor, clearFlags, fClearColor, clearColor, 0, nullptr); } } @@ -676,10 +676,10 @@ namespace dawn_native { namespace d3d12 { continue; } - DescriptorHeapHandle rtvHeap; - DAWN_TRY_ASSIGN(rtvHeap, descriptorHeapAllocator->AllocateCPUHeap( - D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1)); - D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = rtvHeap.GetCPUHandle(0); + CPUDescriptorHeapAllocation rtvHeap; + DAWN_TRY_ASSIGN(rtvHeap, device->GetRenderTargetViewAllocator() + ->AllocateTransientCPUDescriptors()); + const D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = rtvHeap.GetBaseDescriptor(); D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = GetRTVDescriptor(level, layer, 1); device->GetD3D12Device()->CreateRenderTargetView(GetD3D12Resource(),