diff options
| author | azhirnov <zh1dron@gmail.com> | 2020-11-25 16:14:57 +0000 |
|---|---|---|
| committer | azhirnov <zh1dron@gmail.com> | 2020-11-25 16:35:13 +0000 |
| commit | c3058653add8f8a9d147de652a94c178a6973ac6 (patch) | |
| tree | 1dc04806de7cc862ea406d77d2adba8b3210452f /Graphics/GraphicsEngineD3D12 | |
| parent | Added support for VK_KHR_acceleration_structure and VK_KHR_ray_tracing_pipeline (diff) | |
| download | DiligentCore-c3058653add8f8a9d147de652a94c178a6973ac6.tar.gz DiligentCore-c3058653add8f8a9d147de652a94c178a6973ac6.zip | |
Added RootSignatureBuilder, some fixed for vulkan ray tracing
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
6 files changed, 258 insertions, 209 deletions
diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp index 15eff0d9..021a38b0 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp @@ -139,8 +139,8 @@ private: using TShaderStages = std::vector<ShaderStageInfo>; template <typename PSOCreateInfoType, typename InitPSODescType> - void InitInternalObjects(const PSOCreateInfoType& CreateInfo, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot, InitPSODescType InitPSODesc); - void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot); + void InitInternalObjects(const PSOCreateInfoType& CreateInfo, RootSignatureBuilder& RootSigBuilder, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot, InitPSODescType InitPSODesc); + void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, RootSignatureBuilder& RootSigBuilder, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot); void Destruct(); diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp index fe78a852..44b83433 100644 --- a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp @@ -298,33 +298,15 @@ private: /// Implementation of the Diligent::RootSignature class class RootSignature { + friend class RootSignatureBuilder; + public: RootSignature(); - void AllocateImmutableSamplers(const PipelineResourceLayoutDesc& ResourceLayout); - - void Finalize(ID3D12Device* pd3d12Device); - ID3D12RootSignature* GetD3D12RootSignature() const { return m_pd3d12RootSignature; } - size_t GetResourceCacheRequiredMemSize() const; - void InitResourceCache(class RenderDeviceD3D12Impl* pDeviceD3D12Impl, class ShaderResourceCacheD3D12& ResourceCache, IMemoryAllocator& CacheMemAllocator) const; - void InitImmutableSampler(SHADER_TYPE ShaderType, - const char* SamplerName, - const char* SamplerSuffix, - const D3DShaderResourceAttribs& ShaderResAttribs); - - void AllocateResourceSlot(SHADER_TYPE ShaderType, - PIPELINE_TYPE PipelineType, - const D3DShaderResourceAttribs& ShaderResAttribs, - SHADER_RESOURCE_VARIABLE_TYPE VariableType, - D3D12_DESCRIPTOR_RANGE_TYPE RangeType, - Uint32& BindPoint, - Uint32& RootIndex, - Uint32& OffsetFromTableStart); - // This method should be thread-safe as it does not modify any object state void (RootSignature::*CommitDescriptorHandles)(class RenderDeviceD3D12Impl* pRenderDeviceD3D12, ShaderResourceCacheD3D12& ResourceCache, @@ -374,32 +356,7 @@ public: return m_RootParams.GetHash(); } - // Note: sizeof(m_ImmutableSamplers) == 56 (MS compiler, release x64) - struct ImmutableSamplerAttribs - { - ImmutableSamplerDesc SamplerDesc; - UINT ShaderRegister = static_cast<UINT>(-1); - UINT ArraySize = 0; - UINT RegisterSpace = 0; - D3D12_SHADER_VISIBILITY ShaderVisibility = static_cast<D3D12_SHADER_VISIBILITY>(-1); - String Name; - SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN; - - ImmutableSamplerAttribs() noexcept {} - ImmutableSamplerAttribs(const ImmutableSamplerDesc& SamDesc, D3D12_SHADER_VISIBILITY Visibility, SHADER_TYPE Stage) noexcept : - SamplerDesc(SamDesc), - ShaderVisibility(Visibility), - ShaderType{Stage} - {} - }; - const ImmutableSamplerAttribs* GetImmutableSamplers() const { return m_ImmutableSamplers.data(); } - size_t GetImmutableSamplerCount() const { return m_ImmutableSamplers.size(); } - private: -#ifdef DILIGENT_DEBUG - void dbgVerifyRootParameters() const; -#endif - #ifdef DILIGENT_DEVELOPMENT static void DvpVerifyResourceState(const ShaderResourceCacheD3D12::Resource& Res, D3D12_DESCRIPTOR_RANGE_TYPE RangeType); @@ -500,12 +457,8 @@ private: // This array contains the same data for Sampler root table std::array<Uint8, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES* MAX_SHADERS_IN_PIPELINE> m_SamplerRootTablesMap = {}; - std::array<Uint16, D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER + 1> m_NumResources = {}; - RootParamsManager m_RootParams; - std::vector<ImmutableSamplerAttribs, STDAllocatorRawMem<ImmutableSamplerAttribs>> m_ImmutableSamplers; - IMemoryAllocator& m_MemAllocator; // Commits descriptor handles for static and mutable variables @@ -524,6 +477,71 @@ private: bool ValidateStates) const; }; + +class RootSignatureBuilder +{ +public: + explicit RootSignatureBuilder(RootSignature& RootSig); + + void AllocateImmutableSamplers(const PipelineResourceLayoutDesc& ResourceLayout); + + void InitImmutableSampler(SHADER_TYPE ShaderType, + const char* SamplerName, + const char* SamplerSuffix, + const D3DShaderResourceAttribs& ShaderResAttribs); + + void AllocateResourceSlot(SHADER_TYPE ShaderType, + PIPELINE_TYPE PipelineType, + const D3DShaderResourceAttribs& ShaderResAttribs, + SHADER_RESOURCE_VARIABLE_TYPE VariableType, + D3D12_DESCRIPTOR_RANGE_TYPE RangeType, + Uint32& BindPoint, + Uint32& RootIndex, + Uint32& OffsetFromTableStart); + + void Finalize(ID3D12Device* pd3d12Device); + + size_t GetResourceCacheRequiredMemSize() const; + + size_t GetHash() const + { + return m_RootSig.GetHash(); + } + + // Note: sizeof(m_ImmutableSamplers) == 56 (MS compiler, release x64) + struct ImmutableSamplerAttribs + { + ImmutableSamplerDesc SamplerDesc; + UINT ShaderRegister = static_cast<UINT>(-1); + UINT ArraySize = 0; + UINT RegisterSpace = 0; + D3D12_SHADER_VISIBILITY ShaderVisibility = static_cast<D3D12_SHADER_VISIBILITY>(-1); + String Name; + SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN; + + ImmutableSamplerAttribs() noexcept {} + ImmutableSamplerAttribs(const ImmutableSamplerDesc& SamDesc, D3D12_SHADER_VISIBILITY Visibility, SHADER_TYPE Stage) noexcept : + SamplerDesc(SamDesc), + ShaderVisibility(Visibility), + ShaderType{Stage} + {} + }; + const ImmutableSamplerAttribs* GetImmutableSamplers() const { return m_ImmutableSamplers.data(); } + size_t GetImmutableSamplerCount() const { return m_ImmutableSamplers.size(); } + +private: +#ifdef DILIGENT_DEBUG + void dbgVerifyRootParameters() const; +#endif + + RootSignature& m_RootSig; + + std::array<Uint16, D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER + 1> m_NumResources = {}; + + std::vector<ImmutableSamplerAttribs, STDAllocatorRawMem<ImmutableSamplerAttribs>> m_ImmutableSamplers; +}; + + void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, CommandContext& CmdCtx, bool IsCompute, diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp index 6f71f8f8..de0ecc29 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp @@ -140,7 +140,7 @@ public: const SHADER_RESOURCE_VARIABLE_TYPE* const VarTypes, Uint32 NumAllowedTypes, ShaderResourceCacheD3D12* pResourceCache, - class RootSignature* pRootSig, + class RootSignatureBuilder* pRootSig, class LocalRootSignature* pLocalRootSig); // clang-format off diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index f98781eb..6e71fcd6 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -281,7 +281,7 @@ void GetShaderIdentifiers(ID3D12DeviceChild* pSO, } } -void ExtractResourceBindingMap(const RootSignature& RootSig, +void ExtractResourceBindingMap(const RootSignatureBuilder& RootSig, const std::array<Int8, MAX_SHADERS_IN_PIPELINE>& ResourceLayoutIndex, const ShaderResourceLayoutD3D12* pResourceLayouts, const ShaderResourceLayoutD3D12* pStaticLayouts, @@ -364,6 +364,7 @@ size_t PipelineStateD3D12Impl::ShaderStageInfo::Count() const template <typename PSOCreateInfoType, typename InitPSODescType> void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo, + RootSignatureBuilder& RootSigBuilder, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot, InitPSODescType InitPSODesc) @@ -400,12 +401,12 @@ void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& Create InitPSODesc(CreateInfo, MemPool); - m_RootSig.AllocateImmutableSamplers(CreateInfo.PSODesc.ResourceLayout); + RootSigBuilder.AllocateImmutableSamplers(CreateInfo.PSODesc.ResourceLayout); // 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, pLocalRoot); + InitResourceLayouts(CreateInfo, RootSigBuilder, ShaderStages, pLocalRoot); } @@ -417,8 +418,9 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* { try { - TShaderStages ShaderStages; - InitInternalObjects(CreateInfo, ShaderStages, nullptr, + RootSignatureBuilder RootSigBuilder{m_RootSig}; + TShaderStages ShaderStages; + InitInternalObjects(CreateInfo, RootSigBuilder, ShaderStages, nullptr, [this](const GraphicsPipelineStateCreateInfo& CreateInfo, FixedLinearAllocator& MemPool) // { InitializePipelineDesc(CreateInfo, MemPool); @@ -628,8 +630,9 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* { try { - TShaderStages ShaderStages; - InitInternalObjects(CreateInfo, ShaderStages, nullptr, + RootSignatureBuilder RootSigBuilder{m_RootSig}; + TShaderStages ShaderStages; + InitInternalObjects(CreateInfo, RootSigBuilder, ShaderStages, nullptr, [this](const ComputePipelineStateCreateInfo& CreateInfo, FixedLinearAllocator& MemPool) // { InitializePipelineDesc(CreateInfo, MemPool); @@ -690,8 +693,9 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* LocalRootSignature LocalRootSig{CreateInfo.pShaderRecordName, CreateInfo.RayTracingPipeline.ShaderRecordSize}; TShaderStages ShaderStages; DynamicLinearAllocator TempPool{GetRawAllocator(), 4 << 10}; + RootSignatureBuilder RootSigBuilder{m_RootSig}; - InitInternalObjects(CreateInfo, ShaderStages, &LocalRootSig, + InitInternalObjects(CreateInfo, RootSigBuilder, ShaderStages, &LocalRootSig, [&](const RayTracingPipelineStateCreateInfo& CreateInfo, FixedLinearAllocator& MemPool) // { InitializePipelineDesc(CreateInfo, MemPool); @@ -701,7 +705,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* auto pd3d12Device = pDeviceD3D12->GetD3D12Device5(); TBindingMapPerStage BindingMapPerStage; - ExtractResourceBindingMap(m_RootSig, m_ResourceLayoutIndex, &m_pShaderResourceLayouts[0], &m_pShaderResourceLayouts[GetNumShaderStages()], BindingMapPerStage); + ExtractResourceBindingMap(RootSigBuilder, m_ResourceLayoutIndex, &m_pShaderResourceLayouts[0], &m_pShaderResourceLayouts[GetNumShaderStages()], BindingMapPerStage); std::vector<D3D12_STATE_SUBOBJECT> Subobjects; std::vector<CComPtr<IDxcBlob>> ShaderBlobs; @@ -786,6 +790,7 @@ void PipelineStateD3D12Impl::Destruct() IMPLEMENT_QUERY_INTERFACE(PipelineStateD3D12Impl, IID_PipelineStateD3D12, TPipelineStateBase) void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, + RootSignatureBuilder& RootSigBuilder, TShaderStages& ShaderStages, LocalRootSignature* pLocalRoot) { @@ -825,7 +830,7 @@ void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& nullptr, 0, nullptr, - &m_RootSig, + &RootSigBuilder, pLocalRoot // ); @@ -850,7 +855,7 @@ void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& 0 // ); } - m_RootSig.Finalize(pd3d12Device); + RootSigBuilder.Finalize(pd3d12Device); if (m_Desc.SRBAllocationGranularity > 1) { @@ -867,11 +872,11 @@ void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& ShaderVarMgrDataSizes[s] = ShaderVariableManagerD3D12::GetRequiredMemorySize(m_pShaderResourceLayouts[s], AllowedVarTypes.data(), static_cast<Uint32>(AllowedVarTypes.size()), NumVariablesUnused); } - auto CacheMemorySize = m_RootSig.GetResourceCacheRequiredMemSize(); + auto CacheMemorySize = RootSigBuilder.GetResourceCacheRequiredMemSize(); m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumShaderStages(), ShaderVarMgrDataSizes.data(), 1, &CacheMemorySize); } - m_ShaderResourceLayoutHash = m_RootSig.GetHash(); + m_ShaderResourceLayoutHash = RootSigBuilder.GetHash(); } void PipelineStateD3D12Impl::CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources) diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index cbe9d7bd..ab997d1d 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -165,49 +165,18 @@ size_t RootSignature::RootParamsManager::GetHash() const return hash; } -RootSignature::RootSignature() : - m_RootParams{GetRawAllocator()}, - m_MemAllocator{GetRawAllocator()}, - m_ImmutableSamplers(STD_ALLOCATOR_RAW_MEM(ImmutableSamplerAttribs, GetRawAllocator(), "Allocator for vector<ImmutableSamplerAttribs>")) -{ - m_SrvCbvUavRootTablesMap.fill(InvalidRootTableIndex); - m_SamplerRootTablesMap.fill(InvalidRootTableIndex); -} -// clang-format off -static D3D12_DESCRIPTOR_HEAP_TYPE RangeType2HeapTypeMap[] -{ - D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, //D3D12_DESCRIPTOR_RANGE_TYPE_SRV = 0 - D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, //D3D12_DESCRIPTOR_RANGE_TYPE_UAV = ( D3D12_DESCRIPTOR_RANGE_TYPE_SRV + 1 ) - D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, //D3D12_DESCRIPTOR_RANGE_TYPE_CBV = ( D3D12_DESCRIPTOR_RANGE_TYPE_UAV + 1 ) - D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER //D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER = ( D3D12_DESCRIPTOR_RANGE_TYPE_CBV + 1 ) -}; -// clang-format on -D3D12_DESCRIPTOR_HEAP_TYPE HeapTypeFromRangeType(D3D12_DESCRIPTOR_RANGE_TYPE RangeType) +RootSignatureBuilder::RootSignatureBuilder(RootSignature& RootSig) : + m_RootSig{RootSig}, + m_ImmutableSamplers(STD_ALLOCATOR_RAW_MEM(ImmutableSamplerAttribs, GetRawAllocator(), "Allocator for vector<ImmutableSamplerAttribs>")) { - VERIFY_EXPR(RangeType >= D3D12_DESCRIPTOR_RANGE_TYPE_SRV && RangeType <= D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER); - auto HeapType = RangeType2HeapTypeMap[RangeType]; - -#ifdef DILIGENT_DEBUG - switch (RangeType) - { - // clang-format off - case D3D12_DESCRIPTOR_RANGE_TYPE_CBV: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); break; - case D3D12_DESCRIPTOR_RANGE_TYPE_SRV: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); break; - case D3D12_DESCRIPTOR_RANGE_TYPE_UAV: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); break; - case D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); break; - // clang-format on - default: UNEXPECTED("Unexpected descriptor range type"); break; - } -#endif - return HeapType; } -void RootSignature::InitImmutableSampler(SHADER_TYPE ShaderType, - const char* SamplerName, - const char* SamplerSuffix, - const D3DShaderResourceAttribs& SamplerAttribs) +void RootSignatureBuilder::InitImmutableSampler(SHADER_TYPE ShaderType, + const char* SamplerName, + const char* SamplerSuffix, + const D3DShaderResourceAttribs& SamplerAttribs) { auto ShaderVisibility = ShaderTypeToD3D12ShaderVisibility(ShaderType); auto SamplerFound = false; @@ -238,18 +207,20 @@ void RootSignature::InitImmutableSampler(SHADER_TYPE ShaderT } } + // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout#Initializing-Shader-Resource-Layouts-and-Root-Signature-in-a-Pipeline-State-Object -void RootSignature::AllocateResourceSlot(SHADER_TYPE ShaderType, - PIPELINE_TYPE PipelineType, - const D3DShaderResourceAttribs& ShaderResAttribs, - SHADER_RESOURCE_VARIABLE_TYPE VariableType, - D3D12_DESCRIPTOR_RANGE_TYPE RangeType, - Uint32& BindPoint, // in/out parameter - Uint32& RootIndex, // Output parameter - Uint32& OffsetFromTableStart // Output parameter +void RootSignatureBuilder::AllocateResourceSlot(SHADER_TYPE ShaderType, + PIPELINE_TYPE PipelineType, + const D3DShaderResourceAttribs& ShaderResAttribs, + SHADER_RESOURCE_VARIABLE_TYPE VariableType, + D3D12_DESCRIPTOR_RANGE_TYPE RangeType, + Uint32& BindPoint, // in/out parameter + Uint32& RootIndex, // Output parameter + Uint32& OffsetFromTableStart // Output parameter ) { const auto ShaderVisibility = ShaderTypeToD3D12ShaderVisibility(ShaderType); + auto& RootParams = m_RootSig.m_RootParams; // update resource binding for ray tracing if (ShaderType & RayTracingMask) @@ -265,11 +236,11 @@ void RootSignature::AllocateResourceSlot(SHADER_TYPE ShaderT // Allocate single CBV directly in the root signature // Get the next available root index past all allocated tables and root views - RootIndex = m_RootParams.GetNumRootTables() + m_RootParams.GetNumRootViews(); + RootIndex = RootParams.GetNumRootTables() + RootParams.GetNumRootViews(); OffsetFromTableStart = 0; // Add new root view to existing root parameters - m_RootParams.AddRootView(D3D12_ROOT_PARAMETER_TYPE_CBV, RootIndex, BindPoint, ShaderVisibility, VariableType); + RootParams.AddRootView(D3D12_ROOT_PARAMETER_TYPE_CBV, RootIndex, BindPoint, ShaderVisibility, VariableType); } else { @@ -278,26 +249,26 @@ void RootSignature::AllocateResourceSlot(SHADER_TYPE ShaderT const auto RootTableType = (VariableType == SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) ? SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC : SHADER_RESOURCE_VARIABLE_TYPE_STATIC; const auto TableIndKey = ShaderInd * SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES + RootTableType; // Get the table array index (this is not the root index!) - auto& RootTableArrayInd = ((RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER) ? m_SamplerRootTablesMap : m_SrvCbvUavRootTablesMap)[TableIndKey]; - if (RootTableArrayInd == InvalidRootTableIndex) + auto& RootTableArrayInd = ((RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER) ? m_RootSig.m_SamplerRootTablesMap : m_RootSig.m_SrvCbvUavRootTablesMap)[TableIndKey]; + if (RootTableArrayInd == RootSignature::InvalidRootTableIndex) { // Root table has not been assigned to this combination yet // Get the next available root index past all allocated tables and root views - RootIndex = m_RootParams.GetNumRootTables() + m_RootParams.GetNumRootViews(); - VERIFY_EXPR(m_RootParams.GetNumRootTables() < 255); - RootTableArrayInd = static_cast<Uint8>(m_RootParams.GetNumRootTables()); + RootIndex = RootParams.GetNumRootTables() + RootParams.GetNumRootViews(); + VERIFY_EXPR(RootParams.GetNumRootTables() < 255); + RootTableArrayInd = static_cast<Uint8>(RootParams.GetNumRootTables()); // Add root table with one single-descriptor range - m_RootParams.AddRootTable(RootIndex, ShaderVisibility, RootTableType, 1); + RootParams.AddRootTable(RootIndex, ShaderVisibility, RootTableType, 1); } else { // Add a new single-descriptor range to the existing table at index RootTableArrayInd - m_RootParams.AddDescriptorRanges(RootTableArrayInd, 1); + RootParams.AddDescriptorRanges(RootTableArrayInd, 1); } // Reference to either existing or just added table - auto& CurrParam = m_RootParams.GetRootTable(RootTableArrayInd); + auto& CurrParam = RootParams.GetRootTable(RootTableArrayInd); RootIndex = CurrParam.GetRootIndex(); const auto& d3d12RootParam = static_cast<const D3D12_ROOT_PARAMETER&>(CurrParam); @@ -321,73 +292,7 @@ void RootSignature::AllocateResourceSlot(SHADER_TYPE ShaderT } -#ifdef DILIGENT_DEBUG -void RootSignature::dbgVerifyRootParameters() const -{ - Uint32 dbgTotalSrvCbvUavSlots = 0; - Uint32 dbgTotalSamplerSlots = 0; - for (Uint32 rt = 0; rt < m_RootParams.GetNumRootTables(); ++rt) - { - auto& RootTable = m_RootParams.GetRootTable(rt); - auto& Param = static_cast<const D3D12_ROOT_PARAMETER&>(RootTable); - VERIFY(Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Root parameter is expected to be a descriptor table"); - auto& Table = Param.DescriptorTable; - VERIFY(Table.NumDescriptorRanges > 0, "Descriptor table is expected to be non-empty"); - VERIFY(Table.pDescriptorRanges[0].OffsetInDescriptorsFromTableStart == 0, "Descriptor table is expected to start at 0 offset"); - bool IsResourceTable = Table.pDescriptorRanges[0].RangeType != D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; - for (Uint32 r = 0; r < Table.NumDescriptorRanges; ++r) - { - const auto& range = Table.pDescriptorRanges[r]; - if (IsResourceTable) - { - // clang-format off - VERIFY(range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV || - range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV || - range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_UAV, - "Resource type is expected to be SRV, CBV or UAV"); - // clang-format on - dbgTotalSrvCbvUavSlots += range.NumDescriptors; - } - else - { - VERIFY(range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, "Resource type is expected to be sampler"); - dbgTotalSamplerSlots += range.NumDescriptors; - } - - if (r > 0) - { - VERIFY(Table.pDescriptorRanges[r].OffsetInDescriptorsFromTableStart == Table.pDescriptorRanges[r - 1].OffsetInDescriptorsFromTableStart + Table.pDescriptorRanges[r - 1].NumDescriptors, "Ranges in a descriptor table are expected to be consequtive"); - } - } - } - - Uint32 dbgTotalRootViews = 0; - for (Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) - { - auto& RootView = m_RootParams.GetRootView(rv); - auto& Param = static_cast<const D3D12_ROOT_PARAMETER&>(RootView); - VERIFY(Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV, "Root parameter is expected to be a CBV"); - ++dbgTotalRootViews; - } - - // clang-format off - VERIFY(dbgTotalSrvCbvUavSlots == - m_TotalSrvCbvUavSlots[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + - m_TotalSrvCbvUavSlots[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + - m_TotalSrvCbvUavSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC], "Unexpected number of SRV CBV UAV resource slots"); - VERIFY(dbgTotalSamplerSlots == - m_TotalSamplerSlots[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + - m_TotalSamplerSlots[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + - m_TotalSamplerSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC], "Unexpected number of sampler slots"); - VERIFY(dbgTotalRootViews == - m_TotalRootViews[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + - m_TotalRootViews[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + - m_TotalRootViews[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC], "Unexpected number of root views"); - // clang-format on -} -#endif - -void RootSignature::AllocateImmutableSamplers(const PipelineResourceLayoutDesc& ResourceLayout) +void RootSignatureBuilder::AllocateImmutableSamplers(const PipelineResourceLayoutDesc& ResourceLayout) { if (ResourceLayout.NumImmutableSamplers > 0) { @@ -406,11 +311,18 @@ void RootSignature::AllocateImmutableSamplers(const PipelineResourceLayoutDesc& } } -void RootSignature::Finalize(ID3D12Device* pd3d12Device) + +void RootSignatureBuilder::Finalize(ID3D12Device* pd3d12Device) { - for (Uint32 rt = 0; rt < m_RootParams.GetNumRootTables(); ++rt) + auto& RootParams = m_RootSig.m_RootParams; + auto& TotalSamplerSlots = m_RootSig.m_TotalSamplerSlots; + auto& TotalSrvCbvUavSlots = m_RootSig.m_TotalSrvCbvUavSlots; + auto& TotalRootViews = m_RootSig.m_TotalRootViews; + auto& d3d12RootSignature = m_RootSig.m_pd3d12RootSignature; + + for (Uint32 rt = 0; rt < RootParams.GetNumRootTables(); ++rt) { - const auto& RootTbl = m_RootParams.GetRootTable(rt); + const auto& RootTbl = RootParams.GetRootTable(rt); const auto& d3d12RootParam = static_cast<const D3D12_ROOT_PARAMETER&>(RootTbl); VERIFY_EXPR(d3d12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE); @@ -418,13 +330,13 @@ void RootSignature::Finalize(ID3D12Device* pd3d12Device) VERIFY(d3d12RootParam.DescriptorTable.NumDescriptorRanges > 0 && TableSize > 0, "Unexpected empty descriptor table"); auto IsSamplerTable = d3d12RootParam.DescriptorTable.pDescriptorRanges[0].RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; auto VarType = RootTbl.GetShaderVariableType(); - (IsSamplerTable ? m_TotalSamplerSlots : m_TotalSrvCbvUavSlots)[VarType] += TableSize; + (IsSamplerTable ? TotalSamplerSlots : TotalSrvCbvUavSlots)[VarType] += TableSize; } - for (Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) + for (Uint32 rv = 0; rv < RootParams.GetNumRootViews(); ++rv) { - const auto& RootView = m_RootParams.GetRootView(rv); - ++m_TotalRootViews[RootView.GetShaderVariableType()]; + const auto& RootView = RootParams.GetRootView(rv); + ++TotalRootViews[RootView.GetShaderVariableType()]; } #ifdef DILIGENT_DEBUG @@ -434,19 +346,19 @@ void RootSignature::Finalize(ID3D12Device* pd3d12Device) D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc; rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; - auto TotalParams = m_RootParams.GetNumRootTables() + m_RootParams.GetNumRootViews(); + auto TotalParams = RootParams.GetNumRootTables() + RootParams.GetNumRootViews(); std::vector<D3D12_ROOT_PARAMETER, STDAllocatorRawMem<D3D12_ROOT_PARAMETER>> D3D12Parameters(TotalParams, D3D12_ROOT_PARAMETER{}, STD_ALLOCATOR_RAW_MEM(D3D12_ROOT_PARAMETER, GetRawAllocator(), "Allocator for vector<D3D12_ROOT_PARAMETER>")); - for (Uint32 rt = 0; rt < m_RootParams.GetNumRootTables(); ++rt) + for (Uint32 rt = 0; rt < RootParams.GetNumRootTables(); ++rt) { - const auto& RootTable = m_RootParams.GetRootTable(rt); + const auto& RootTable = RootParams.GetRootTable(rt); const D3D12_ROOT_PARAMETER& SrcParam = RootTable; VERIFY(SrcParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE && SrcParam.DescriptorTable.NumDescriptorRanges > 0, "Non-empty descriptor table is expected"); D3D12Parameters[RootTable.GetRootIndex()] = SrcParam; } - for (Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) + for (Uint32 rv = 0; rv < RootParams.GetNumRootViews(); ++rv) { - const auto& RootView = m_RootParams.GetRootView(rv); + const auto& RootView = RootParams.GetRootView(rv); const D3D12_ROOT_PARAMETER& SrcParam = RootView; VERIFY(SrcParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV, "Root CBV is expected"); D3D12Parameters[RootView.GetRootIndex()] = SrcParam; @@ -504,30 +416,144 @@ void RootSignature::Finalize(ID3D12Device* pd3d12Device) CComPtr<ID3DBlob> signature; CComPtr<ID3DBlob> error; HRESULT hr = D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error); + if (error) + { + LOG_ERROR_MESSAGE("Error: ", (const char*)error->GetBufferPointer()); + } CHECK_D3D_RESULT_THROW(hr, "Failed to serialize root signature"); - hr = pd3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), __uuidof(m_pd3d12RootSignature), reinterpret_cast<void**>(static_cast<ID3D12RootSignature**>(&m_pd3d12RootSignature))); + hr = pd3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), __uuidof(d3d12RootSignature), reinterpret_cast<void**>(static_cast<ID3D12RootSignature**>(&d3d12RootSignature))); CHECK_D3D_RESULT_THROW(hr, "Failed to create root signature"); - bool bHasDynamicDescriptors = m_TotalSrvCbvUavSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] != 0 || m_TotalSamplerSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] != 0; + bool bHasDynamicDescriptors = TotalSrvCbvUavSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] != 0 || TotalSamplerSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] != 0; if (bHasDynamicDescriptors) { - CommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SMD<false>; - TransitionAndCommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SMD<true>; + m_RootSig.CommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SMD<false>; + m_RootSig.TransitionAndCommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SMD<true>; } else { - CommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SM<false>; - TransitionAndCommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SM<true>; + m_RootSig.CommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SM<false>; + m_RootSig.TransitionAndCommitDescriptorHandles = &RootSignature::CommitDescriptorHandlesInternal_SM<true>; } } -size_t RootSignature::GetResourceCacheRequiredMemSize() const + +#ifdef DILIGENT_DEBUG +void RootSignatureBuilder::dbgVerifyRootParameters() const { - auto CacheTableSizes = GetCacheTableSizes(); + auto& RootParams = m_RootSig.m_RootParams; + auto& TotalSamplerSlots = m_RootSig.m_TotalSamplerSlots; + auto& TotalSrvCbvUavSlots = m_RootSig.m_TotalSrvCbvUavSlots; + auto& TotalRootViews = m_RootSig.m_TotalRootViews; + + Uint32 dbgTotalSrvCbvUavSlots = 0; + Uint32 dbgTotalSamplerSlots = 0; + for (Uint32 rt = 0; rt < RootParams.GetNumRootTables(); ++rt) + { + auto& RootTable = RootParams.GetRootTable(rt); + auto& Param = static_cast<const D3D12_ROOT_PARAMETER&>(RootTable); + VERIFY(Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Root parameter is expected to be a descriptor table"); + auto& Table = Param.DescriptorTable; + VERIFY(Table.NumDescriptorRanges > 0, "Descriptor table is expected to be non-empty"); + VERIFY(Table.pDescriptorRanges[0].OffsetInDescriptorsFromTableStart == 0, "Descriptor table is expected to start at 0 offset"); + bool IsResourceTable = Table.pDescriptorRanges[0].RangeType != D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + for (Uint32 r = 0; r < Table.NumDescriptorRanges; ++r) + { + const auto& range = Table.pDescriptorRanges[r]; + if (IsResourceTable) + { + // clang-format off + VERIFY(range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV || + range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV || + range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_UAV, + "Resource type is expected to be SRV, CBV or UAV"); + // clang-format on + dbgTotalSrvCbvUavSlots += range.NumDescriptors; + } + else + { + VERIFY(range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, "Resource type is expected to be sampler"); + dbgTotalSamplerSlots += range.NumDescriptors; + } + + if (r > 0) + { + VERIFY(Table.pDescriptorRanges[r].OffsetInDescriptorsFromTableStart == Table.pDescriptorRanges[r - 1].OffsetInDescriptorsFromTableStart + Table.pDescriptorRanges[r - 1].NumDescriptors, "Ranges in a descriptor table are expected to be consequtive"); + } + } + } + + Uint32 dbgTotalRootViews = 0; + for (Uint32 rv = 0; rv < RootParams.GetNumRootViews(); ++rv) + { + auto& RootView = RootParams.GetRootView(rv); + auto& Param = static_cast<const D3D12_ROOT_PARAMETER&>(RootView); + VERIFY(Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV, "Root parameter is expected to be a CBV"); + ++dbgTotalRootViews; + } + + // clang-format off + VERIFY(dbgTotalSrvCbvUavSlots == + TotalSrvCbvUavSlots[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + + TotalSrvCbvUavSlots[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + + TotalSrvCbvUavSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC], "Unexpected number of SRV CBV UAV resource slots"); + VERIFY(dbgTotalSamplerSlots == + TotalSamplerSlots[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + + TotalSamplerSlots[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + + TotalSamplerSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC], "Unexpected number of sampler slots"); + VERIFY(dbgTotalRootViews == + TotalRootViews[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + + TotalRootViews[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + + TotalRootViews[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC], "Unexpected number of root views"); + // clang-format on +} +#endif + +size_t RootSignatureBuilder::GetResourceCacheRequiredMemSize() const +{ + auto CacheTableSizes = m_RootSig.GetCacheTableSizes(); return ShaderResourceCacheD3D12::GetRequiredMemorySize(static_cast<Uint32>(CacheTableSizes.size()), CacheTableSizes.data()); } + +RootSignature::RootSignature() : + m_RootParams{GetRawAllocator()}, + m_MemAllocator{GetRawAllocator()} +{ + m_SrvCbvUavRootTablesMap.fill(InvalidRootTableIndex); + m_SamplerRootTablesMap.fill(InvalidRootTableIndex); +} + +// clang-format off +static D3D12_DESCRIPTOR_HEAP_TYPE RangeType2HeapTypeMap[] +{ + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, //D3D12_DESCRIPTOR_RANGE_TYPE_SRV = 0 + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, //D3D12_DESCRIPTOR_RANGE_TYPE_UAV = ( D3D12_DESCRIPTOR_RANGE_TYPE_SRV + 1 ) + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, //D3D12_DESCRIPTOR_RANGE_TYPE_CBV = ( D3D12_DESCRIPTOR_RANGE_TYPE_UAV + 1 ) + D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER //D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER = ( D3D12_DESCRIPTOR_RANGE_TYPE_CBV + 1 ) +}; +// clang-format on +D3D12_DESCRIPTOR_HEAP_TYPE HeapTypeFromRangeType(D3D12_DESCRIPTOR_RANGE_TYPE RangeType) +{ + VERIFY_EXPR(RangeType >= D3D12_DESCRIPTOR_RANGE_TYPE_SRV && RangeType <= D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER); + auto HeapType = RangeType2HeapTypeMap[RangeType]; + +#ifdef DILIGENT_DEBUG + switch (RangeType) + { + // clang-format off + case D3D12_DESCRIPTOR_RANGE_TYPE_CBV: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); break; + case D3D12_DESCRIPTOR_RANGE_TYPE_SRV: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); break; + case D3D12_DESCRIPTOR_RANGE_TYPE_UAV: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); break; + case D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER: VERIFY_EXPR(HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); break; + // clang-format on + default: UNEXPECTED("Unexpected descriptor range type"); break; + } +#endif + return HeapType; +} + std::vector<Uint32, STDAllocatorRawMem<Uint32>> RootSignature::GetCacheTableSizes() const { // Get root table size for every root index diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index f5b4e806..771e2c23 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -139,7 +139,7 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* const SHADER_RESOURCE_VARIABLE_TYPE* const AllowedVarTypes, Uint32 NumAllowedTypes, ShaderResourceCacheD3D12* pResourceCache, - RootSignature* pRootSig, + RootSignatureBuilder* pRootSig, LocalRootSignature* pLocalRootSig) { m_pd3d12Device = pd3d12Device; |
