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>
This commit is contained in:
parent
e06f01be71
commit
e6b93e8706
|
@ -25,6 +25,7 @@ namespace dawn_native {
|
|||
|
||||
class RingBufferAllocator {
|
||||
public:
|
||||
RingBufferAllocator() = default;
|
||||
RingBufferAllocator(size_t maxSize);
|
||||
~RingBufferAllocator() = default;
|
||||
|
||||
|
|
|
@ -67,24 +67,12 @@ namespace dawn_native { namespace d3d12 {
|
|||
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 @@ namespace dawn_native { namespace d3d12 {
|
|||
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 @@ namespace dawn_native { namespace d3d12 {
|
|||
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
|
||||
|
|
|
@ -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 @@ namespace dawn_native { namespace d3d12 {
|
|||
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
|
||||
|
|
|
@ -221,7 +221,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
mResourceAllocator->Tick(mCompletedSerial);
|
||||
mCommandAllocatorManager->Tick(mCompletedSerial);
|
||||
mDescriptorHeapAllocator->Tick(mCompletedSerial);
|
||||
mDescriptorHeapAllocator->Deallocate(mCompletedSerial);
|
||||
mMapRequestTracker->Tick(mCompletedSerial);
|
||||
mUsedComObjectRefs.ClearUpTo(mCompletedSerial);
|
||||
ExecuteCommandList(nullptr);
|
||||
|
|
Loading…
Reference in New Issue