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 <bryan.bernhart@intel.com>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn_native/BUILD.gn b/src/dawn_native/BUILD.gn
index d11afca..4251196 100644
--- a/src/dawn_native/BUILD.gn
+++ b/src/dawn_native/BUILD.gn
@@ -301,8 +301,6 @@
"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 ff46a74..9d78325 100644
--- a/src/dawn_native/CMakeLists.txt
+++ b/src/dawn_native/CMakeLists.txt
@@ -182,8 +182,6 @@
"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 14d0f95..2726e5c 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 {
-
- // TODO(jiawei.shao@intel.com): use hash map <RenderPass, OMSetRenderTargetArgs> as
- // cache to avoid redundant RTV and DSV memory allocations.
- ResultOrError<OMSetRenderTargetArgs> GetSubpassOMSetRenderTargetArgs(
- BeginRenderPassCmd* renderPass,
- Device* device) {
- OMSetRenderTargetArgs args = {};
-
- uint32_t rtvCount = static_cast<uint32_t>(
- 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 @@
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 @@
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 @@
} else {
renderPassBuilder->SetDepthStencilNoAccess();
}
+
+ return {};
}
void CommandBuffer::EmulateBeginRenderPass(CommandRecordingContext* commandContext,
@@ -958,17 +943,14 @@
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 b49882b..cc53fd5 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 <array>
@@ -31,12 +29,6 @@
namespace dawn_native { namespace d3d12 {
- struct OMSetRenderTargetArgs {
- unsigned int numRTVs = 0;
- std::array<D3D12_CPU_DESCRIPTOR_HANDLE, kMaxColorAttachments> RTVs = {};
- D3D12_CPU_DESCRIPTOR_HANDLE dsv = {};
- };
-
class BindGroupStateTracker;
class CommandRecordingContext;
class Device;
@@ -58,9 +50,9 @@
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 facc307..0000000
--- 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<ID3D12DescriptorHeap> 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<DescriptorHeapHandle> 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<ID3D12DescriptorHeap> 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<DescriptorHeapHandle> DescriptorHeapAllocator::AllocateCPUHeap(
- D3D12_DESCRIPTOR_HEAP_TYPE type,
- uint32_t count) {
- return Allocate(type, count, count, &mCpuDescriptorHeapInfos[type],
- D3D12_DESCRIPTOR_HEAP_FLAG_NONE);
- }
-
- ResultOrError<DescriptorHeapHandle> 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 bcb6ff5..0000000
--- 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 <array>
-#include <vector>
-#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<ID3D12DescriptorHeap> 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<ID3D12DescriptorHeap> mDescriptorHeap;
- uint32_t mSizeIncrement;
- uint64_t mOffset;
- };
-
- class DescriptorHeapAllocator {
- public:
- DescriptorHeapAllocator(Device* device);
-
- ResultOrError<DescriptorHeapHandle> AllocateGPUHeap(D3D12_DESCRIPTOR_HEAP_TYPE type,
- uint32_t count);
- ResultOrError<DescriptorHeapHandle> AllocateCPUHeap(D3D12_DESCRIPTOR_HEAP_TYPE type,
- uint32_t count);
- void Deallocate(uint64_t lastCompletedSerial);
-
- private:
- struct DescriptorHeapInfo {
- ComPtr<ID3D12DescriptorHeap> heap;
- RingBufferAllocator allocator;
- };
-
- ResultOrError<DescriptorHeapHandle> Allocate(D3D12_DESCRIPTOR_HEAP_TYPE type,
- uint32_t count,
- uint32_t allocationSize,
- DescriptorHeapInfo* heapInfo,
- D3D12_DESCRIPTOR_HEAP_FLAGS flags);
-
- Device* mDevice;
-
- std::array<uint32_t, D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES> mSizeIncrements;
- std::array<DescriptorHeapInfo, D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES>
- mCpuDescriptorHeapInfos;
- std::array<DescriptorHeapInfo, D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES>
- 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 97c09d7..41895b3 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*> Device::Create(Adapter* adapter, const DeviceDescriptor* descriptor) {
@@ -81,7 +81,6 @@
// Initialize backend services
mCommandAllocatorManager = std::make_unique<CommandAllocatorManager>(this);
- mDescriptorHeapAllocator = std::make_unique<DescriptorHeapAllocator>(this);
mShaderVisibleDescriptorAllocator =
std::make_unique<ShaderVisibleDescriptorAllocator>(this);
@@ -91,13 +90,20 @@
for (uint32_t countIndex = 1; countIndex < kNumOfStagingDescriptorAllocators;
countIndex++) {
mViewAllocators[countIndex] = std::make_unique<StagingDescriptorAllocator>(
- this, countIndex, kStagingDescriptorHeapSize,
+ this, countIndex, kShaderVisibleDescriptorHeapSize,
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
mSamplerAllocators[countIndex] = std::make_unique<StagingDescriptorAllocator>(
- this, countIndex, kStagingDescriptorHeapSize, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
+ this, countIndex, kShaderVisibleDescriptorHeapSize,
+ D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
}
+ mRenderTargetViewAllocator = std::make_unique<StagingDescriptorAllocator>(
+ this, 1, kAttachmentDescriptorHeapSize, D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
+
+ mDepthStencilViewAllocator = std::make_unique<StagingDescriptorAllocator>(
+ this, 1, kAttachmentDescriptorHeapSize, D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
+
mMapRequestTracker = std::make_unique<MapRequestTracker>(this);
mResidencyManager = std::make_unique<ResidencyManager>(this);
mResourceAllocatorManager = std::make_unique<ResourceAllocatorManager>(this);
@@ -159,10 +165,6 @@
return mDrawIndexedIndirectSignature;
}
- DescriptorHeapAllocator* Device::GetDescriptorHeapAllocator() const {
- return mDescriptorHeapAllocator.get();
- }
-
ComPtr<IDXGIFactory4> Device::GetFactory() const {
return ToBackend(GetAdapter())->GetBackend()->GetFactory();
}
@@ -211,6 +213,8 @@
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 @@
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 a5bff18..f7298b5 100644
--- a/src/dawn_native/d3d12/DeviceD3D12.h
+++ b/src/dawn_native/d3d12/DeviceD3D12.h
@@ -67,7 +67,6 @@
ComPtr<ID3D12CommandSignature> GetDrawIndirectSignature() const;
ComPtr<ID3D12CommandSignature> GetDrawIndexedIndirectSignature() const;
- DescriptorHeapAllocator* GetDescriptorHeapAllocator() const;
MapRequestTracker* GetMapRequestTracker() const;
CommandAllocatorManager* GetCommandAllocatorManager() const;
ResidencyManager* GetResidencyManager() const;
@@ -110,6 +109,10 @@
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 @@
SerialQueue<ComPtr<IUnknown>> mUsedComObjectRefs;
std::unique_ptr<CommandAllocatorManager> mCommandAllocatorManager;
- std::unique_ptr<DescriptorHeapAllocator> mDescriptorHeapAllocator;
std::unique_ptr<MapRequestTracker> mMapRequestTracker;
std::unique_ptr<ResourceAllocatorManager> mResourceAllocatorManager;
std::unique_ptr<ResidencyManager> mResidencyManager;
@@ -187,6 +189,10 @@
std::array<std::unique_ptr<StagingDescriptorAllocator>, kNumOfStagingDescriptorAllocators>
mSamplerAllocators;
+
+ std::unique_ptr<StagingDescriptorAllocator> mRenderTargetViewAllocator;
+
+ std::unique_ptr<StagingDescriptorAllocator> mDepthStencilViewAllocator;
};
}} // namespace dawn_native::d3d12
diff --git a/src/dawn_native/d3d12/RenderPassBuilderD3D12.cpp b/src/dawn_native/d3d12/RenderPassBuilderD3D12.cpp
index c6846a0..1965784 100644
--- a/src/dawn_native/d3d12/RenderPassBuilderD3D12.cpp
+++ b/src/dawn_native/d3d12/RenderPassBuilderD3D12.cpp
@@ -102,19 +102,24 @@
}
} // 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 @@
}
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 1ecd87e..aadb2e8 100644
--- a/src/dawn_native/d3d12/RenderPassBuilderD3D12.h
+++ b/src/dawn_native/d3d12/RenderPassBuilderD3D12.h
@@ -25,8 +25,6 @@
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 @@
// 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 @@
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 @@
D3D12_RENDER_PASS_DEPTH_STENCIL_DESC mRenderPassDepthStencilDesc;
std::array<D3D12_RENDER_PASS_RENDER_TARGET_DESC, kMaxColorAttachments>
mRenderPassRenderTargetDescriptors;
- const D3D12_CPU_DESCRIPTOR_HANDLE* mRenderTargetViews;
+ std::array<D3D12_CPU_DESCRIPTOR_HANDLE, kMaxColorAttachments> mRenderTargetViews;
std::array<D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_SUBRESOURCE_PARAMETERS,
kMaxColorAttachments>
mSubresourceParams;
diff --git a/src/dawn_native/d3d12/StagingDescriptorAllocatorD3D12.cpp b/src/dawn_native/d3d12/StagingDescriptorAllocatorD3D12.cpp
index d7e0653..84fd788 100644
--- a/src/dawn_native/d3d12/StagingDescriptorAllocatorD3D12.cpp
+++ b/src/dawn_native/d3d12/StagingDescriptorAllocatorD3D12.cpp
@@ -29,8 +29,6 @@
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 @@
}
void StagingDescriptorAllocator::Deallocate(CPUDescriptorHeapAllocation* allocation) {
+ ASSERT(allocation->IsValid());
+
const uint32_t heapIndex = allocation->GetHeapIndex();
ASSERT(heapIndex < mPool.size());
@@ -132,4 +132,21 @@
return ((mHeapSize * mSizeIncrement) / mBlockSize);
}
+ ResultOrError<CPUDescriptorHeapAllocation>
+ 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 292fb10..eebbe2a 100644
--- a/src/dawn_native/d3d12/StagingDescriptorAllocatorD3D12.h
+++ b/src/dawn_native/d3d12/StagingDescriptorAllocatorD3D12.h
@@ -45,10 +45,15 @@
ResultOrError<CPUDescriptorHeapAllocation> AllocateCPUDescriptors();
+ // Will call Deallocate when the serial is passed.
+ ResultOrError<CPUDescriptorHeapAllocation> AllocateTransientCPUDescriptors();
+
void Deallocate(CPUDescriptorHeapAllocation* allocation);
uint32_t GetSizeIncrement() const;
+ void Tick(Serial completedSerial);
+
private:
using Index = uint16_t;
@@ -71,6 +76,8 @@
uint32_t mHeapSize; // Size of the heap (in number of descriptors).
D3D12_DESCRIPTOR_HEAP_TYPE mHeapType;
+
+ SerialQueue<CPUDescriptorHeapAllocation> mAllocationsToDelete;
};
}} // namespace dawn_native::d3d12
diff --git a/src/dawn_native/d3d12/TextureD3D12.cpp b/src/dawn_native/d3d12/TextureD3D12.cpp
index c9242c1..bbcd4e1 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 @@
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 @@
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 @@
clearFlags |= D3D12_CLEAR_FLAG_STENCIL;
}
- commandList->ClearDepthStencilView(dsvHandle, clearFlags, fClearColor,
+ commandList->ClearDepthStencilView(baseDescriptor, clearFlags, fClearColor,
clearColor, 0, nullptr);
}
}
@@ -676,10 +676,10 @@
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(),