Move heap descriptor into its own file and prepare for the removing of the staging descriptor

This commit is contained in:
2025-03-29 22:05:09 -04:00
parent 94292851cc
commit 76848ab4e3
9 changed files with 239 additions and 215 deletions

View File

@@ -187,6 +187,7 @@
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_state_object.h" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\dxgiformat.h" />
<ClInclude Include="src\Graphics\D3D12\D3D12Common.h"/>
<ClInclude Include="src\Graphics\D3D12\D3D12DescriptorHeap.h" />
<ClInclude Include="src\Graphics\D3D12\D3D12GraphicsPipeline.h" />
<ClInclude Include="src\Graphics\D3D12\D3D12RenderPass.h"/>
<ClInclude Include="src\Graphics\D3D12\D3D12Shader.h"/>
@@ -231,6 +232,7 @@
<ClCompile Include="src\Engine\Engine.cpp" />
<ClCompile Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_property_format_table.cpp" />
<ClCompile Include="src\Graphics\D3D12\D3D12Common.cpp" />
<ClCompile Include="src\Graphics\D3D12\D3D12DescriptorHeap.cpp" />
<ClCompile Include="src\Graphics\D3D12\D3D12GraphicsPipeline.cpp" />
<ClCompile Include="src\Graphics\D3D12\D3D12RenderPass.cpp" />
<ClCompile Include="src\Graphics\D3D12\D3D12Shader.cpp" />

View File

@@ -368,79 +368,14 @@ namespace Juliet::D3D12
namespace Internal
{
namespace
{
D3D12DescriptorHeap* AcquireDescriptorHeapFromPool(NonNullPtr<D3D12CommandList> commandList, D3D12_DESCRIPTOR_HEAP_TYPE type)
{
D3D12Driver* d3d12Driver = commandList->Driver;
D3D12DescriptorHeapPool* pool = nullptr;
uint32 count = 0;
if (type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)
{
pool = &d3d12Driver->CRB_SRV_UAV_HeapPool;
count = GPUDriver::kCBV_SRV_UAV_HeapDescriptorCount;
}
else if (type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER)
{
pool = &d3d12Driver->RTV_HeapPool;
count = GPUDriver::kSampler_HeapDescriptorCount;
}
Assert(pool != nullptr);
D3D12DescriptorHeap* result = nullptr;
if (pool->Count > 0)
{
result = pool->Heaps[pool->Count - 1];
pool->Count -= 1;
}
else
{
result = CreateDescriptorHeap(d3d12Driver, type, count, false);
}
return result;
}
void ReturnDescriptorHeapToPool(NonNullPtr<D3D12Driver> d3d12Driver, D3D12DescriptorHeap* heap)
{
if (heap == nullptr)
{
return;
}
D3D12DescriptorHeapPool* pool = nullptr;
if (heap->HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)
{
pool = &d3d12Driver->CRB_SRV_UAV_HeapPool;
}
else if (heap->HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER)
{
pool = &d3d12Driver->RTV_HeapPool;
}
Assert(pool != nullptr);
heap->CurrentDescriptorIndex = 0;
if (pool->Count >= pool->Capacity)
{
pool->Capacity *= 2;
pool->Heaps =
static_cast<D3D12DescriptorHeap**>(Realloc(pool->Heaps, pool->Capacity * sizeof(D3D12DescriptorHeap*)));
}
pool->Heaps[pool->Count] = heap;
pool->Count += 1;
}
} // namespace
void SetDescriptorHeaps(NonNullPtr<D3D12CommandList> commandList)
{
ID3D12DescriptorHeap* heaps[2];
D3D12DescriptorHeap* viewHeap = nullptr;
D3D12DescriptorHeap* samplerHeap = nullptr;
viewHeap = AcquireDescriptorHeapFromPool(commandList, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
samplerHeap = AcquireDescriptorHeapFromPool(commandList, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
viewHeap = AcquireDescriptorHeapFromPool(commandList->Driver, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
samplerHeap = AcquireDescriptorHeapFromPool(commandList->Driver, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
commandList->CRB_SRV_UAV_Heap = viewHeap;
commandList->RTV_Heap = samplerHeap;

View File

@@ -75,8 +75,8 @@ namespace Juliet::D3D12
// D3D12UniformBuffer *vertexUniformBuffers[GPUDriver::kMaxUniformBuffersPerStage];
// D3D12UniformBuffer *fragmentUniformBuffers[GPUDriver::kMaxUniformBuffersPerStage];
D3D12DescriptorHeap* CRB_SRV_UAV_Heap;
D3D12DescriptorHeap* RTV_Heap;
Internal::D3D12DescriptorHeap* CRB_SRV_UAV_Heap;
Internal::D3D12DescriptorHeap* RTV_Heap;
// Resource Tracking
D3D12Texture** UsedTextures;

View File

@@ -8,7 +8,7 @@
#include <Graphics/D3D12/D3D12Includes.h>
#include <Graphics/D3D12/D3D12Utils.h>
namespace Juliet::D3D12
namespace Juliet::D3D12::Internal
{
namespace
{
@@ -49,126 +49,72 @@ namespace Juliet::D3D12
}
} // namespace
namespace Internal
D3D12StagingDescriptorPool* CreateStagingDescriptorPool(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type)
{
D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type,
uint32 count, bool isStaging)
D3D12DescriptorHeap* heap = CreateDescriptorHeap(driver, type, kStagingHeapDescriptorExpectedCount, true);
if (!heap)
{
ID3D12DescriptorHeap* handle;
auto heap = static_cast<D3D12DescriptorHeap*>(Calloc(1, sizeof(D3D12DescriptorHeap)));
if (!heap)
{
return nullptr;
}
heap->CurrentDescriptorIndex = 0;
D3D12_DESCRIPTOR_HEAP_DESC heapDesc;
heapDesc.NumDescriptors = count;
heapDesc.Type = type;
heapDesc.Flags = isStaging ? D3D12_DESCRIPTOR_HEAP_FLAG_NONE : D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
heapDesc.NodeMask = 0;
HRESULT result =
ID3D12Device_CreateDescriptorHeap(driver->D3D12Device, &heapDesc, IID_ID3D12DescriptorHeap, (void**)&handle);
if (FAILED(result))
{
LogError(driver->D3D12Device, "Failed to create descriptor heap!", result);
DestroyDescriptorHeap(heap);
return nullptr;
}
heap->Handle = handle;
heap->HeapType = type;
heap->MaxDescriptors = count;
heap->Staging = isStaging;
heap->DescriptorSize = ID3D12Device_GetDescriptorHandleIncrementSize(driver->D3D12Device, type);
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(handle, &heap->DescriptorHeapCPUStart);
if (!isStaging)
{
ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(handle, &heap->DescriptorHeapGPUStart);
}
return heap;
return nullptr;
}
void DestroyDescriptorHeap(NonNullPtr<D3D12DescriptorHeap> heap)
auto pool = static_cast<D3D12StagingDescriptorPool*>(Calloc(1, sizeof(D3D12StagingDescriptorPool)));
// First create the heaps
pool->HeapCount = 1;
pool->Heaps = static_cast<D3D12DescriptorHeap**>(Malloc(sizeof(D3D12DescriptorHeap*)));
pool->Heaps[0] = heap;
pool->FreeDescriptorCapacity = kStagingHeapDescriptorExpectedCount;
pool->FreeDescriptorCount = kStagingHeapDescriptorExpectedCount;
pool->FreeDescriptors =
static_cast<D3D12StagingDescriptor*>(Malloc(kStagingHeapDescriptorExpectedCount * sizeof(D3D12StagingDescriptor)));
InitStagingDescriptorPool(heap, pool);
return pool;
}
bool AssignStagingDescriptor(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type, D3D12StagingDescriptor& outDescriptor)
{
// TODO: Make it thread safe
D3D12StagingDescriptor* descriptor = nullptr;
D3D12StagingDescriptorPool* pool = driver->StagingDescriptorPools[type];
if (pool->FreeDescriptorCount == 0)
{
if (heap->Handle)
if (!ExtendStagingDescriptorPool(driver, *pool))
{
ID3D12DescriptorHeap_Release(heap->Handle);
}
Free(heap.Get());
}
D3D12StagingDescriptorPool* CreateStagingDescriptorPool(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type)
{
D3D12DescriptorHeap* heap = CreateDescriptorHeap(driver, type, kStagingHeapDescriptorExpectedCount, true);
if (!heap)
{
return nullptr;
}
auto pool = static_cast<D3D12StagingDescriptorPool*>(Calloc(1, sizeof(D3D12StagingDescriptorPool)));
// First create the heaps
pool->HeapCount = 1;
pool->Heaps = static_cast<D3D12DescriptorHeap**>(Malloc(sizeof(D3D12DescriptorHeap*)));
pool->Heaps[0] = heap;
pool->FreeDescriptorCapacity = kStagingHeapDescriptorExpectedCount;
pool->FreeDescriptorCount = kStagingHeapDescriptorExpectedCount;
pool->FreeDescriptors = static_cast<D3D12StagingDescriptor*>(
Malloc(kStagingHeapDescriptorExpectedCount * sizeof(D3D12StagingDescriptor)));
InitStagingDescriptorPool(heap, pool);
return pool;
}
bool AssignStagingDescriptor(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type, D3D12StagingDescriptor& outDescriptor)
{
// TODO: Make it thread safe
D3D12StagingDescriptor* descriptor = nullptr;
D3D12StagingDescriptorPool* pool = driver->StagingDescriptorPools[type];
if (pool->FreeDescriptorCount == 0)
{
if (!ExtendStagingDescriptorPool(driver, *pool))
{
return false;
}
}
descriptor = &pool->FreeDescriptors[pool->FreeDescriptorCount - 1];
MemCopy(&outDescriptor, descriptor, sizeof(D3D12StagingDescriptor));
pool->FreeDescriptorCount -= 1;
return true;
}
void ReleaseStagingDescriptor(NonNullPtr<D3D12Driver> driver, D3D12StagingDescriptor& cpuDescriptor)
{
D3D12StagingDescriptorPool* pool = cpuDescriptor.Pool;
if (pool != nullptr)
{
MemCopy(&pool->FreeDescriptors[pool->FreeDescriptorCount], &cpuDescriptor, sizeof(D3D12StagingDescriptor));
pool->FreeDescriptorCount += 1;
return false;
}
}
void DestroyStagingDescriptorPool(NonNullPtr<D3D12StagingDescriptorPool> pool)
{
for (uint32 i = 0; i < pool->HeapCount; i += 1)
{
DestroyDescriptorHeap(pool->Heaps[i]);
}
descriptor = &pool->FreeDescriptors[pool->FreeDescriptorCount - 1];
MemCopy(&outDescriptor, descriptor, sizeof(D3D12StagingDescriptor));
pool->FreeDescriptorCount -= 1;
Free(pool->Heaps);
Free(pool->FreeDescriptors);
Free(pool.Get());
return true;
}
void ReleaseStagingDescriptor(NonNullPtr<D3D12Driver> driver, D3D12StagingDescriptor& cpuDescriptor)
{
D3D12StagingDescriptorPool* pool = cpuDescriptor.Pool;
if (pool != nullptr)
{
MemCopy(&pool->FreeDescriptors[pool->FreeDescriptorCount], &cpuDescriptor, sizeof(D3D12StagingDescriptor));
pool->FreeDescriptorCount += 1;
}
} // namespace Internal
} // namespace Juliet::D3D12
}
void DestroyStagingDescriptorPool(NonNullPtr<D3D12StagingDescriptorPool> pool)
{
for (uint32 i = 0; i < pool->HeapCount; i += 1)
{
DestroyDescriptorHeap(pool->Heaps[i]);
}
Free(pool->Heaps);
Free(pool->FreeDescriptors);
Free(pool.Get());
}
} // namespace Juliet::D3D12::Internal

View File

@@ -2,6 +2,7 @@
#include <Core/Common/NonNullPtr.h>
#include <Core/Thread/Mutex.h>
#include <Graphics/D3D12/D3D12DescriptorHeap.h>
#include <Graphics/D3D12/D3D12Includes.h>
// Definitions:
@@ -19,29 +20,9 @@ namespace Juliet::D3D12
struct D3D12Driver;
struct D3D12StagingDescriptor;
// https://learn.microsoft.com/en-us/windows/win32/direct3d12/descriptor-heaps
struct D3D12DescriptorHeap
{
ID3D12DescriptorHeap* Handle;
D3D12_DESCRIPTOR_HEAP_TYPE HeapType;
D3D12_CPU_DESCRIPTOR_HANDLE DescriptorHeapCPUStart;
D3D12_GPU_DESCRIPTOR_HANDLE DescriptorHeapGPUStart; // only used by GPU heaps
uint32 MaxDescriptors;
uint32 DescriptorSize;
uint32 CurrentDescriptorIndex; // only used by GPU heaps
bool Staging : 1;
};
struct D3D12DescriptorHeapPool
{
D3D12DescriptorHeap** Heaps;
size_t Capacity;
size_t Count;
};
struct D3D12StagingDescriptorPool
{
D3D12DescriptorHeap** Heaps;
Internal::D3D12DescriptorHeap** Heaps;
uint32 HeapCount;
// Descriptor handles are owned by resources, so these can be thought of as descriptions of a free index within a heap.
@@ -53,18 +34,14 @@ namespace Juliet::D3D12
// https://learn.microsoft.com/en-us/windows/win32/direct3d12/descriptors-overview
struct D3D12StagingDescriptor
{
D3D12StagingDescriptorPool* Pool;
D3D12DescriptorHeap* Heap;
D3D12StagingDescriptorPool* Pool;
Internal::D3D12DescriptorHeap* Heap;
D3D12_CPU_DESCRIPTOR_HANDLE CpuHandle;
uint32 CpuHandleIndex;
};
namespace Internal
{
extern D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr<D3D12Driver> driver,
D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count, bool isStaging);
extern void DestroyDescriptorHeap(NonNullPtr<D3D12DescriptorHeap> heap);
extern D3D12StagingDescriptorPool* CreateStagingDescriptorPool(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type);
extern bool AssignStagingDescriptor(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type,
D3D12StagingDescriptor& outDescriptor);

View File

@@ -0,0 +1,119 @@
#include <pch.h>
#include <Core/Memory/Allocator.h>
#include <Graphics/D3D12/D3D12DescriptorHeap.h>
#include <Graphics/D3D12/D3D12GraphicsDevice.h>
#include <Graphics/D3D12/D3D12Utils.h>
namespace Juliet::D3D12::Internal
{
D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count, bool isStaging)
{
ID3D12DescriptorHeap* handle;
auto heap = static_cast<D3D12DescriptorHeap*>(Calloc(1, sizeof(D3D12DescriptorHeap)));
if (!heap)
{
return nullptr;
}
heap->CurrentDescriptorIndex = 0;
D3D12_DESCRIPTOR_HEAP_DESC heapDesc;
heapDesc.NumDescriptors = count;
heapDesc.Type = type;
heapDesc.Flags = isStaging ? D3D12_DESCRIPTOR_HEAP_FLAG_NONE : D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
heapDesc.NodeMask = 0;
HRESULT result =
ID3D12Device_CreateDescriptorHeap(driver->D3D12Device, &heapDesc, IID_ID3D12DescriptorHeap, (void**)&handle);
if (FAILED(result))
{
LogError(driver->D3D12Device, "Failed to create descriptor heap!", result);
DestroyDescriptorHeap(heap);
return nullptr;
}
heap->Handle = handle;
heap->HeapType = type;
heap->MaxDescriptors = count;
heap->Staging = isStaging;
heap->DescriptorSize = ID3D12Device_GetDescriptorHandleIncrementSize(driver->D3D12Device, type);
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(handle, &heap->DescriptorHeapCPUStart);
if (!isStaging)
{
ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(handle, &heap->DescriptorHeapGPUStart);
}
return heap;
}
void DestroyDescriptorHeap(NonNullPtr<D3D12DescriptorHeap> heap)
{
if (heap->Handle)
{
ID3D12DescriptorHeap_Release(heap->Handle);
}
Free(heap.Get());
}
D3D12DescriptorHeap* AcquireDescriptorHeapFromPool(NonNullPtr<D3D12Driver> d3d12Driver, D3D12_DESCRIPTOR_HEAP_TYPE type)
{
D3D12DescriptorHeapPool* pool = nullptr;
uint32 count = 0;
if (type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)
{
pool = &d3d12Driver->CRB_SRV_UAV_HeapPool;
count = GPUDriver::kCBV_SRV_UAV_HeapDescriptorCount;
}
else if (type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER)
{
pool = &d3d12Driver->RTV_HeapPool;
count = GPUDriver::kSampler_HeapDescriptorCount;
}
Assert(pool != nullptr);
D3D12DescriptorHeap* result = nullptr;
if (pool->Count > 0)
{
result = pool->Heaps[pool->Count - 1];
pool->Count -= 1;
}
else
{
result = CreateDescriptorHeap(d3d12Driver, type, count, false);
}
return result;
}
void ReturnDescriptorHeapToPool(NonNullPtr<D3D12Driver> d3d12Driver, D3D12DescriptorHeap* heap)
{
if (heap == nullptr)
{
return;
}
D3D12DescriptorHeapPool* pool = nullptr;
if (heap->HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)
{
pool = &d3d12Driver->CRB_SRV_UAV_HeapPool;
}
else if (heap->HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER)
{
pool = &d3d12Driver->RTV_HeapPool;
}
Assert(pool != nullptr);
heap->CurrentDescriptorIndex = 0;
if (pool->Count >= pool->Capacity)
{
pool->Capacity *= 2;
pool->Heaps =
static_cast<D3D12DescriptorHeap**>(Realloc(pool->Heaps, pool->Capacity * sizeof(D3D12DescriptorHeap*)));
}
pool->Heaps[pool->Count] = heap;
pool->Count += 1;
}
} // namespace Juliet::D3D12::Internal

View File

@@ -0,0 +1,41 @@
#pragma once
#include <Core/Common/NonNullPtr.h>
#include <Graphics/D3D12/D3D12Includes.h>
// Forward declare
namespace Juliet::D3D12
{
struct D3D12Driver;
}
namespace Juliet::D3D12::Internal
{
// https://learn.microsoft.com/en-us/windows/win32/direct3d12/descriptor-heaps
struct D3D12DescriptorHeap
{
ID3D12DescriptorHeap* Handle;
D3D12_DESCRIPTOR_HEAP_TYPE HeapType;
D3D12_CPU_DESCRIPTOR_HANDLE DescriptorHeapCPUStart;
D3D12_GPU_DESCRIPTOR_HANDLE DescriptorHeapGPUStart; // only used by GPU heaps
uint32 MaxDescriptors;
uint32 DescriptorSize;
uint32 CurrentDescriptorIndex; // only used by GPU heaps
bool Staging : 1;
};
struct D3D12DescriptorHeapPool
{
D3D12DescriptorHeap** Heaps;
size_t Capacity;
size_t Count;
};
extern D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr<D3D12Driver> driver,
D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count, bool isStaging);
extern void DestroyDescriptorHeap(NonNullPtr<D3D12DescriptorHeap> heap);
extern D3D12DescriptorHeap* AcquireDescriptorHeapFromPool(NonNullPtr<D3D12Driver> commandList,
D3D12_DESCRIPTOR_HEAP_TYPE type);
extern void ReturnDescriptorHeapToPool(NonNullPtr<D3D12Driver> d3d12Driver, D3D12DescriptorHeap* heap);
} // namespace Juliet::D3D12

View File

@@ -4,6 +4,7 @@
#include <Core/HAL/DynLib/DynamicLibrary.h>
#include <Core/Memory/Allocator.h>
#include <Graphics/D3D12/D3D12CommandList.h>
#include <Graphics/D3D12/D3D12DescriptorHeap.h>
#include <Graphics/D3D12/D3D12GraphicsDevice.h>
#include <Graphics/D3D12/D3D12GraphicsPipeline.h>
#include <Graphics/D3D12/D3D12Includes.h>
@@ -471,7 +472,7 @@ namespace Juliet::D3D12
}
}
auto DestroyDescriptorHeapPool = [](D3D12DescriptorHeapPool& heapPool)
auto DestroyDescriptorHeapPool = [](Internal::D3D12DescriptorHeapPool& heapPool)
{
if (heapPool.Heaps)
{
@@ -914,11 +915,12 @@ namespace Juliet::D3D12
}
// Other Descriptor pools
auto CreateDescriptorPool = [&](D3D12DescriptorHeapPool& heapPool, D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count) -> bool
auto CreateDescriptorPool = [&](Internal::D3D12DescriptorHeapPool& heapPool,
D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count) -> bool
{
heapPool.Capacity = 4;
heapPool.Count = 4;
heapPool.Heaps = static_cast<D3D12DescriptorHeap**>(Calloc(heapPool.Capacity, sizeof(D3D12DescriptorHeap*)));
heapPool.Heaps = static_cast<Internal::D3D12DescriptorHeap**>(Calloc(heapPool.Capacity, sizeof(Internal::D3D12DescriptorHeap*)));
for (uint32 i = 0; i < heapPool.Capacity; ++i)
{

View File

@@ -2,6 +2,7 @@
#include <Core/Common/EnumUtils.h>
#include <Graphics/D3D12/D3D12Common.h>
#include <Graphics/D3D12/D3D12DescriptorHeap.h>
#include <Graphics/D3D12/D3D12GraphicsPipeline.h>
#include <Graphics/D3D12/D3D12Texture.h>
#include <Graphics/GraphicsDevice.h>
@@ -13,6 +14,7 @@ namespace Juliet
namespace Juliet::D3D12
{
struct D3D12StagingDescriptorPool;
// Forward Declare
struct D3D12CommandList;
struct D3D12Fence;
@@ -93,9 +95,9 @@ namespace Juliet::D3D12
D3D12GraphicsRootSignature* BindlessRootSignature;
D3D12StagingDescriptorPool* StagingDescriptorPools[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES];
D3D12DescriptorHeapPool CRB_SRV_UAV_HeapPool;
D3D12DescriptorHeapPool RTV_HeapPool;
D3D12StagingDescriptorPool* StagingDescriptorPools[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES];
Internal::D3D12DescriptorHeapPool CRB_SRV_UAV_HeapPool;
Internal::D3D12DescriptorHeapPool RTV_HeapPool;
String Semantic;