Bindless resource first step
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
#include <D3D12CommandList.h>
|
||||||
#include <pch.h>
|
#include <pch.h>
|
||||||
|
|
||||||
#include <Core/Memory/Allocator.h>
|
#include <Core/Memory/Allocator.h>
|
||||||
@@ -367,6 +368,89 @@ 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)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
commandList->CRB_SRV_UAV_Heap = viewHeap;
|
||||||
|
commandList->RTV_Heap = samplerHeap;
|
||||||
|
|
||||||
|
heaps[0] = viewHeap->Handle;
|
||||||
|
heaps[1] = samplerHeap->Handle;
|
||||||
|
|
||||||
|
ID3D12GraphicsCommandList_SetDescriptorHeaps(commandList->GraphicsCommandList.CommandList, 2, heaps);
|
||||||
|
}
|
||||||
|
|
||||||
void DestroyCommandList(NonNullPtr<D3D12CommandList> commandList)
|
void DestroyCommandList(NonNullPtr<D3D12CommandList> commandList)
|
||||||
{
|
{
|
||||||
// TODO : Handle other kind of command list (copy compute)
|
// TODO : Handle other kind of command list (copy compute)
|
||||||
@@ -403,6 +487,12 @@ namespace Juliet::D3D12
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return heap descriptor to pool
|
||||||
|
ReturnDescriptorHeapToPool(driver, commandList->CRB_SRV_UAV_Heap);
|
||||||
|
ReturnDescriptorHeapToPool(driver, commandList->RTV_Heap);
|
||||||
|
commandList->CRB_SRV_UAV_Heap = nullptr;
|
||||||
|
commandList->RTV_Heap = nullptr;
|
||||||
|
|
||||||
// Clean up resource tracking
|
// Clean up resource tracking
|
||||||
for (uint32 idx = 0; idx < commandList->UsedTextureCount; ++idx)
|
for (uint32 idx = 0; idx < commandList->UsedTextureCount; ++idx)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <Core/Common/NonNullPtr.h>
|
#include <Core/Common/NonNullPtr.h>
|
||||||
#include <Core/Math/Shape.h>
|
#include <Core/Math/Shape.h>
|
||||||
|
#include <D3D12Common.h>
|
||||||
#include <D3D12GraphicsPipeline.h>
|
#include <D3D12GraphicsPipeline.h>
|
||||||
#include <Graphics/D3D12/D3D12Includes.h>
|
#include <Graphics/D3D12/D3D12Includes.h>
|
||||||
#include <Graphics/GraphicsDevice.h>
|
#include <Graphics/GraphicsDevice.h>
|
||||||
@@ -74,6 +75,9 @@ namespace Juliet::D3D12
|
|||||||
// D3D12UniformBuffer *vertexUniformBuffers[GPUDriver::kMaxUniformBuffersPerStage];
|
// D3D12UniformBuffer *vertexUniformBuffers[GPUDriver::kMaxUniformBuffersPerStage];
|
||||||
// D3D12UniformBuffer *fragmentUniformBuffers[GPUDriver::kMaxUniformBuffersPerStage];
|
// D3D12UniformBuffer *fragmentUniformBuffers[GPUDriver::kMaxUniformBuffersPerStage];
|
||||||
|
|
||||||
|
D3D12DescriptorHeap* CRB_SRV_UAV_Heap;
|
||||||
|
D3D12DescriptorHeap* RTV_Heap;
|
||||||
|
|
||||||
// Resource Tracking
|
// Resource Tracking
|
||||||
D3D12Texture** UsedTextures;
|
D3D12Texture** UsedTextures;
|
||||||
uint32 UsedTextureCount;
|
uint32 UsedTextureCount;
|
||||||
@@ -93,6 +97,8 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
namespace Internal
|
namespace Internal
|
||||||
{
|
{
|
||||||
|
extern void SetDescriptorHeaps(NonNullPtr<D3D12CommandList> commandList);
|
||||||
|
|
||||||
extern void DestroyCommandList(NonNullPtr<D3D12CommandList> commandList);
|
extern void DestroyCommandList(NonNullPtr<D3D12CommandList> commandList);
|
||||||
extern bool CleanCommandList(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12CommandList> commandList, bool cancel);
|
extern bool CleanCommandList(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12CommandList> commandList, bool cancel);
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,13 @@ namespace Juliet::D3D12
|
|||||||
bool Staging : 1;
|
bool Staging : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct D3D12DescriptorHeapPool
|
||||||
|
{
|
||||||
|
D3D12DescriptorHeap** Heaps;
|
||||||
|
size_t Capacity;
|
||||||
|
size_t Count;
|
||||||
|
};
|
||||||
|
|
||||||
struct D3D12StagingDescriptorPool
|
struct D3D12StagingDescriptorPool
|
||||||
{
|
{
|
||||||
D3D12DescriptorHeap** Heaps;
|
D3D12DescriptorHeap** Heaps;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#define D3D12_DLL "d3d12.dll"
|
#define D3D12_DLL "d3d12.dll"
|
||||||
#define D3D12_CREATEDEVICE_FUNC "D3D12CreateDevice"
|
#define D3D12_CREATEDEVICE_FUNC "D3D12CreateDevice"
|
||||||
#define D3D12_SERIALIZE_ROOT_SIGNATURE_FUNC "D3D12SerializeRootSignature"
|
#define D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE_FUNC "D3D12SerializeVersionedRootSignature"
|
||||||
#define DXGIDEBUG_DLL "dxgidebug.dll"
|
#define DXGIDEBUG_DLL "dxgidebug.dll"
|
||||||
#define DXGI_GET_DEBUG_INTERFACE_FUNC "DXGIGetDebugInterface"
|
#define DXGI_GET_DEBUG_INTERFACE_FUNC "DXGIGetDebugInterface"
|
||||||
#define D3D12_GET_DEBUG_INTERFACE_FUNC "D3D12GetDebugInterface"
|
#define D3D12_GET_DEBUG_INTERFACE_FUNC "D3D12GetDebugInterface"
|
||||||
@@ -196,6 +196,127 @@ namespace Juliet::D3D12
|
|||||||
return driverIsValid;
|
return driverIsValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DestroyGraphicsRootSignature(D3D12GraphicsRootSignature* rootSignature)
|
||||||
|
{
|
||||||
|
if (!rootSignature)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (rootSignature->Handle)
|
||||||
|
{
|
||||||
|
ID3D12RootSignature_Release(rootSignature->Handle);
|
||||||
|
}
|
||||||
|
Free(rootSignature);
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12GraphicsRootSignature* CreateGraphicsRootSignature(NonNullPtr<D3D12Driver> d3d12Driver)
|
||||||
|
{
|
||||||
|
auto d3d12GraphicsRootSignature =
|
||||||
|
static_cast<D3D12GraphicsRootSignature*>(Calloc(1, sizeof(D3D12GraphicsRootSignature)));
|
||||||
|
if (!d3d12GraphicsRootSignature)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12_ROOT_PARAMETER1 parameters[ToUnderlying(RootParameters::Count)] = {};
|
||||||
|
parameters[ToUnderlying(RootParameters::Constants32Bits)] = {
|
||||||
|
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS,
|
||||||
|
.Constants = {
|
||||||
|
.ShaderRegister = 0,
|
||||||
|
.RegisterSpace = 0,
|
||||||
|
.Num32BitValues = 58, // 58 because each root cbv takes 2 uints, and the max is 64
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
parameters[ToUnderlying(RootParameters::PassCBV)] = {
|
||||||
|
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV,
|
||||||
|
.Descriptor = {
|
||||||
|
.ShaderRegister = 1,
|
||||||
|
.Flags = D3D12_ROOT_DESCRIPTOR_FLAG_DATA_VOLATILE,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
parameters[ToUnderlying(RootParameters::ViewCBV)] = {
|
||||||
|
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV,
|
||||||
|
.Descriptor = {
|
||||||
|
.ShaderRegister = 2,
|
||||||
|
.Flags = D3D12_ROOT_DESCRIPTOR_FLAG_DATA_VOLATILE,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
parameters[ToUnderlying(RootParameters::GlobalCBV)] = {
|
||||||
|
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV,
|
||||||
|
.Descriptor = {
|
||||||
|
.ShaderRegister = 3,
|
||||||
|
.Flags = D3D12_ROOT_DESCRIPTOR_FLAG_DATA_VOLATILE,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
D3D12_STATIC_SAMPLER_DESC samplers[] = {
|
||||||
|
{
|
||||||
|
// s_nearest
|
||||||
|
.Filter = D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR,
|
||||||
|
.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
|
||||||
|
.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
|
||||||
|
.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
|
||||||
|
.MipLODBias = 0.0f,
|
||||||
|
.MinLOD = 0.0f,
|
||||||
|
.MaxLOD = D3D12_FLOAT32_MAX,
|
||||||
|
.ShaderRegister = 0,
|
||||||
|
.RegisterSpace = 0,
|
||||||
|
.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
D3D12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc = {
|
||||||
|
.Version = D3D_ROOT_SIGNATURE_VERSION_1_1,
|
||||||
|
.Desc_1_1 = {
|
||||||
|
.NumParameters = ArraySize(parameters),
|
||||||
|
.pParameters = parameters,
|
||||||
|
.NumStaticSamplers = ArraySize(samplers),
|
||||||
|
.pStaticSamplers = samplers,
|
||||||
|
.Flags = D3D12_ROOT_SIGNATURE_FLAG_CBV_SRV_UAV_HEAP_DIRECTLY_INDEXED,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Serialize the root signature
|
||||||
|
ID3DBlob* serializedRootSignature;
|
||||||
|
ID3DBlob* errorBlob;
|
||||||
|
HRESULT res =
|
||||||
|
d3d12Driver->D3D12SerializeVersionedRootSignatureFct(&rootSignatureDesc, &serializedRootSignature, &errorBlob);
|
||||||
|
if (FAILED(res))
|
||||||
|
{
|
||||||
|
if (errorBlob)
|
||||||
|
{
|
||||||
|
auto errorBuffer = ID3D10Blob_GetBufferPointer(errorBlob);
|
||||||
|
LogError(LogCategory::Graphics, "Failed to serialize RootSignature: %s", errorBuffer);
|
||||||
|
ID3D10Blob_Release(errorBlob);
|
||||||
|
}
|
||||||
|
DestroyGraphicsRootSignature(d3d12GraphicsRootSignature);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the root signature
|
||||||
|
ID3D12RootSignature* rootSignature;
|
||||||
|
res = ID3D12Device_CreateRootSignature(d3d12Driver->D3D12Device, 0, ID3D10Blob_GetBufferPointer(serializedRootSignature),
|
||||||
|
ID3D10Blob_GetBufferSize(serializedRootSignature),
|
||||||
|
IID_ID3D12RootSignature, reinterpret_cast<void**>(&rootSignature));
|
||||||
|
if (FAILED(res))
|
||||||
|
{
|
||||||
|
if (errorBlob)
|
||||||
|
{
|
||||||
|
LogError(LogCategory::Graphics, "Failed to create RootSignature: %s",
|
||||||
|
(const char*)ID3D10Blob_GetBufferPointer(errorBlob));
|
||||||
|
ID3D10Blob_Release(errorBlob);
|
||||||
|
}
|
||||||
|
DestroyGraphicsRootSignature(d3d12GraphicsRootSignature);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
d3d12GraphicsRootSignature->Handle = rootSignature;
|
||||||
|
return d3d12GraphicsRootSignature;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef IDXGIINFOQUEUE_SUPPORTED
|
#ifdef IDXGIINFOQUEUE_SUPPORTED
|
||||||
void InitializeDXGIDebug(NonNullPtr<D3D12Driver> driver)
|
void InitializeDXGIDebug(NonNullPtr<D3D12Driver> driver)
|
||||||
{
|
{
|
||||||
@@ -355,7 +476,7 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
void DestroyDriver_Internal(NonNullPtr<D3D12Driver> driver)
|
void DestroyDriver_Internal(NonNullPtr<D3D12Driver> driver)
|
||||||
{
|
{
|
||||||
// Destroy pools
|
// Destroy Descriptor pools
|
||||||
for (uint32 i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; i += 1)
|
for (uint32 i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; i += 1)
|
||||||
{
|
{
|
||||||
if (driver->StagingDescriptorPools[i])
|
if (driver->StagingDescriptorPools[i])
|
||||||
@@ -365,6 +486,24 @@ namespace Juliet::D3D12
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto DestroyDescriptorHeapPool = [](D3D12DescriptorHeapPool& heapPool)
|
||||||
|
{
|
||||||
|
if (heapPool.Heaps)
|
||||||
|
{
|
||||||
|
for (uint32 i = 0; i < heapPool.Count; ++i)
|
||||||
|
{
|
||||||
|
if (heapPool.Heaps[i])
|
||||||
|
{
|
||||||
|
Internal::DestroyDescriptorHeap(heapPool.Heaps[i]);
|
||||||
|
heapPool.Heaps[i] = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SafeFree(heapPool.Heaps);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
DestroyDescriptorHeapPool(driver->CRB_SRV_UAV_HeapPool);
|
||||||
|
DestroyDescriptorHeapPool(driver->RTV_HeapPool);
|
||||||
|
|
||||||
// Release command buffers
|
// Release command buffers
|
||||||
for (uint32 i = 0; i < driver->AvailableCommandListCount; i += 1)
|
for (uint32 i = 0; i < driver->AvailableCommandListCount; i += 1)
|
||||||
{
|
{
|
||||||
@@ -385,6 +524,8 @@ namespace Juliet::D3D12
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DestroyGraphicsRootSignature(driver->BindlessRootSignature);
|
||||||
|
|
||||||
// Clean allocations
|
// Clean allocations
|
||||||
SafeFree(driver->AvailableCommandLists);
|
SafeFree(driver->AvailableCommandLists);
|
||||||
SafeFree(driver->SubmittedCommandLists);
|
SafeFree(driver->SubmittedCommandLists);
|
||||||
@@ -440,7 +581,7 @@ namespace Juliet::D3D12
|
|||||||
driver->D3D12DLL = nullptr;
|
driver->D3D12DLL = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
driver->D3D12SerializeRootSignatureFct = nullptr;
|
driver->D3D12SerializeVersionedRootSignatureFct = nullptr;
|
||||||
|
|
||||||
Free(driver.Get());
|
Free(driver.Get());
|
||||||
}
|
}
|
||||||
@@ -624,12 +765,12 @@ namespace Juliet::D3D12
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
driver->D3D12SerializeRootSignatureFct = reinterpret_cast<PFN_D3D12_SERIALIZE_ROOT_SIGNATURE>(
|
driver->D3D12SerializeVersionedRootSignatureFct = reinterpret_cast<PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE>(
|
||||||
LoadFunction(driver->D3D12DLL, D3D12_SERIALIZE_ROOT_SIGNATURE_FUNC));
|
LoadFunction(driver->D3D12DLL, D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE_FUNC));
|
||||||
if (driver->D3D12SerializeRootSignatureFct == nullptr)
|
if (driver->D3D12SerializeVersionedRootSignatureFct == nullptr)
|
||||||
{
|
{
|
||||||
Log(LogLevel::Error, LogCategory::Graphics,
|
Log(LogLevel::Error, LogCategory::Graphics,
|
||||||
"DX12: Couldn't Load function " D3D12_SERIALIZE_ROOT_SIGNATURE_FUNC " in " D3D12_DLL);
|
"DX12: Couldn't Load function " D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE_FUNC " in " D3D12_DLL);
|
||||||
DestroyDriver_Internal(driver);
|
DestroyDriver_Internal(driver);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -687,6 +828,9 @@ namespace Juliet::D3D12
|
|||||||
driver->GPUUploadHeapSupported = options16.GPUUploadHeapSupported;
|
driver->GPUUploadHeapSupported = options16.GPUUploadHeapSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create bindless root signature
|
||||||
|
driver->BindlessRootSignature = CreateGraphicsRootSignature(driver);
|
||||||
|
|
||||||
// Command Queues
|
// Command Queues
|
||||||
// Graphics Queue only for now
|
// Graphics Queue only for now
|
||||||
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
||||||
@@ -784,6 +928,38 @@ namespace Juliet::D3D12
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Other Descriptor pools
|
||||||
|
auto CreateDescriptorPool = [&](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*)));
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < heapPool.Capacity; ++i)
|
||||||
|
{
|
||||||
|
heapPool.Heaps[i] = Internal::CreateDescriptorHeap(driver, type, count, false);
|
||||||
|
|
||||||
|
if (heapPool.Heaps[i] == nullptr)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!CreateDescriptorPool(driver->CRB_SRV_UAV_HeapPool, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
|
||||||
|
GPUDriver::kCBV_SRV_UAV_HeapDescriptorCount))
|
||||||
|
{
|
||||||
|
DestroyDriver_Internal(driver);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CreateDescriptorPool(driver->RTV_HeapPool, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GPUDriver::kSampler_HeapDescriptorCount))
|
||||||
|
{
|
||||||
|
DestroyDriver_Internal(driver);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Deferred dispose vectors
|
// Deferred dispose vectors
|
||||||
driver->GraphicsPipelinesToDisposeCapacity = 4;
|
driver->GraphicsPipelinesToDisposeCapacity = 4;
|
||||||
driver->GraphicsPipelinesToDisposeCount = 0;
|
driver->GraphicsPipelinesToDisposeCount = 0;
|
||||||
|
|||||||
@@ -17,6 +17,15 @@ namespace Juliet::D3D12
|
|||||||
struct D3D12CommandList;
|
struct D3D12CommandList;
|
||||||
struct D3D12Fence;
|
struct D3D12Fence;
|
||||||
|
|
||||||
|
enum class RootParameters : uint8
|
||||||
|
{
|
||||||
|
Constants32Bits,
|
||||||
|
PassCBV,
|
||||||
|
ViewCBV,
|
||||||
|
GlobalCBV,
|
||||||
|
Count,
|
||||||
|
};
|
||||||
|
|
||||||
struct D3D12WindowData
|
struct D3D12WindowData
|
||||||
{
|
{
|
||||||
Window* Window;
|
Window* Window;
|
||||||
@@ -43,7 +52,7 @@ namespace Juliet::D3D12
|
|||||||
// D3D12
|
// D3D12
|
||||||
DynamicLibrary* D3D12DLL;
|
DynamicLibrary* D3D12DLL;
|
||||||
ID3D12Device5* D3D12Device;
|
ID3D12Device5* D3D12Device;
|
||||||
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignatureFct;
|
PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE D3D12SerializeVersionedRootSignatureFct;
|
||||||
ID3D12CommandQueue* GraphicsQueue;
|
ID3D12CommandQueue* GraphicsQueue;
|
||||||
D3D12_COMMAND_QUEUE_DESC QueueDesc[ToUnderlying(QueueType::Copy)];
|
D3D12_COMMAND_QUEUE_DESC QueueDesc[ToUnderlying(QueueType::Copy)];
|
||||||
#ifdef JULIET_DEBUG
|
#ifdef JULIET_DEBUG
|
||||||
@@ -85,7 +94,11 @@ namespace Juliet::D3D12
|
|||||||
uint32 GraphicsPipelinesToDisposeCount;
|
uint32 GraphicsPipelinesToDisposeCount;
|
||||||
uint32 GraphicsPipelinesToDisposeCapacity;
|
uint32 GraphicsPipelinesToDisposeCapacity;
|
||||||
|
|
||||||
|
D3D12GraphicsRootSignature* BindlessRootSignature;
|
||||||
|
|
||||||
D3D12StagingDescriptorPool* StagingDescriptorPools[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES];
|
D3D12StagingDescriptorPool* StagingDescriptorPools[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES];
|
||||||
|
D3D12DescriptorHeapPool CRB_SRV_UAV_HeapPool;
|
||||||
|
D3D12DescriptorHeapPool RTV_HeapPool;
|
||||||
|
|
||||||
String Semantic;
|
String Semantic;
|
||||||
|
|
||||||
|
|||||||
@@ -319,284 +319,6 @@ namespace Juliet::D3D12
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DestroyGraphicsRootSignature(NonNullPtr<D3D12GraphicsRootSignature> rootSignature);
|
|
||||||
|
|
||||||
constexpr size_t kMaxRootSignatureParameters = 64;
|
|
||||||
D3D12GraphicsRootSignature* CreateGraphicsRootSignature(NonNullPtr<D3D12Driver> d3d12Driver,
|
|
||||||
NonNullPtr<D3D12Shader> vertexShader,
|
|
||||||
NonNullPtr<D3D12Shader> fragmentShader)
|
|
||||||
{
|
|
||||||
// TODO: Investigate bindless resources
|
|
||||||
D3D12_ROOT_PARAMETER rootParameters[kMaxRootSignatureParameters];
|
|
||||||
D3D12_DESCRIPTOR_RANGE descriptorRanges[kMaxRootSignatureParameters];
|
|
||||||
ZeroArray(rootParameters);
|
|
||||||
ZeroArray(descriptorRanges);
|
|
||||||
|
|
||||||
uint32 parameterCount = 0;
|
|
||||||
uint32 rangeCount = 0;
|
|
||||||
D3D12_DESCRIPTOR_RANGE descriptorRange = {};
|
|
||||||
D3D12_ROOT_PARAMETER rootParameter = {};
|
|
||||||
auto d3d12GraphicsRootSignature =
|
|
||||||
static_cast<D3D12GraphicsRootSignature*>(Calloc(1, sizeof(D3D12GraphicsRootSignature)));
|
|
||||||
if (!d3d12GraphicsRootSignature)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
d3d12GraphicsRootSignature->VertexSamplerRootIndex = -1;
|
|
||||||
d3d12GraphicsRootSignature->VertexSamplerTextureRootIndex = -1;
|
|
||||||
d3d12GraphicsRootSignature->VertexStorageTextureRootIndex = -1;
|
|
||||||
d3d12GraphicsRootSignature->VertexStorageBufferRootIndex = -1;
|
|
||||||
|
|
||||||
d3d12GraphicsRootSignature->FragmentSamplerRootIndex = -1;
|
|
||||||
d3d12GraphicsRootSignature->FragmentSamplerTextureRootIndex = -1;
|
|
||||||
d3d12GraphicsRootSignature->FragmentStorageTextureRootIndex = -1;
|
|
||||||
d3d12GraphicsRootSignature->FragmentStorageBufferRootIndex = -1;
|
|
||||||
|
|
||||||
for (uint32 i = 0; i < GPUDriver::kMaxUniformBuffersPerStage; ++i)
|
|
||||||
{
|
|
||||||
d3d12GraphicsRootSignature->VertexUniformBufferRootIndex[i] = -1;
|
|
||||||
d3d12GraphicsRootSignature->FragmentUniformBufferRootIndex[i] = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vertexShader->NumSamplers > 0)
|
|
||||||
{
|
|
||||||
// Vertex Samplers
|
|
||||||
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
|
|
||||||
descriptorRange.NumDescriptors = vertexShader->NumSamplers;
|
|
||||||
descriptorRange.BaseShaderRegister = 0;
|
|
||||||
descriptorRange.RegisterSpace = 0;
|
|
||||||
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
|
|
||||||
descriptorRanges[rangeCount] = descriptorRange;
|
|
||||||
|
|
||||||
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
|
||||||
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
|
|
||||||
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
|
|
||||||
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
|
|
||||||
rootParameters[parameterCount] = rootParameter;
|
|
||||||
d3d12GraphicsRootSignature->VertexSamplerRootIndex = parameterCount;
|
|
||||||
rangeCount += 1;
|
|
||||||
parameterCount += 1;
|
|
||||||
|
|
||||||
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
|
|
||||||
descriptorRange.NumDescriptors = vertexShader->NumSamplers;
|
|
||||||
descriptorRange.BaseShaderRegister = 0;
|
|
||||||
descriptorRange.RegisterSpace = 0;
|
|
||||||
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
|
|
||||||
descriptorRanges[rangeCount] = descriptorRange;
|
|
||||||
|
|
||||||
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
|
||||||
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
|
|
||||||
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
|
|
||||||
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
|
|
||||||
rootParameters[parameterCount] = rootParameter;
|
|
||||||
d3d12GraphicsRootSignature->VertexSamplerTextureRootIndex = parameterCount;
|
|
||||||
rangeCount += 1;
|
|
||||||
parameterCount += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vertexShader->NumStorageTextures)
|
|
||||||
{
|
|
||||||
// Vertex storage textures
|
|
||||||
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
|
|
||||||
descriptorRange.NumDescriptors = vertexShader->NumStorageTextures;
|
|
||||||
descriptorRange.BaseShaderRegister = vertexShader->NumSamplers;
|
|
||||||
descriptorRange.RegisterSpace = 0;
|
|
||||||
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
|
|
||||||
descriptorRanges[rangeCount] = descriptorRange;
|
|
||||||
|
|
||||||
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
|
||||||
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
|
|
||||||
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
|
|
||||||
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
|
|
||||||
rootParameters[parameterCount] = rootParameter;
|
|
||||||
d3d12GraphicsRootSignature->VertexStorageTextureRootIndex = parameterCount;
|
|
||||||
rangeCount += 1;
|
|
||||||
parameterCount += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vertexShader->NumStorageBuffers)
|
|
||||||
{
|
|
||||||
// Vertex storage buffers
|
|
||||||
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
|
|
||||||
descriptorRange.NumDescriptors = vertexShader->NumStorageBuffers;
|
|
||||||
descriptorRange.BaseShaderRegister = vertexShader->NumSamplers + vertexShader->NumStorageBuffers;
|
|
||||||
descriptorRange.RegisterSpace = 0;
|
|
||||||
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
|
|
||||||
descriptorRanges[rangeCount] = descriptorRange;
|
|
||||||
|
|
||||||
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
|
||||||
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
|
|
||||||
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
|
|
||||||
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
|
|
||||||
rootParameters[parameterCount] = rootParameter;
|
|
||||||
d3d12GraphicsRootSignature->VertexStorageBufferRootIndex = parameterCount;
|
|
||||||
rangeCount += 1;
|
|
||||||
parameterCount += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vertex Uniforms
|
|
||||||
for (uint32 i = 0; i < vertexShader->NumUniformBuffers; ++i)
|
|
||||||
{
|
|
||||||
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
|
|
||||||
rootParameter.Descriptor.ShaderRegister = i;
|
|
||||||
rootParameter.Descriptor.RegisterSpace = 1;
|
|
||||||
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
|
|
||||||
rootParameters[parameterCount] = rootParameter;
|
|
||||||
d3d12GraphicsRootSignature->VertexUniformBufferRootIndex[i] = parameterCount;
|
|
||||||
parameterCount += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fragmentShader->NumSamplers)
|
|
||||||
{
|
|
||||||
// Fragment Samplers
|
|
||||||
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
|
|
||||||
descriptorRange.NumDescriptors = fragmentShader->NumSamplers;
|
|
||||||
descriptorRange.BaseShaderRegister = 0;
|
|
||||||
descriptorRange.RegisterSpace = 2;
|
|
||||||
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
|
|
||||||
descriptorRanges[rangeCount] = descriptorRange;
|
|
||||||
|
|
||||||
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
|
||||||
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
|
|
||||||
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
|
|
||||||
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
|
|
||||||
rootParameters[parameterCount] = rootParameter;
|
|
||||||
d3d12GraphicsRootSignature->FragmentSamplerRootIndex = parameterCount;
|
|
||||||
rangeCount += 1;
|
|
||||||
parameterCount += 1;
|
|
||||||
|
|
||||||
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
|
|
||||||
descriptorRange.NumDescriptors = fragmentShader->NumSamplers;
|
|
||||||
descriptorRange.BaseShaderRegister = 0;
|
|
||||||
descriptorRange.RegisterSpace = 2;
|
|
||||||
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
|
|
||||||
descriptorRanges[rangeCount] = descriptorRange;
|
|
||||||
|
|
||||||
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
|
||||||
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
|
|
||||||
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
|
|
||||||
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
|
|
||||||
rootParameters[parameterCount] = rootParameter;
|
|
||||||
d3d12GraphicsRootSignature->FragmentSamplerTextureRootIndex = parameterCount;
|
|
||||||
rangeCount += 1;
|
|
||||||
parameterCount += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fragmentShader->NumStorageTextures)
|
|
||||||
{
|
|
||||||
// Fragment Storage Textures
|
|
||||||
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
|
|
||||||
descriptorRange.NumDescriptors = fragmentShader->NumStorageTextures;
|
|
||||||
descriptorRange.BaseShaderRegister = fragmentShader->NumSamplers;
|
|
||||||
descriptorRange.RegisterSpace = 2;
|
|
||||||
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
|
|
||||||
descriptorRanges[rangeCount] = descriptorRange;
|
|
||||||
|
|
||||||
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
|
||||||
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
|
|
||||||
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
|
|
||||||
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
|
|
||||||
rootParameters[parameterCount] = rootParameter;
|
|
||||||
d3d12GraphicsRootSignature->FragmentStorageTextureRootIndex = parameterCount;
|
|
||||||
rangeCount += 1;
|
|
||||||
parameterCount += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fragmentShader->NumStorageBuffers)
|
|
||||||
{
|
|
||||||
// Fragment Storage Buffers
|
|
||||||
descriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
|
|
||||||
descriptorRange.NumDescriptors = fragmentShader->NumStorageBuffers;
|
|
||||||
descriptorRange.BaseShaderRegister = fragmentShader->NumSamplers + fragmentShader->NumStorageTextures;
|
|
||||||
descriptorRange.RegisterSpace = 2;
|
|
||||||
descriptorRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
|
|
||||||
descriptorRanges[rangeCount] = descriptorRange;
|
|
||||||
|
|
||||||
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
|
||||||
rootParameter.DescriptorTable.NumDescriptorRanges = 1;
|
|
||||||
rootParameter.DescriptorTable.pDescriptorRanges = &descriptorRanges[rangeCount];
|
|
||||||
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
|
|
||||||
rootParameters[parameterCount] = rootParameter;
|
|
||||||
d3d12GraphicsRootSignature->FragmentStorageBufferRootIndex = parameterCount;
|
|
||||||
rangeCount += 1;
|
|
||||||
parameterCount += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fragment Uniforms
|
|
||||||
for (uint32 i = 0; i < fragmentShader->NumUniformBuffers; ++i)
|
|
||||||
{
|
|
||||||
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
|
|
||||||
rootParameter.Descriptor.ShaderRegister = i;
|
|
||||||
rootParameter.Descriptor.RegisterSpace = 3;
|
|
||||||
rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
|
|
||||||
rootParameters[parameterCount] = rootParameter;
|
|
||||||
d3d12GraphicsRootSignature->FragmentUniformBufferRootIndex[i] = parameterCount;
|
|
||||||
parameterCount += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert(parameterCount <= kMaxRootSignatureParameters);
|
|
||||||
Assert(rangeCount <= kMaxRootSignatureParameters);
|
|
||||||
|
|
||||||
// Create the root signature description
|
|
||||||
D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc;
|
|
||||||
rootSignatureDesc.NumParameters = parameterCount;
|
|
||||||
rootSignatureDesc.pParameters = rootParameters;
|
|
||||||
rootSignatureDesc.NumStaticSamplers = 0;
|
|
||||||
rootSignatureDesc.pStaticSamplers = nullptr;
|
|
||||||
rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
|
|
||||||
|
|
||||||
// Serialize the root signature
|
|
||||||
ID3DBlob* serializedRootSignature;
|
|
||||||
ID3DBlob* errorBlob;
|
|
||||||
HRESULT res = d3d12Driver->D3D12SerializeRootSignatureFct(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1_0,
|
|
||||||
&serializedRootSignature, &errorBlob);
|
|
||||||
if (FAILED(res))
|
|
||||||
{
|
|
||||||
if (errorBlob)
|
|
||||||
{
|
|
||||||
auto errorBuffer = ID3D10Blob_GetBufferPointer(errorBlob);
|
|
||||||
LogError(LogCategory::Graphics, "Failed to serialize RootSignature: %s", errorBuffer);
|
|
||||||
ID3D10Blob_Release(errorBlob);
|
|
||||||
}
|
|
||||||
DestroyGraphicsRootSignature(d3d12GraphicsRootSignature);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the root signature
|
|
||||||
ID3D12RootSignature* rootSignature;
|
|
||||||
res = ID3D12Device_CreateRootSignature(d3d12Driver->D3D12Device, 0, ID3D10Blob_GetBufferPointer(serializedRootSignature),
|
|
||||||
ID3D10Blob_GetBufferSize(serializedRootSignature),
|
|
||||||
IID_ID3D12RootSignature, reinterpret_cast<void**>(&rootSignature));
|
|
||||||
if (FAILED(res))
|
|
||||||
{
|
|
||||||
if (errorBlob)
|
|
||||||
{
|
|
||||||
LogError(LogCategory::Graphics, "Failed to create RootSignature: %s",
|
|
||||||
(const char*)ID3D10Blob_GetBufferPointer(errorBlob));
|
|
||||||
ID3D10Blob_Release(errorBlob);
|
|
||||||
}
|
|
||||||
DestroyGraphicsRootSignature(d3d12GraphicsRootSignature);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
d3d12GraphicsRootSignature->Handle = rootSignature;
|
|
||||||
return d3d12GraphicsRootSignature;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DestroyGraphicsRootSignature(NonNullPtr<D3D12GraphicsRootSignature> rootSignature)
|
|
||||||
{
|
|
||||||
if (!rootSignature)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (rootSignature->Handle)
|
|
||||||
{
|
|
||||||
ID3D12RootSignature_Release(rootSignature->Handle);
|
|
||||||
}
|
|
||||||
Free(rootSignature.Get());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CopyShader(NonNullPtr<D3D12Shader> destination, NonNullPtr<D3D12Shader> source)
|
void CopyShader(NonNullPtr<D3D12Shader> destination, NonNullPtr<D3D12Shader> source)
|
||||||
{
|
{
|
||||||
D3D12Shader* src = source.Get();
|
D3D12Shader* src = source.Get();
|
||||||
@@ -680,14 +402,8 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
psoDesc.NodeMask = 0;
|
psoDesc.NodeMask = 0;
|
||||||
|
|
||||||
D3D12GraphicsRootSignature* rootSignature = CreateGraphicsRootSignature(d3d12Driver, vertexShader, fragmentShader);
|
pipeline->RootSignature = d3d12Driver->BindlessRootSignature;
|
||||||
if (rootSignature == nullptr)
|
psoDesc.pRootSignature = d3d12Driver->BindlessRootSignature->Handle;
|
||||||
{
|
|
||||||
Internal::ReleaseGraphicsPipeline(pipeline);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
pipeline->RootSignature = rootSignature;
|
|
||||||
psoDesc.pRootSignature = rootSignature->Handle;
|
|
||||||
|
|
||||||
ID3D12PipelineState* pipelineState;
|
ID3D12PipelineState* pipelineState;
|
||||||
HRESULT res = ID3D12Device_CreateGraphicsPipelineState(d3d12Driver->D3D12Device, &psoDesc, IID_ID3D12PipelineState,
|
HRESULT res = ID3D12Device_CreateGraphicsPipelineState(d3d12Driver->D3D12Device, &psoDesc, IID_ID3D12PipelineState,
|
||||||
@@ -774,20 +490,13 @@ namespace Juliet::D3D12
|
|||||||
fragmentShader = d3d12GraphicsPipeline->FragmentShaderCache;
|
fragmentShader = d3d12GraphicsPipeline->FragmentShaderCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recreate a new root signature and pipeline state
|
|
||||||
D3D12GraphicsRootSignature* rootSignature = CreateGraphicsRootSignature(d3d12Driver, vertexShader, fragmentShader);
|
|
||||||
if (rootSignature == nullptr)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto psoDesc = d3d12GraphicsPipeline->PSODescTemplate;
|
auto psoDesc = d3d12GraphicsPipeline->PSODescTemplate;
|
||||||
psoDesc.VS.pShaderBytecode = vertexShader->ByteCode.Data;
|
psoDesc.VS.pShaderBytecode = vertexShader->ByteCode.Data;
|
||||||
psoDesc.VS.BytecodeLength = vertexShader->ByteCode.Size;
|
psoDesc.VS.BytecodeLength = vertexShader->ByteCode.Size;
|
||||||
psoDesc.PS.pShaderBytecode = fragmentShader->ByteCode.Data;
|
psoDesc.PS.pShaderBytecode = fragmentShader->ByteCode.Data;
|
||||||
psoDesc.PS.BytecodeLength = fragmentShader->ByteCode.Size;
|
psoDesc.PS.BytecodeLength = fragmentShader->ByteCode.Size;
|
||||||
|
|
||||||
psoDesc.pRootSignature = rootSignature->Handle;
|
psoDesc.pRootSignature = d3d12Driver->BindlessRootSignature->Handle;
|
||||||
|
|
||||||
ID3D12PipelineState* pipelineState;
|
ID3D12PipelineState* pipelineState;
|
||||||
HRESULT res = ID3D12Device_CreateGraphicsPipelineState(d3d12Driver->D3D12Device, &psoDesc, IID_ID3D12PipelineState,
|
HRESULT res = ID3D12Device_CreateGraphicsPipelineState(d3d12Driver->D3D12Device, &psoDesc, IID_ID3D12PipelineState,
|
||||||
@@ -815,12 +524,6 @@ namespace Juliet::D3D12
|
|||||||
}
|
}
|
||||||
d3d12GraphicsPipeline->PipelineState = pipelineState;
|
d3d12GraphicsPipeline->PipelineState = pipelineState;
|
||||||
|
|
||||||
if (d3d12GraphicsPipeline->RootSignature)
|
|
||||||
{
|
|
||||||
DestroyGraphicsRootSignature(d3d12GraphicsPipeline->RootSignature);
|
|
||||||
}
|
|
||||||
d3d12GraphicsPipeline->RootSignature = rootSignature;
|
|
||||||
|
|
||||||
if (vertexShader != d3d12GraphicsPipeline->VertexShaderCache)
|
if (vertexShader != d3d12GraphicsPipeline->VertexShaderCache)
|
||||||
{
|
{
|
||||||
CopyShader(d3d12GraphicsPipeline->VertexShaderCache, vertexShader);
|
CopyShader(d3d12GraphicsPipeline->VertexShaderCache, vertexShader);
|
||||||
@@ -842,7 +545,6 @@ namespace Juliet::D3D12
|
|||||||
{
|
{
|
||||||
ID3D12PipelineState_Release(d3d12GraphicsPipeline->PipelineState);
|
ID3D12PipelineState_Release(d3d12GraphicsPipeline->PipelineState);
|
||||||
}
|
}
|
||||||
DestroyGraphicsRootSignature(d3d12GraphicsPipeline->RootSignature);
|
|
||||||
|
|
||||||
#if ALLOW_SHADER_HOT_RELOAD
|
#if ALLOW_SHADER_HOT_RELOAD
|
||||||
SafeFree(d3d12GraphicsPipeline->VertexShaderCache);
|
SafeFree(d3d12GraphicsPipeline->VertexShaderCache);
|
||||||
|
|||||||
@@ -18,20 +18,6 @@ namespace Juliet::D3D12
|
|||||||
struct D3D12GraphicsRootSignature
|
struct D3D12GraphicsRootSignature
|
||||||
{
|
{
|
||||||
ID3D12RootSignature* Handle;
|
ID3D12RootSignature* Handle;
|
||||||
|
|
||||||
int32 VertexSamplerRootIndex;
|
|
||||||
int32 VertexSamplerTextureRootIndex;
|
|
||||||
int32 VertexStorageTextureRootIndex;
|
|
||||||
int32 VertexStorageBufferRootIndex;
|
|
||||||
|
|
||||||
int32 VertexUniformBufferRootIndex[GPUDriver::kMaxUniformBuffersPerStage];
|
|
||||||
|
|
||||||
int32 FragmentSamplerRootIndex;
|
|
||||||
int32 FragmentSamplerTextureRootIndex;
|
|
||||||
int32 FragmentStorageTextureRootIndex;
|
|
||||||
int32 FragmentStorageBufferRootIndex;
|
|
||||||
|
|
||||||
int32 FragmentUniformBufferRootIndex[GPUDriver::kMaxUniformBuffersPerStage];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct D3D12GraphicsPipeline
|
struct D3D12GraphicsPipeline
|
||||||
|
|||||||
@@ -197,6 +197,9 @@ namespace Juliet::D3D12
|
|||||||
|
|
||||||
d3d12CommandList->CurrentGraphicsPipeline = pipeline;
|
d3d12CommandList->CurrentGraphicsPipeline = pipeline;
|
||||||
|
|
||||||
|
// Set the Descriptor heap
|
||||||
|
Internal::SetDescriptorHeaps(d3d12CommandList);
|
||||||
|
|
||||||
// Set the pipeline state
|
// Set the pipeline state
|
||||||
ID3D12GraphicsCommandList_SetPipelineState(d3d12CommandList->GraphicsCommandList.CommandList, pipeline->PipelineState);
|
ID3D12GraphicsCommandList_SetPipelineState(d3d12CommandList->GraphicsCommandList.CommandList, pipeline->PipelineState);
|
||||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(d3d12CommandList->GraphicsCommandList.CommandList,
|
ID3D12GraphicsCommandList_SetGraphicsRootSignature(d3d12CommandList->GraphicsCommandList.CommandList,
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ namespace Juliet
|
|||||||
static constexpr uint8 kMaxColorTargetInfo = 4;
|
static constexpr uint8 kMaxColorTargetInfo = 4;
|
||||||
static constexpr uint8 kMaxUniformBuffersPerStage = 4;
|
static constexpr uint8 kMaxUniformBuffersPerStage = 4;
|
||||||
static constexpr uint8 kMaxVertexBuffers = 16;
|
static constexpr uint8 kMaxVertexBuffers = 16;
|
||||||
|
|
||||||
|
static constexpr uint32 kCBV_SRV_UAV_HeapDescriptorCount = 65536;
|
||||||
|
static constexpr uint32 kSampler_HeapDescriptorCount = 2048;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GraphicsDevice
|
struct GraphicsDevice
|
||||||
|
|||||||
@@ -96,19 +96,19 @@ namespace
|
|||||||
case ShaderStage::Vertex:
|
case ShaderStage::Vertex:
|
||||||
{
|
{
|
||||||
args[argCount++] = const_cast<LPCWSTR>(L"-T");
|
args[argCount++] = const_cast<LPCWSTR>(L"-T");
|
||||||
args[argCount++] = const_cast<LPCWSTR>(L"vs_6_0");
|
args[argCount++] = const_cast<LPCWSTR>(L"vs_6_6");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ShaderStage::Fragment:
|
case ShaderStage::Fragment:
|
||||||
{
|
{
|
||||||
args[argCount++] = const_cast<LPCWSTR>(L"-T");
|
args[argCount++] = const_cast<LPCWSTR>(L"-T");
|
||||||
args[argCount++] = const_cast<LPCWSTR>(L"ps_6_0");
|
args[argCount++] = const_cast<LPCWSTR>(L"ps_6_6");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ShaderStage::Compute:
|
case ShaderStage::Compute:
|
||||||
{
|
{
|
||||||
args[argCount++] = const_cast<LPCWSTR>(L"-T");
|
args[argCount++] = const_cast<LPCWSTR>(L"-T");
|
||||||
args[argCount++] = const_cast<LPCWSTR>(L"cs_6_0");
|
args[argCount++] = const_cast<LPCWSTR>(L"cs_6_6");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ShaderStage::Invalid:
|
case ShaderStage::Invalid:
|
||||||
|
|||||||
Reference in New Issue
Block a user