From 259c5701953e05cbd3ea13ab40f0e66a893bc8e9 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Fri, 12 Feb 2021 23:56:18 +0300 Subject: bug fixes for dx12 resource signature --- .../include/PipelineResourceSignatureD3D12Impl.hpp | 23 ++++++-- .../GraphicsEngineD3D12/include/RootSignature.hpp | 8 ++- .../include/ShaderVariableD3D12.hpp | 11 +++- .../src/DeviceContextD3D12Impl.cpp | 6 +- .../src/PipelineResourceSignatureD3D12Impl.cpp | 29 +++++----- .../src/PipelineStateD3D12Impl.cpp | 64 +++++++++++++++++---- Graphics/GraphicsEngineD3D12/src/RootSignature.cpp | 14 +++-- .../src/ShaderVariableD3D12.cpp | 67 +++++++++++----------- 8 files changed, 142 insertions(+), 80 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineResourceSignatureD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineResourceSignatureD3D12Impl.hpp index 2ed29d20..fa076b35 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineResourceSignatureD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/PipelineResourceSignatureD3D12Impl.hpp @@ -53,6 +53,8 @@ class PipelineResourceSignatureD3D12Impl final : public PipelineResourceSignatur public: using TPipelineResourceSignatureBase = PipelineResourceSignatureBase; + static constexpr Uint32 MAX_SPACES_PER_SIGNATURE = 128; + PipelineResourceSignatureD3D12Impl(IReferenceCounters* pRefCounters, RenderDeviceD3D12Impl* pDevice, const PipelineResourceSignatureDesc& Desc, @@ -91,7 +93,7 @@ public: /* 0 */const Uint32 Register : _RegisterBits; // Shader register /* 2 */const Uint32 SRBRootIndex : _SRBRootIndexBits; // Root view/table index in the SRB /* 4 */const Uint32 SamplerInd : _SamplerIndBits; // Index in m_Desc.Resources and m_pResourceAttribs -/* 6 */const Uint32 Space : _SpaceBits; // Shader register space +/* 6 */const Uint32 Space : _SpaceBits; // Shader register space (local space in range 0..MAX_SPACES_PER_SIGNATURE) /* 7.0*/const Uint32 SigRootIndex : _SigRootIndexBits; // Root table index for signature (static only) /* 7.3*/const Uint32 ImtblSamplerAssigned : _SamplerAssignedBits; // Immutable sampler flag /* 7.4*/const Uint32 IsRootView : _RootViewFlagBits; // Is root view (for debugging) @@ -150,15 +152,15 @@ public: struct ImmutableSamplerAttribs { private: - static constexpr Uint32 _ShaderRegisterBits = 16; - static constexpr Uint32 _RegisterSpaceBits = 16; + static constexpr Uint32 _ShaderRegisterBits = 24; + static constexpr Uint32 _RegisterSpaceBits = 8; static constexpr Uint32 _InvalidShaderRegister = (1u << _ShaderRegisterBits) - 1; static constexpr Uint32 _InvalidRegisterSpace = (1u << _RegisterSpaceBits) - 1; public: Uint32 ArraySize = 1; Uint32 ShaderRegister : _ShaderRegisterBits; - Uint32 RegisterSpace : _RegisterSpaceBits; + Uint32 RegisterSpace : _RegisterSpaceBits; // (local space in range 0..MAX_SPACES_PER_SIGNATURE) ImmutableSamplerAttribs() : ShaderRegister{_InvalidShaderRegister}, @@ -198,6 +200,16 @@ public: return m_RootParams.GetNumRootTables() + m_RootParams.GetNumRootViews(); } + Uint32 GetNumRootTables() const + { + return m_RootParams.GetNumRootTables(); + } + + Uint32 GetNumRootViews() const + { + return m_RootParams.GetNumRootViews(); + } + Uint32 GetBaseRegisterSpace() const { return m_Desc.BindingIndex * MAX_SPACES_PER_SIGNATURE; @@ -295,8 +307,7 @@ private: Uint32 FindAssignedSampler(const PipelineResourceDesc& SepImg) const; private: - static constexpr Uint8 InvalidRootTableIndex = static_cast(-1); - static constexpr Uint32 MAX_SPACES_PER_SIGNATURE = 128; + static constexpr Uint8 InvalidRootTableIndex = static_cast(-1); ResourceAttribs* m_pResourceAttribs = nullptr; // [m_Desc.NumResources] diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp index d7391086..7e1817ea 100644 --- a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp @@ -107,11 +107,13 @@ public: ID3D12RootSignature* Create(ID3D12Device* pDevice); -private: - static constexpr Uint32 InvalidBindPoint = ~0u; + bool IsDefined() const { return m_ShaderRecordSize > 0 && m_pName != nullptr; } + const char* GetName() const { return m_pName; } + Uint32 GetRegisterSpace() const { return PipelineResourceSignatureD3D12Impl::MAX_SPACES_PER_SIGNATURE * MAX_RESOURCE_SIGNATURES; } + Uint32 GetShaderRegister() const { return 0; } +private: const char* m_pName = nullptr; - Uint32 m_BindPoint = InvalidBindPoint; const Uint32 m_ShaderRecordSize = 0; CComPtr m_pd3d12RootSignature; }; diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp index cacd8e49..00f27122 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp @@ -87,7 +87,7 @@ public: IMemoryAllocator& Allocator, const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, Uint32 NumAllowedTypes, - SHADER_TYPE ShaderType); + SHADER_TYPE ShaderStages); ~ShaderVariableManagerD3D12(); void Destroy(IMemoryAllocator& Allocator); @@ -100,7 +100,7 @@ public: static size_t GetRequiredMemorySize(const PipelineResourceSignatureD3D12Impl& Signature, const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, Uint32 NumAllowedTypes, - SHADER_TYPE ShaderType, + SHADER_TYPE ShaderStages, Uint32& NumVariables); Uint32 GetVariableCount() const { return m_NumVariables; } @@ -122,6 +122,13 @@ private: return m_pSignature->GetResourceAttribs(Index); } + template + static void ProcessSignatureResources(const PipelineResourceSignatureD3D12Impl& Signature, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + SHADER_TYPE ShaderStages, + HandlerType Handler); + private: PipelineResourceSignatureD3D12Impl const* m_pSignature = nullptr; diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 4dbfe323..58e3262f 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -307,7 +307,7 @@ void DeviceContextD3D12Impl::CommitRootTables(RootTableInfo& RootInfo) auto* pSignature = RootSig.GetSignature(s); auto* pSRB = RootInfo.SRBs[s]; - if (pSignature == nullptr) + if (pSignature == nullptr || pSignature->GetTotalResourceCount() == 0) continue; VERIFY_EXPR(pSRB != nullptr); @@ -315,7 +315,7 @@ void DeviceContextD3D12Impl::CommitRootTables(RootTableInfo& RootInfo) } } - if (!RootInfo.bRootViewsCommitted) + //if (!RootInfo.bRootViewsCommitted) { RootInfo.bRootViewsCommitted = true; @@ -324,7 +324,7 @@ void DeviceContextD3D12Impl::CommitRootTables(RootTableInfo& RootInfo) auto* pSignature = RootSig.GetSignature(s); auto* pSRB = RootInfo.SRBs[s]; - if (pSignature == nullptr) + if (pSignature == nullptr || pSignature->GetNumRootViews() == 0) continue; VERIFY_EXPR(pSRB != nullptr); diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp index 3081fb0c..6af3a899 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp @@ -359,6 +359,8 @@ void PipelineResourceSignatureD3D12Impl::CreateLayout() Register = ImmutableSampler.ShaderRegister; Space = ImmutableSampler.RegisterSpace; + VERIFY_EXPR(ResDesc.ArraySize == ImmutableSampler.ArraySize); + // Use previous bind point and decrease resource counter if (!IsRuntimeSizedArray) NumResources[DescriptorRangeType] -= ResDesc.ArraySize; @@ -392,7 +394,7 @@ void PipelineResourceSignatureD3D12Impl::CreateLayout() const auto DescriptorRangeType = ResourceTypeToD3D12DescriptorRangeType(SHADER_RESOURCE_TYPE_SAMPLER); - ImmutableSampler.RegisterSpace = FirstSpace; + ImmutableSampler.RegisterSpace = 0; ImmutableSampler.ShaderRegister = NumResources[DescriptorRangeType]; NumResources[DescriptorRangeType] += 1; } @@ -1256,13 +1258,13 @@ void PipelineResourceSignatureD3D12Impl::CommitRootTables(ShaderResourceCacheD3D else CmdCtx.GetCommandList()->SetGraphicsRootDescriptorTable(FirstRootIndex + RootInd, RootTableGPUDescriptorHandle); - ProcessCachedTableResources( - RootInd, D3D12Param, ResourceCache, dbgHeapType, - [&](UINT OffsetFromTableStart, - const D3D12_DESCRIPTOR_RANGE& range, - ShaderResourceCacheD3D12::Resource& Res) // - { - if (IsDynamicTable) + if (IsDynamicTable) + { + ProcessCachedTableResources( + RootInd, D3D12Param, ResourceCache, dbgHeapType, + [&](UINT OffsetFromTableStart, + const D3D12_DESCRIPTOR_RANGE& range, + ShaderResourceCacheD3D12::Resource& Res) // { if (IsResourceTable) { @@ -1298,16 +1300,14 @@ void PipelineResourceSignatureD3D12Impl::CommitRootTables(ShaderResourceCacheD3D ++DynamicSamplerTblOffset; } - } - } // - ); + }); // + } } // ); VERIFY_EXPR(DynamicCbvSrvUavTblOffset == NumDynamicCbvSrvUavDescriptors); VERIFY_EXPR(DynamicSamplerTblOffset == NumDynamicSamplerDescriptors); - for (Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) { auto& RootView = m_RootParams.GetRootView(rv); @@ -1686,8 +1686,9 @@ void BindResourceHelper::BindResource(IDeviceObject* pObj) const break; case SHADER_RESOURCE_TYPE_SAMPLER: - DEV_CHECK_ERR(Signature.IsUsingSeparateSamplers(), "Samplers should not be set directly when using combined texture samplers"); - CacheSampler(pObj); + //DEV_CHECK_ERR(Signature.IsUsingSeparateSamplers(), "Samplers should not be set directly when using combined texture samplers"); + if (Signature.IsUsingSeparateSamplers()) + CacheSampler(pObj); break; case SHADER_RESOURCE_TYPE_ACCEL_STRUCT: diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 0fc12cdf..e9515ea2 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -104,9 +104,11 @@ private: std::array m_Map; }; +template void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateInfo, std::vector& Subobjects, - DynamicLinearAllocator& TempPool) noexcept(false) + DynamicLinearAllocator& TempPool, + TShaderStages& ShaderStages) noexcept(false) { #define LOG_PSO_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of ray tracing PSO '", (CreateInfo.PSODesc.Name ? CreateInfo.PSODesc.Name : ""), "' is invalid: ", ##__VA_ARGS__) @@ -114,6 +116,17 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI std::unordered_map UniqueShaders; + std::array StagesPtr = {}; + std::array ShaderIndices = {}; + + // prepare + for (auto& Stage : ShaderStages) + { + const auto Idx = GetShaderTypePipelineIndex(Stage.Type, PIPELINE_TYPE_RAY_TRACING); + VERIFY_EXPR(StagesPtr[Idx] == nullptr); + StagesPtr[Idx] = &Stage; + } + const auto AddDxilLib = [&](IShader* pShader, const char* Name) -> LPCWSTR { if (pShader == nullptr) return nullptr; @@ -121,10 +134,18 @@ void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateI auto it_inserted = UniqueShaders.emplace(pShader, nullptr); if (it_inserted.second) { - auto& LibDesc = *TempPool.Construct(); - auto& ExportDesc = *TempPool.Construct(); - auto* pShaderD3D12 = ValidatedCast(pShader); - auto* pBlob = pShaderD3D12->GetShaderByteCode(); + const auto StageIdx = GetShaderTypePipelineIndex(pShader->GetDesc().ShaderType, PIPELINE_TYPE_RAY_TRACING); + const auto& Stage = *StagesPtr[StageIdx]; + auto& ShaderIndex = ShaderIndices[StageIdx]; + + // shaders must be in same order as in ExtractShaders() + VERIFY_EXPR(Stage.Shaders[ShaderIndex] == pShader); + + auto& LibDesc = *TempPool.Construct(); + auto& ExportDesc = *TempPool.Construct(); + const auto* pShaderD3D12 = ValidatedCast(pShader); + const auto& pBlob = Stage.ByteCodes[ShaderIndex]; + ++ShaderIndex; LibDesc.DXILLibrary.BytecodeLength = pBlob->GetBufferSize(); LibDesc.DXILLibrary.pShaderBytecode = pBlob->GetBufferPointer(); @@ -549,9 +570,10 @@ void PipelineStateD3D12Impl::InitRootSignature(const PipelineStateCreateInfo& Cr for (size_t s = 0; s < ShaderStages.size(); ++s) { - const auto& Shaders = ShaderStages[s].Shaders; - auto& ByteCodes = ShaderStages[s].ByteCodes; - const auto ShaderType = ShaderStages[s].Type; + const auto& Shaders = ShaderStages[s].Shaders; + auto& ByteCodes = ShaderStages[s].ByteCodes; + const auto ShaderType = ShaderStages[s].Type; + bool HasImtblSampArray = false; ResourceBinding::TMap ResourceMap; for (Uint32 Sig = 0, SigCount = GetSignatureCount(); Sig < SigCount; ++Sig) @@ -568,7 +590,7 @@ void PipelineStateD3D12Impl::InitRootSignature(const PipelineStateCreateInfo& Cr if (ResDesc.ShaderStages & ShaderType) { - auto IsUnique = ResourceMap.emplace(HashMapStringKey{ResDesc.Name}, ResourceBinding::BindInfo{Attribs.Register, Attribs.Space + FirstSpace}).second; + auto IsUnique = ResourceMap.emplace(HashMapStringKey{ResDesc.Name}, ResourceBinding::BindInfo{Attribs.Register, Attribs.Space + FirstSpace, ResDesc.ArraySize}).second; VERIFY(IsUnique, "resource name must be unique"); } } @@ -577,10 +599,12 @@ void PipelineStateD3D12Impl::InitRootSignature(const PipelineStateCreateInfo& Cr { const auto& ImtblSam = pSignature->GetImmutableSamplerDesc(samp); const auto& SampAttr = pSignature->GetImmutableSamplerAttribs(samp); - ResourceBinding::BindInfo BindInfo{SampAttr.ShaderRegister, SampAttr.RegisterSpace + FirstSpace}; + ResourceBinding::BindInfo BindInfo{SampAttr.ShaderRegister, SampAttr.RegisterSpace + FirstSpace, SampAttr.ArraySize}; if (ImtblSam.ShaderStages & ShaderType) { + HasImtblSampArray = HasImtblSampArray || (SampAttr.ArraySize > 1); + auto IsUnique = ResourceMap.emplace(HashMapStringKey{ImtblSam.SamplerOrTextureName}, BindInfo).second; if (!IsUnique && pSignature->IsUsingCombinedSamplers()) { @@ -594,7 +618,12 @@ void PipelineStateD3D12Impl::InitRootSignature(const PipelineStateCreateInfo& Cr } } - // AZ TODO: add local root signature to ResourceMap + if (pLocalRootSig != nullptr && pLocalRootSig->IsDefined()) + { + bool IsUnique = ResourceMap.emplace(HashMapStringKey{pLocalRootSig->GetName()}, ResourceBinding::BindInfo{pLocalRootSig->GetShaderRegister(), pLocalRootSig->GetRegisterSpace(), 1}).second; + if (!IsUnique) + LOG_ERROR_AND_THROW("Shader record constant buffer is already exist in resource signature"); + } for (size_t i = 0; i < Shaders.size(); ++i) { @@ -602,6 +631,17 @@ void PipelineStateD3D12Impl::InitRootSignature(const PipelineStateCreateInfo& Cr auto& pBytecode = ByteCodes[i]; CComPtr pBlob; + if (HasImtblSampArray) + { + Uint32 VerMajor, VerMinor; + pShader->GetShaderResources()->GetShaderModel(VerMajor, VerMinor); + + if ((VerMajor == 5 && VerMinor >= 1) || VerMajor >= 6) + { + LOG_ERROR_AND_THROW("One of resource signatures uses immutable sampler array that is not allowed in shader model 5.1 and above."); + } + } + if (IsDXILBytecode(pBytecode->GetBufferPointer(), pBytecode->GetBufferSize())) { if (!compiler) @@ -935,7 +975,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* DynamicLinearAllocator TempPool{GetRawAllocator(), 4 << 10}; std::vector Subobjects; - BuildRTPipelineDescription(CreateInfo, Subobjects, TempPool); + BuildRTPipelineDescription(CreateInfo, Subobjects, TempPool, ShaderStages); D3D12_GLOBAL_ROOT_SIGNATURE GlobalRoot = {m_RootSig->GetD3D12RootSignature()}; Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE, &GlobalRoot}); diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index e10ee9b3..830c7a31 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -112,11 +112,13 @@ void RootSignatureD3D12::Finalize() for (Uint32 sig = 0; sig < m_SignatureCount; ++sig) { - auto& pSignature = m_Signatures[sig]; - const auto FirstRootIndex = m_FirstRootIndex[sig]; + auto& pSignature = m_Signatures[sig]; if (pSignature != nullptr) { + const auto FirstRootIndex = m_FirstRootIndex[sig]; + const Uint32 FirstSpace = pSignature->GetBaseRegisterSpace(); + auto& RootParams = pSignature->m_RootParams; for (Uint32 rt = 0; rt < RootParams.GetNumRootTables(); ++rt) { @@ -162,7 +164,7 @@ void RootSignatureD3D12::Finalize() SamDesc.MinLOD, SamDesc.MaxLOD, SampAttr.ShaderRegister + ArrInd, - SampAttr.RegisterSpace, + SampAttr.RegisterSpace + FirstSpace, ShaderVisibility // } // ); @@ -220,7 +222,7 @@ bool LocalRootSignatureD3D12::IsShaderRecord(const D3DShaderResourceAttribs& CB) ID3D12RootSignature* LocalRootSignatureD3D12::Create(ID3D12Device* pDevice) { - if (m_ShaderRecordSize == 0 || m_BindPoint == InvalidBindPoint) + if (m_ShaderRecordSize == 0) return nullptr; VERIFY(m_pd3d12RootSignature == nullptr, "This root signature is already created"); @@ -231,8 +233,8 @@ ID3D12RootSignature* LocalRootSignatureD3D12::Create(ID3D12Device* pDevice) 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; + d3d12Params.Constants.RegisterSpace = GetRegisterSpace(); + d3d12Params.Constants.ShaderRegister = GetShaderRegister(); d3d12RootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE; d3d12RootSignatureDesc.NumParameters = 1; diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp index 53eb1f9b..fb71679d 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp @@ -34,13 +34,13 @@ namespace Diligent { -size_t ShaderVariableManagerD3D12::GetRequiredMemorySize(const PipelineResourceSignatureD3D12Impl& Signature, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - SHADER_TYPE ShaderType, - Uint32& NumVariables) +template +void ShaderVariableManagerD3D12::ProcessSignatureResources(const PipelineResourceSignatureD3D12Impl& Signature, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + SHADER_TYPE ShaderStages, + HandlerType Handler) { - NumVariables = 0; const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); const bool UsingSeparateSamplers = Signature.IsUsingSeparateSamplers(); @@ -51,19 +51,35 @@ size_t ShaderVariableManagerD3D12::GetRequiredMemorySize(const PipelineResourceS const auto ResIdxRange = Signature.GetResourceIndexRange(VarType); for (Uint32 r = ResIdxRange.first; r < ResIdxRange.second; ++r) { - const auto& Res = Signature.GetResourceDesc(r); + const auto& Res = Signature.GetResourceDesc(r); + const auto& Attr = Signature.GetResourceAttribs(r); VERIFY_EXPR(Res.VarType == VarType); - if (!(Res.ShaderStages & ShaderType)) + if (!(Res.ShaderStages & ShaderStages)) continue; - if (!UsingSeparateSamplers && Res.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER) + if (Res.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER && + (!UsingSeparateSamplers || Attr.IsImmutableSamplerAssigned())) continue; - ++NumVariables; + Handler(r); } } } +} + +size_t ShaderVariableManagerD3D12::GetRequiredMemorySize(const PipelineResourceSignatureD3D12Impl& Signature, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + SHADER_TYPE ShaderStages, + Uint32& NumVariables) +{ + NumVariables = 0; + ProcessSignatureResources(Signature, AllowedVarTypes, NumAllowedTypes, ShaderStages, + [&NumVariables](Uint32) // + { + ++NumVariables; + }); return NumVariables * sizeof(ShaderVariableD3D12Impl); } @@ -89,30 +105,13 @@ void ShaderVariableManagerD3D12::Initialize(const PipelineResourceSignatureD3D12 auto* pRawMem = ALLOCATE_RAW(Allocator, "Raw memory buffer for shader variables", MemSize); m_pVariables = reinterpret_cast(pRawMem); - Uint32 VarInd = 0; - const bool UsingSeparateSamplers = Signature.IsUsingSeparateSamplers(); - - for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType + 1)) - { - if (IsAllowedType(VarType, AllowedTypeBits)) - { - const auto ResIdxRange = Signature.GetResourceIndexRange(VarType); - for (Uint32 r = ResIdxRange.first; r < ResIdxRange.second; ++r) - { - const auto& Res = Signature.GetResourceDesc(r); - VERIFY_EXPR(Res.VarType == VarType); - - if (!(Res.ShaderStages & ShaderType)) - continue; - - if (!UsingSeparateSamplers && Res.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER) - continue; - - ::new (m_pVariables + VarInd) ShaderVariableD3D12Impl{*this, r}; - ++VarInd; - } - } - } + Uint32 VarInd = 0; + ProcessSignatureResources(Signature, AllowedVarTypes, NumAllowedTypes, ShaderType, + [this, &VarInd](Uint32 ResIndex) // + { + ::new (m_pVariables + VarInd) ShaderVariableD3D12Impl{*this, ResIndex}; + ++VarInd; + }); VERIFY_EXPR(VarInd == m_NumVariables); m_pSignature = &Signature; -- cgit v1.2.3