D3D12: Use ringbuffer allocator for descriptor heaps.
Enable descriptor heap re-use by using ringbuffer.
BUG=dawn:155
Change-Id: I72e3fb98a64dc1af671e185e2114868a577a0554
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/9460
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Bryan Bernhart <bryan.bernhart@intel.com>
diff --git a/src/dawn_native/RingBufferAllocator.h b/src/dawn_native/RingBufferAllocator.h
index 82241b3..60ee639 100644
--- a/src/dawn_native/RingBufferAllocator.h
+++ b/src/dawn_native/RingBufferAllocator.h
@@ -25,6 +25,7 @@
class RingBufferAllocator {
public:
+ RingBufferAllocator() = default;
RingBufferAllocator(size_t maxSize);
~RingBufferAllocator() = default;
diff --git a/src/dawn_native/d3d12/DescriptorHeapAllocator.cpp b/src/dawn_native/d3d12/DescriptorHeapAllocator.cpp
index 3f28e5a..29ccab7 100644
--- a/src/dawn_native/d3d12/DescriptorHeapAllocator.cpp
+++ b/src/dawn_native/d3d12/DescriptorHeapAllocator.cpp
@@ -67,24 +67,12 @@
uint32_t allocationSize,
DescriptorHeapInfo* heapInfo,
D3D12_DESCRIPTOR_HEAP_FLAGS flags) {
- // TODO(enga@google.com): This is just a linear allocator so the heap will quickly run out
- // of space causing a new one to be allocated We should reuse heap subranges that have been
- // released
- if (count == 0) {
- return DescriptorHeapHandle();
- }
-
- {
- // If the current pool for this type has space, linearly allocate count bytes in the
- // pool
- auto& allocationInfo = heapInfo->second;
- if (allocationInfo.remaining >= count) {
- DescriptorHeapHandle handle(heapInfo->first, mSizeIncrements[type],
- allocationInfo.size - allocationInfo.remaining);
- allocationInfo.remaining -= count;
- Release(handle);
- return handle;
- }
+ const Serial pendingSerial = mDevice->GetPendingCommandSerial();
+ size_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
@@ -100,12 +88,15 @@
return DAWN_OUT_OF_MEMORY_ERROR("Unable to allocate heap");
}
- AllocationInfo allocationInfo = {allocationSize, allocationSize - count};
- *heapInfo = std::make_pair(heap, allocationInfo);
+ mDevice->ReferenceUntilUnused(heap);
- DescriptorHeapHandle handle(heap, mSizeIncrements[type], 0);
- Release(handle);
- return handle;
+ *heapInfo = {heap, RingBufferAllocator(allocationSize)};
+
+ startOffset = heapInfo->allocator.Allocate(count, pendingSerial);
+
+ ASSERT(startOffset != RingBufferAllocator::kInvalidOffset);
+
+ return DescriptorHeapHandle(heap, mSizeIncrements[type], startOffset);
}
ResultOrError<DescriptorHeapHandle> DescriptorHeapAllocator::AllocateCPUHeap(
@@ -120,18 +111,24 @@
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 ? kMaxCbvUavSrvHeapSize
- : kMaxSamplerHeapSize);
+ 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::Tick(uint64_t lastCompletedSerial) {
- mReleasedHandles.ClearUpTo(lastCompletedSerial);
- }
+ 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);
+ }
+ }
- void DescriptorHeapAllocator::Release(DescriptorHeapHandle handle) {
- mReleasedHandles.Enqueue(handle, mDevice->GetPendingCommandSerial());
+ 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
index d98b7a8f..e4949a6 100644
--- a/src/dawn_native/d3d12/DescriptorHeapAllocator.h
+++ b/src/dawn_native/d3d12/DescriptorHeapAllocator.h
@@ -22,6 +22,7 @@
#include "common/SerialQueue.h"
#include "dawn_native/Error.h"
+#include "dawn_native/RingBufferAllocator.h"
namespace dawn_native { namespace d3d12 {
@@ -52,34 +53,27 @@
uint32_t count);
ResultOrError<DescriptorHeapHandle> AllocateCPUHeap(D3D12_DESCRIPTOR_HEAP_TYPE type,
uint32_t count);
- void Tick(uint64_t lastCompletedSerial);
+ void Deallocate(uint64_t lastCompletedSerial);
private:
- static constexpr unsigned int kMaxCbvUavSrvHeapSize = 1000000;
- static constexpr unsigned int kMaxSamplerHeapSize = 2048;
- static constexpr unsigned int kDescriptorHeapTypes =
- D3D12_DESCRIPTOR_HEAP_TYPE::D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES;
-
- struct AllocationInfo {
- uint32_t size = 0;
- uint32_t remaining = 0;
+ struct DescriptorHeapInfo {
+ ComPtr<ID3D12DescriptorHeap> heap;
+ RingBufferAllocator allocator;
};
- using DescriptorHeapInfo = std::pair<ComPtr<ID3D12DescriptorHeap>, AllocationInfo>;
-
ResultOrError<DescriptorHeapHandle> Allocate(D3D12_DESCRIPTOR_HEAP_TYPE type,
uint32_t count,
uint32_t allocationSize,
DescriptorHeapInfo* heapInfo,
D3D12_DESCRIPTOR_HEAP_FLAGS flags);
- void Release(DescriptorHeapHandle handle);
Device* mDevice;
- std::array<uint32_t, kDescriptorHeapTypes> mSizeIncrements;
- std::array<DescriptorHeapInfo, kDescriptorHeapTypes> mCpuDescriptorHeapInfos;
- std::array<DescriptorHeapInfo, kDescriptorHeapTypes> mGpuDescriptorHeapInfos;
- SerialQueue<DescriptorHeapHandle> mReleasedHandles;
+ 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
diff --git a/src/dawn_native/d3d12/DeviceD3D12.cpp b/src/dawn_native/d3d12/DeviceD3D12.cpp
index ffc5a7ed..2f535ee 100644
--- a/src/dawn_native/d3d12/DeviceD3D12.cpp
+++ b/src/dawn_native/d3d12/DeviceD3D12.cpp
@@ -221,7 +221,7 @@
mResourceAllocator->Tick(mCompletedSerial);
mCommandAllocatorManager->Tick(mCompletedSerial);
- mDescriptorHeapAllocator->Tick(mCompletedSerial);
+ mDescriptorHeapAllocator->Deallocate(mCompletedSerial);
mMapRequestTracker->Tick(mCompletedSerial);
mUsedComObjectRefs.ClearUpTo(mCompletedSerial);
ExecuteCommandList(nullptr);