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>
This commit is contained in:
parent
96c4019214
commit
7434b2c67d
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 <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 @@ 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.
|
||||
|
|
|
@ -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 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 @@ 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;
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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_
|
|
@ -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 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
// 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 @@ namespace dawn_native { namespace d3d12 {
|
|||
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 @@ namespace dawn_native { namespace d3d12 {
|
|||
return mDrawIndexedIndirectSignature;
|
||||
}
|
||||
|
||||
DescriptorHeapAllocator* Device::GetDescriptorHeapAllocator() const {
|
||||
return mDescriptorHeapAllocator.get();
|
||||
}
|
||||
|
||||
ComPtr<IDXGIFactory4> 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
|
||||
|
|
|
@ -67,7 +67,6 @@ namespace dawn_native { namespace d3d12 {
|
|||
ComPtr<ID3D12CommandSignature> GetDrawIndirectSignature() const;
|
||||
ComPtr<ID3D12CommandSignature> 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<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 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
std::array<std::unique_ptr<StagingDescriptorAllocator>, kNumOfStagingDescriptorAllocators>
|
||||
mSamplerAllocators;
|
||||
|
||||
std::unique_ptr<StagingDescriptorAllocator> mRenderTargetViewAllocator;
|
||||
|
||||
std::unique_ptr<StagingDescriptorAllocator> mDepthStencilViewAllocator;
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<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;
|
||||
|
|
|
@ -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<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
|
|
@ -45,10 +45,15 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
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 @@ namespace dawn_native { namespace d3d12 {
|
|||
uint32_t mHeapSize; // Size of the heap (in number of descriptors).
|
||||
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE mHeapType;
|
||||
|
||||
SerialQueue<CPUDescriptorHeapAllocation> mAllocationsToDelete;
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
|
|
@ -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(),
|
||||
|
|
Loading…
Reference in New Issue