Move heap descriptor into its own file and prepare for the removing of the staging descriptor
This commit is contained in:
@@ -187,6 +187,7 @@
|
|||||||
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_state_object.h" />
|
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_state_object.h" />
|
||||||
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\dxgiformat.h" />
|
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\dxgiformat.h" />
|
||||||
<ClInclude Include="src\Graphics\D3D12\D3D12Common.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\D3D12GraphicsPipeline.h" />
|
||||||
<ClInclude Include="src\Graphics\D3D12\D3D12RenderPass.h"/>
|
<ClInclude Include="src\Graphics\D3D12\D3D12RenderPass.h"/>
|
||||||
<ClInclude Include="src\Graphics\D3D12\D3D12Shader.h"/>
|
<ClInclude Include="src\Graphics\D3D12\D3D12Shader.h"/>
|
||||||
@@ -231,6 +232,7 @@
|
|||||||
<ClCompile Include="src\Engine\Engine.cpp" />
|
<ClCompile Include="src\Engine\Engine.cpp" />
|
||||||
<ClCompile Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_property_format_table.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\D3D12Common.cpp" />
|
||||||
|
<ClCompile Include="src\Graphics\D3D12\D3D12DescriptorHeap.cpp" />
|
||||||
<ClCompile Include="src\Graphics\D3D12\D3D12GraphicsPipeline.cpp" />
|
<ClCompile Include="src\Graphics\D3D12\D3D12GraphicsPipeline.cpp" />
|
||||||
<ClCompile Include="src\Graphics\D3D12\D3D12RenderPass.cpp" />
|
<ClCompile Include="src\Graphics\D3D12\D3D12RenderPass.cpp" />
|
||||||
<ClCompile Include="src\Graphics\D3D12\D3D12Shader.cpp" />
|
<ClCompile Include="src\Graphics\D3D12\D3D12Shader.cpp" />
|
||||||
|
|||||||
@@ -368,79 +368,14 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
namespace Internal
|
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)
|
void SetDescriptorHeaps(NonNullPtr<D3D12CommandList> commandList)
|
||||||
{
|
{
|
||||||
ID3D12DescriptorHeap* heaps[2];
|
ID3D12DescriptorHeap* heaps[2];
|
||||||
D3D12DescriptorHeap* viewHeap = nullptr;
|
D3D12DescriptorHeap* viewHeap = nullptr;
|
||||||
D3D12DescriptorHeap* samplerHeap = nullptr;
|
D3D12DescriptorHeap* samplerHeap = nullptr;
|
||||||
|
|
||||||
viewHeap = AcquireDescriptorHeapFromPool(commandList, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
viewHeap = AcquireDescriptorHeapFromPool(commandList->Driver, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||||
samplerHeap = AcquireDescriptorHeapFromPool(commandList, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
|
samplerHeap = AcquireDescriptorHeapFromPool(commandList->Driver, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
|
||||||
|
|
||||||
commandList->CRB_SRV_UAV_Heap = viewHeap;
|
commandList->CRB_SRV_UAV_Heap = viewHeap;
|
||||||
commandList->RTV_Heap = samplerHeap;
|
commandList->RTV_Heap = samplerHeap;
|
||||||
|
|||||||
@@ -75,8 +75,8 @@ namespace Juliet::D3D12
|
|||||||
// D3D12UniformBuffer *vertexUniformBuffers[GPUDriver::kMaxUniformBuffersPerStage];
|
// D3D12UniformBuffer *vertexUniformBuffers[GPUDriver::kMaxUniformBuffersPerStage];
|
||||||
// D3D12UniformBuffer *fragmentUniformBuffers[GPUDriver::kMaxUniformBuffersPerStage];
|
// D3D12UniformBuffer *fragmentUniformBuffers[GPUDriver::kMaxUniformBuffersPerStage];
|
||||||
|
|
||||||
D3D12DescriptorHeap* CRB_SRV_UAV_Heap;
|
Internal::D3D12DescriptorHeap* CRB_SRV_UAV_Heap;
|
||||||
D3D12DescriptorHeap* RTV_Heap;
|
Internal::D3D12DescriptorHeap* RTV_Heap;
|
||||||
|
|
||||||
// Resource Tracking
|
// Resource Tracking
|
||||||
D3D12Texture** UsedTextures;
|
D3D12Texture** UsedTextures;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include <Graphics/D3D12/D3D12Includes.h>
|
#include <Graphics/D3D12/D3D12Includes.h>
|
||||||
#include <Graphics/D3D12/D3D12Utils.h>
|
#include <Graphics/D3D12/D3D12Utils.h>
|
||||||
|
|
||||||
namespace Juliet::D3D12
|
namespace Juliet::D3D12::Internal
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -49,126 +49,72 @@ namespace Juliet::D3D12
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace Internal
|
D3D12StagingDescriptorPool* CreateStagingDescriptorPool(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type)
|
||||||
{
|
{
|
||||||
D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type,
|
D3D12DescriptorHeap* heap = CreateDescriptorHeap(driver, type, kStagingHeapDescriptorExpectedCount, true);
|
||||||
uint32 count, bool isStaging)
|
if (!heap)
|
||||||
{
|
{
|
||||||
ID3D12DescriptorHeap* handle;
|
return nullptr;
|
||||||
|
|
||||||
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)
|
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);
|
return false;
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DestroyStagingDescriptorPool(NonNullPtr<D3D12StagingDescriptorPool> pool)
|
descriptor = &pool->FreeDescriptors[pool->FreeDescriptorCount - 1];
|
||||||
{
|
MemCopy(&outDescriptor, descriptor, sizeof(D3D12StagingDescriptor));
|
||||||
for (uint32 i = 0; i < pool->HeapCount; i += 1)
|
pool->FreeDescriptorCount -= 1;
|
||||||
{
|
|
||||||
DestroyDescriptorHeap(pool->Heaps[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Free(pool->Heaps);
|
return true;
|
||||||
Free(pool->FreeDescriptors);
|
}
|
||||||
Free(pool.Get());
|
|
||||||
|
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
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <Core/Common/NonNullPtr.h>
|
#include <Core/Common/NonNullPtr.h>
|
||||||
#include <Core/Thread/Mutex.h>
|
#include <Core/Thread/Mutex.h>
|
||||||
|
#include <Graphics/D3D12/D3D12DescriptorHeap.h>
|
||||||
#include <Graphics/D3D12/D3D12Includes.h>
|
#include <Graphics/D3D12/D3D12Includes.h>
|
||||||
|
|
||||||
// Definitions:
|
// Definitions:
|
||||||
@@ -19,29 +20,9 @@ namespace Juliet::D3D12
|
|||||||
struct D3D12Driver;
|
struct D3D12Driver;
|
||||||
struct D3D12StagingDescriptor;
|
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
|
struct D3D12StagingDescriptorPool
|
||||||
{
|
{
|
||||||
D3D12DescriptorHeap** Heaps;
|
Internal::D3D12DescriptorHeap** Heaps;
|
||||||
uint32 HeapCount;
|
uint32 HeapCount;
|
||||||
|
|
||||||
// Descriptor handles are owned by resources, so these can be thought of as descriptions of a free index within a heap.
|
// 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
|
// https://learn.microsoft.com/en-us/windows/win32/direct3d12/descriptors-overview
|
||||||
struct D3D12StagingDescriptor
|
struct D3D12StagingDescriptor
|
||||||
{
|
{
|
||||||
D3D12StagingDescriptorPool* Pool;
|
D3D12StagingDescriptorPool* Pool;
|
||||||
D3D12DescriptorHeap* Heap;
|
Internal::D3D12DescriptorHeap* Heap;
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE CpuHandle;
|
D3D12_CPU_DESCRIPTOR_HANDLE CpuHandle;
|
||||||
uint32 CpuHandleIndex;
|
uint32 CpuHandleIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Internal
|
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 D3D12StagingDescriptorPool* CreateStagingDescriptorPool(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type);
|
||||||
extern bool AssignStagingDescriptor(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type,
|
extern bool AssignStagingDescriptor(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type,
|
||||||
D3D12StagingDescriptor& outDescriptor);
|
D3D12StagingDescriptor& outDescriptor);
|
||||||
|
|||||||
119
Juliet/src/Graphics/D3D12/D3D12DescriptorHeap.cpp
Normal file
119
Juliet/src/Graphics/D3D12/D3D12DescriptorHeap.cpp
Normal 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
|
||||||
41
Juliet/src/Graphics/D3D12/D3D12DescriptorHeap.h
Normal file
41
Juliet/src/Graphics/D3D12/D3D12DescriptorHeap.h
Normal 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
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <Core/HAL/DynLib/DynamicLibrary.h>
|
#include <Core/HAL/DynLib/DynamicLibrary.h>
|
||||||
#include <Core/Memory/Allocator.h>
|
#include <Core/Memory/Allocator.h>
|
||||||
#include <Graphics/D3D12/D3D12CommandList.h>
|
#include <Graphics/D3D12/D3D12CommandList.h>
|
||||||
|
#include <Graphics/D3D12/D3D12DescriptorHeap.h>
|
||||||
#include <Graphics/D3D12/D3D12GraphicsDevice.h>
|
#include <Graphics/D3D12/D3D12GraphicsDevice.h>
|
||||||
#include <Graphics/D3D12/D3D12GraphicsPipeline.h>
|
#include <Graphics/D3D12/D3D12GraphicsPipeline.h>
|
||||||
#include <Graphics/D3D12/D3D12Includes.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)
|
if (heapPool.Heaps)
|
||||||
{
|
{
|
||||||
@@ -914,11 +915,12 @@ namespace Juliet::D3D12
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Other Descriptor pools
|
// 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.Capacity = 4;
|
||||||
heapPool.Count = 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)
|
for (uint32 i = 0; i < heapPool.Capacity; ++i)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <Core/Common/EnumUtils.h>
|
#include <Core/Common/EnumUtils.h>
|
||||||
#include <Graphics/D3D12/D3D12Common.h>
|
#include <Graphics/D3D12/D3D12Common.h>
|
||||||
|
#include <Graphics/D3D12/D3D12DescriptorHeap.h>
|
||||||
#include <Graphics/D3D12/D3D12GraphicsPipeline.h>
|
#include <Graphics/D3D12/D3D12GraphicsPipeline.h>
|
||||||
#include <Graphics/D3D12/D3D12Texture.h>
|
#include <Graphics/D3D12/D3D12Texture.h>
|
||||||
#include <Graphics/GraphicsDevice.h>
|
#include <Graphics/GraphicsDevice.h>
|
||||||
@@ -13,6 +14,7 @@ namespace Juliet
|
|||||||
|
|
||||||
namespace Juliet::D3D12
|
namespace Juliet::D3D12
|
||||||
{
|
{
|
||||||
|
struct D3D12StagingDescriptorPool;
|
||||||
// Forward Declare
|
// Forward Declare
|
||||||
struct D3D12CommandList;
|
struct D3D12CommandList;
|
||||||
struct D3D12Fence;
|
struct D3D12Fence;
|
||||||
@@ -93,9 +95,9 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
D3D12GraphicsRootSignature* BindlessRootSignature;
|
D3D12GraphicsRootSignature* BindlessRootSignature;
|
||||||
|
|
||||||
D3D12StagingDescriptorPool* StagingDescriptorPools[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES];
|
D3D12StagingDescriptorPool* StagingDescriptorPools[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES];
|
||||||
D3D12DescriptorHeapPool CRB_SRV_UAV_HeapPool;
|
Internal::D3D12DescriptorHeapPool CRB_SRV_UAV_HeapPool;
|
||||||
D3D12DescriptorHeapPool RTV_HeapPool;
|
Internal::D3D12DescriptorHeapPool RTV_HeapPool;
|
||||||
|
|
||||||
String Semantic;
|
String Semantic;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user