summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineD3D12
diff options
context:
space:
mode:
authorazhirnov <zh1dron@gmail.com>2020-11-05 16:58:57 +0000
committerazhirnov <zh1dron@gmail.com>2020-11-05 16:58:57 +0000
commit8e0218168e2f63812f658298b3571c53879a5780 (patch)
treeb07a48fcca9fb9440493ed00b67dd2b28872c327 /Graphics/GraphicsEngineD3D12
parentAdded AS copy with compacting. (diff)
downloadDiligentCore-8e0218168e2f63812f658298b3571c53879a5780.tar.gz
DiligentCore-8e0218168e2f63812f658298b3571c53879a5780.zip
Added support for local root signature & shader record.
Bug fix for ray tracing.
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
-rw-r--r--Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp4
-rw-r--r--Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp11
-rw-r--r--Graphics/GraphicsEngineD3D12/include/RootSignature.hpp19
-rw-r--r--Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp3
-rw-r--r--Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp19
-rw-r--r--Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp73
-rw-r--r--Graphics/GraphicsEngineD3D12/src/RootSignature.cpp53
-rw-r--r--Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp9
8 files changed, 127 insertions, 64 deletions
diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp
index a112b90e..1ef31842 100644
--- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp
@@ -262,10 +262,10 @@ public:
virtual void DILIGENT_CALL_TYPE TransitionBufferState(IBuffer* pBuffer, D3D12_RESOURCE_STATES State) override final;
/// Implementation of IDeviceContext::BuildBLAS() in Direct3D12 backend.
- virtual void DILIGENT_CALL_TYPE BuildBLAS(const BLASBuildAttribs& Attribs) override final;
+ virtual void DILIGENT_CALL_TYPE BuildBLAS(const BuildBLASAttribs& Attribs) override final;
/// Implementation of IDeviceContext::BuildTLAS() in Direct3D12 backend.
- virtual void DILIGENT_CALL_TYPE BuildTLAS(const TLASBuildAttribs& Attribs) override final;
+ virtual void DILIGENT_CALL_TYPE BuildTLAS(const BuildTLASAttribs& Attribs) override final;
/// Implementation of IDeviceContext::CopyBLAS() in Direct3D12 backend.
virtual void DILIGENT_CALL_TYPE CopyBLAS(const CopyBLASAttribs& Attribs) override final;
diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp
index f336c6ff..15eff0d9 100644
--- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp
@@ -139,16 +139,13 @@ private:
using TShaderStages = std::vector<ShaderStageInfo>;
template <typename PSOCreateInfoType, typename InitPSODescType>
- void InitInternalObjects(const PSOCreateInfoType& CreateInfo, TShaderStages& ShaderStages, InitPSODescType InitPSODesc);
- void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages);
+ void InitInternalObjects(const PSOCreateInfoType& CreateInfo, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot, InitPSODescType InitPSODesc);
+ void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot);
void Destruct();
- void CreateLocalRootSignature(const RayTracingPipelineDesc& Desc);
-
- CComPtr<ID3D12DeviceChild> m_pd3d12PSO;
- RootSignature m_RootSig;
- CComPtr<ID3D12RootSignature> m_LocalRootSignature;
+ CComPtr<ID3D12DeviceChild> m_pd3d12PSO;
+ RootSignature m_RootSig;
// Must be defined before default SRB
SRBMemoryAllocator m_SRBMemAllocator;
diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp
index a6bf76b1..331c62e5 100644
--- a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp
@@ -587,4 +587,23 @@ void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache,
}
}
+
+class LocalRootSignature
+{
+public:
+ LocalRootSignature(const char* pCBName, Uint32 ShaderRecordSize);
+
+ bool SetOrMerge(const D3DShaderResourceAttribs& CB);
+
+ ID3D12RootSignature* Create(ID3D12Device* pDevice);
+
+private:
+ static constexpr Uint32 InvalidBindPoint = ~0u;
+
+ const char* m_pName = nullptr;
+ Uint32 m_BindPoint = InvalidBindPoint;
+ const Uint32 m_ShaderRecordSize = 0;
+ CComPtr<ID3D12RootSignature> m_LocalRootSignature;
+};
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp
index f7f2fa13..fe161157 100644
--- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp
@@ -140,7 +140,8 @@ public:
const SHADER_RESOURCE_VARIABLE_TYPE* const VarTypes,
Uint32 NumAllowedTypes,
ShaderResourceCacheD3D12* pResourceCache,
- class RootSignature* pRootSig);
+ class RootSignature* pRootSig,
+ class LocalRootSignature* pLocalRootSig);
// clang-format off
ShaderResourceLayoutD3D12 (const ShaderResourceLayoutD3D12&) = delete;
diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
index 41de3a47..99e4156d 100644
--- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
@@ -2272,7 +2272,7 @@ void DeviceContextD3D12Impl::ResolveTextureSubresource(ITexture*
CmdCtx.ResolveSubresource(pDstTexD3D12->GetD3D12Resource(), DstSubresIndex, pSrcTexD3D12->GetD3D12Resource(), SrcSubresIndex, DXGIFmt);
}
-void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs)
+void DeviceContextD3D12Impl::BuildBLAS(const BuildBLASAttribs& Attribs)
{
if (!TDeviceContextBase::BuildBLAS(Attribs, 0))
return;
@@ -2344,6 +2344,8 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs)
auto* const pTB = ValidatedCast<BufferD3D12Impl>(SrcTris.pTransformBuffer);
d3d12Tris.Transform3x4 = pTB->GetGPUAddress() + SrcTris.TransformBufferOffset;
+ VERIFY_EXPR(d3d12Tris.Transform3x4 % D3D12_RAYTRACING_TRANSFORM3X4_BYTE_ALIGNMENT == 0);
+
TransitionOrVerifyBufferState(CmdCtx, *pTB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
}
else
@@ -2378,6 +2380,8 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs)
d3d12AABs.AABBs.StartAddress = pBB->GetGPUAddress() + SrcBoxes.BoxOffset;
d3d12AABs.AABBs.StrideInBytes = SrcBoxes.BoxStride;
+ VERIFY_EXPR(d3d12AABs.AABBs.StartAddress % D3D12_RAYTRACING_AABB_BYTE_ALIGNMENT == 0);
+
TransitionOrVerifyBufferState(CmdCtx, *pBB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, OpName);
}
}
@@ -2389,9 +2393,11 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs)
d3d12BuildASInputs.pGeometryDescs = Geometries.data();
d3d12BuildASDesc.DestAccelerationStructureData = pBLASD12->GetGPUAddress();
- d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress();
+ d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress() + Attribs.ScratchBufferOffset;
d3d12BuildASDesc.SourceAccelerationStructureData = 0;
+ VERIFY_EXPR(d3d12BuildASDesc.ScratchAccelerationStructureData % D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT == 0);
+
CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(d3d12BuildASDesc, 0, nullptr);
++m_State.NumCommands;
@@ -2400,7 +2406,7 @@ void DeviceContextD3D12Impl::BuildBLAS(const BLASBuildAttribs& Attribs)
#endif
}
-void DeviceContextD3D12Impl::BuildTLAS(const TLASBuildAttribs& Attribs)
+void DeviceContextD3D12Impl::BuildTLAS(const BuildTLASAttribs& Attribs)
{
if (!TDeviceContextBase::BuildTLAS(Attribs, 0))
return;
@@ -2451,12 +2457,15 @@ void DeviceContextD3D12Impl::BuildTLAS(const TLASBuildAttribs& Attribs)
d3d12BuildASInputs.Flags = BuildASFlagsToD3D12ASBuildFlags(pTLASD12->GetDesc().Flags);
d3d12BuildASInputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
d3d12BuildASInputs.NumDescs = Attribs.InstanceCount;
- d3d12BuildASInputs.InstanceDescs = pInstancesD12->GetGPUAddress();
+ d3d12BuildASInputs.InstanceDescs = pInstancesD12->GetGPUAddress() + Attribs.InstanceBufferOffset;
d3d12BuildASDesc.DestAccelerationStructureData = pTLASD12->GetGPUAddress();
- d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress();
+ d3d12BuildASDesc.ScratchAccelerationStructureData = pScratchD12->GetGPUAddress() + Attribs.ScratchBufferOffset;
d3d12BuildASDesc.SourceAccelerationStructureData = 0;
+ VERIFY_EXPR(d3d12BuildASInputs.InstanceDescs % D3D12_RAYTRACING_INSTANCE_DESCS_BYTE_ALIGNMENT == 0);
+ VERIFY_EXPR(d3d12BuildASDesc.ScratchAccelerationStructureData % D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT == 0);
+
CmdCtx.AsGraphicsContext4().BuildRaytracingAccelerationStructure(d3d12BuildASDesc, 0, nullptr);
++m_State.NumCommands;
}
diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp
index b1fe19fe..1a12f25b 100644
--- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp
@@ -208,17 +208,18 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI
VERIFY_EXPR(Uint32{CreateInfo.GeneralShaderCount} + Uint32{CreateInfo.TriangleHitShaderCount} + Uint32{CreateInfo.ProceduralHitShaderCount} == GroupIndex);
- if (CreateInfo.RayTracingPipeline.MaxRecursionDepth > D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH)
- LOG_PSO_ERROR_AND_THROW("MaxRecursionDepth must be less than equal to ", D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH);
+ const Uint32 RecursionDepthLimit = D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH - 1;
+ if (CreateInfo.RayTracingPipeline.MaxRecursionDepth > RecursionDepthLimit)
+ LOG_PSO_ERROR_AND_THROW("MaxRecursionDepth must be less than or equal to ", RecursionDepthLimit);
auto& PipelineConfig = *TempPool.Construct<D3D12_RAYTRACING_PIPELINE_CONFIG>();
- // for compatibility with Vulkan set minimal recursion depth to 1
- PipelineConfig.MaxTraceRecursionDepth = std::max<Uint32>(1, CreateInfo.RayTracingPipeline.MaxRecursionDepth);
+ // For compatibility with Vulkan set minimal recursion depth to one, zero means no tracing of rays at all.
+ PipelineConfig.MaxTraceRecursionDepth = CreateInfo.RayTracingPipeline.MaxRecursionDepth + 1;
Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG, &PipelineConfig});
auto& ShaderConfig = *TempPool.Construct<D3D12_RAYTRACING_SHADER_CONFIG>();
- ShaderConfig.MaxAttributeSizeInBytes = D3D12_RAYTRACING_MAX_ATTRIBUTE_SIZE_IN_BYTES;
- ShaderConfig.MaxPayloadSizeInBytes = 32; // AZ TODO
+ ShaderConfig.MaxAttributeSizeInBytes = CreateInfo.MaxAttributeSize == 0 ? D3D12_RAYTRACING_MAX_ATTRIBUTE_SIZE_IN_BYTES : CreateInfo.MaxAttributeSize;
+ ShaderConfig.MaxPayloadSizeInBytes = CreateInfo.MaxPayloadSize == 0 ? 32 : CreateInfo.MaxPayloadSize;
Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG, &ShaderConfig});
#undef LOG_PSO_ERROR_AND_THROW
}
@@ -304,6 +305,7 @@ size_t PipelineStateD3D12Impl::ShaderStageInfo::Count() const
template <typename PSOCreateInfoType, typename InitPSODescType>
void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo,
TShaderStages& ShaderStages,
+ LocalRootSignature* pLocalRoot,
InitPSODescType InitPSODesc)
{
m_ResourceLayoutIndex.fill(-1);
@@ -343,7 +345,7 @@ void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& Create
// It is important to construct all objects before initializing them because if an exception is thrown,
// destructors will be called for all objects
- InitResourceLayouts(CreateInfo, ShaderStages);
+ InitResourceLayouts(CreateInfo, ShaderStages, pLocalRoot);
}
@@ -356,7 +358,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters*
try
{
TShaderStages ShaderStages;
- InitInternalObjects(CreateInfo, ShaderStages,
+ InitInternalObjects(CreateInfo, ShaderStages, nullptr,
[this](const GraphicsPipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) //
{
InitializePipelineDesc(CreateInfo, MemPool);
@@ -567,7 +569,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters*
try
{
TShaderStages ShaderStages;
- InitInternalObjects(CreateInfo, ShaderStages,
+ InitInternalObjects(CreateInfo, ShaderStages, nullptr,
[this](const ComputePipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) //
{
InitializePipelineDesc(CreateInfo, MemPool);
@@ -625,12 +627,12 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters*
{
try
{
- CreateLocalRootSignature(CreateInfo.RayTracingPipeline);
-
+ LocalRootSignature LocalRootSig{CreateInfo.pShaderRecordName, CreateInfo.RayTracingPipeline.ShaderRecordSize};
TShaderStages ShaderStages;
std::vector<D3D12_STATE_SUBOBJECT> Subobjects;
DynamicLinearAllocator TempPool{GetRawAllocator(), 4 << 10};
- InitInternalObjects(CreateInfo, ShaderStages,
+
+ InitInternalObjects(CreateInfo, ShaderStages, &LocalRootSig,
[&](const RayTracingPipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) //
{
TNameToGroupIndexMap NameToGroupIndex;
@@ -639,11 +641,13 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters*
} //
);
+ auto pd3d12Device = pDeviceD3D12->GetD3D12Device5();
+
D3D12_GLOBAL_ROOT_SIGNATURE GlobalRoot = {m_RootSig.GetD3D12RootSignature()};
Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE, &GlobalRoot});
- D3D12_LOCAL_ROOT_SIGNATURE LocalRoot = {m_LocalRootSignature};
- if (m_LocalRootSignature)
+ D3D12_LOCAL_ROOT_SIGNATURE LocalRoot = {LocalRootSig.Create(pd3d12Device)};
+ if (LocalRoot.pLocalRootSignature)
Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE, &LocalRoot});
D3D12_STATE_OBJECT_DESC RTPipelineDesc = {};
@@ -651,8 +655,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters*
RTPipelineDesc.NumSubobjects = static_cast<UINT>(Subobjects.size());
RTPipelineDesc.pSubobjects = Subobjects.data();
- auto pd3d12Device = pDeviceD3D12->GetD3D12Device5();
- HRESULT hr = pd3d12Device->CreateStateObject(&RTPipelineDesc, IID_PPV_ARGS(&m_pd3d12PSO));
+ HRESULT hr = pd3d12Device->CreateStateObject(&RTPipelineDesc, IID_PPV_ARGS(&m_pd3d12PSO));
if (FAILED(hr))
LOG_ERROR_AND_THROW("Failed to create ray tracing state object");
@@ -674,35 +677,6 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters*
}
}
-void PipelineStateD3D12Impl::CreateLocalRootSignature(const RayTracingPipelineDesc& Desc)
-{
- // AZ TODO
- /*if (Desc.ShaderRecordSize == 0)
- return;
-
- D3D12_ROOT_SIGNATURE_DESC d3d12RootSignatureDesc = {};
- D3D12_ROOT_PARAMETER d3d12Params = {};
-
- d3d12Params.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
- d3d12Params.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- d3d12Params.Constants.Num32BitValues = Desc.ShaderRecordSize / 4;
- d3d12Params.Constants.RegisterSpace = Desc.LocalRootRegisterSpace;
- d3d12Params.Constants.ShaderRegister = 0;
-
- d3d12RootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE;
- d3d12RootSignatureDesc.NumParameters = 1;
- d3d12RootSignatureDesc.pParameters = &d3d12Params;
-
- CComPtr<ID3DBlob> signature;
- auto hr = D3D12SerializeRootSignature(&d3d12RootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, nullptr);
- CHECK_D3D_RESULT_THROW(hr, "Failed to serialize root signature");
-
- auto pd3d12Device = GetDevice()->GetD3D12Device();
-
- hr = pd3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_LocalRootSignature));
- CHECK_D3D_RESULT_THROW(hr, "Failed to create root signature");*/
-}
-
PipelineStateD3D12Impl::~PipelineStateD3D12Impl()
{
Destruct();
@@ -749,7 +723,8 @@ IMPLEMENT_QUERY_INTERFACE(PipelineStateD3D12Impl, IID_PipelineStateD3D12, TPipel
void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo,
- TShaderStages& ShaderStages)
+ TShaderStages& ShaderStages,
+ LocalRootSignature* pLocalRoot)
{
auto pd3d12Device = GetDevice()->GetD3D12Device();
const auto& ResourceLayout = m_Desc.ResourceLayout;
@@ -786,7 +761,8 @@ void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo&
nullptr,
0,
nullptr,
- &m_RootSig //
+ &m_RootSig,
+ pLocalRoot //
);
const SHADER_RESOURCE_VARIABLE_TYPE StaticVarType[] = {SHADER_RESOURCE_VARIABLE_TYPE_STATIC};
@@ -799,7 +775,8 @@ void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo&
StaticVarType,
_countof(StaticVarType),
m_pStaticResourceCaches + s,
- nullptr //
+ nullptr,
+ pLocalRoot //
);
m_pStaticVarManagers[s].Initialize(
diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp
index e6af12c8..921a6e4c 100644
--- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp
@@ -1109,4 +1109,57 @@ void RootSignature::TransitionResources(ShaderResourceCacheD3D12& ResourceCache,
);
}
+
+LocalRootSignature::LocalRootSignature(const char* pCBName, Uint32 ShaderRecordSize) :
+ m_pName{pCBName},
+ m_ShaderRecordSize{ShaderRecordSize}
+{
+ VERIFY_EXPR((m_pName != nullptr) == (m_ShaderRecordSize > 0));
+}
+
+bool LocalRootSignature::SetOrMerge(const D3DShaderResourceAttribs& CB)
+{
+ if (m_ShaderRecordSize > 0 &&
+ CB.GetInputType() == D3D_SIT_CBUFFER &&
+ strcmp(m_pName, CB.Name) == 0)
+ {
+ if (m_BindPoint == InvalidBindPoint)
+ m_BindPoint = CB.BindPoint;
+
+ VERIFY_EXPR(CB.BindCount == 1);
+ VERIFY_EXPR(m_BindPoint == CB.BindPoint);
+
+ return true;
+ }
+ return false;
+}
+
+ID3D12RootSignature* LocalRootSignature::Create(ID3D12Device* pDevice)
+{
+ if (m_ShaderRecordSize == 0 || m_BindPoint == InvalidBindPoint)
+ return nullptr;
+
+ D3D12_ROOT_SIGNATURE_DESC d3d12RootSignatureDesc = {};
+ D3D12_ROOT_PARAMETER d3d12Params = {};
+
+ d3d12Params.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
+ d3d12Params.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
+ d3d12Params.Constants.Num32BitValues = m_ShaderRecordSize / 4;
+ d3d12Params.Constants.RegisterSpace = 0;
+ d3d12Params.Constants.ShaderRegister = m_BindPoint;
+
+ d3d12RootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE;
+ d3d12RootSignatureDesc.NumParameters = 1;
+ d3d12RootSignatureDesc.pParameters = &d3d12Params;
+
+ CComPtr<ID3DBlob> signature;
+ auto hr = D3D12SerializeRootSignature(&d3d12RootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, nullptr);
+ CHECK_D3D_RESULT_THROW(hr, "Failed to serialize root signature");
+
+ hr = pDevice->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_LocalRootSignature));
+ CHECK_D3D_RESULT_THROW(hr, "Failed to create root signature");
+
+ return m_LocalRootSignature;
+}
+
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp
index bfc8693a..6218fbd3 100644
--- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp
@@ -135,7 +135,8 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device*
const SHADER_RESOURCE_VARIABLE_TYPE* const AllowedVarTypes,
Uint32 NumAllowedTypes,
ShaderResourceCacheD3D12* pResourceCache,
- RootSignature* pRootSig)
+ RootSignature* pRootSig,
+ LocalRootSignature* pLocalRootSig)
{
m_pd3d12Device = pd3d12Device;
@@ -170,6 +171,9 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device*
auto VarType = pResources->FindVariableType(Res, ResourceLayout);
if (IsAllowedType(VarType, AllowedTypeBits))
{
+ if (pLocalRootSig && pLocalRootSig->SetOrMerge(Res))
+ return;
+
bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Res.Name}, InvalidResourceIndex).second;
if (IsUniqueName)
{
@@ -313,6 +317,9 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device*
pResources->ProcessResources(
[&](const D3DShaderResourceAttribs& CB, Uint32) //
{
+ if (pLocalRootSig && pLocalRootSig->SetOrMerge(CB))
+ return;
+
auto VarType = pResources->FindVariableType(CB, ResourceLayout);
if (IsAllowedType(VarType, AllowedTypeBits))
AddResource(CB, CachedResourceType::CBV, VarType);