From 683b1a498da93e33b7a159164525465909c00e99 Mon Sep 17 00:00:00 2001 From: assiduous Date: Thu, 25 Feb 2021 17:26:03 -0800 Subject: Reworked PSO intialization to allow shader resources be combined when defined through Desc.ResourceLayout --- .../src/PipelineStateD3D12Impl.cpp | 112 +++++++++------------ 1 file changed, 48 insertions(+), 64 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 959c6793..dae0165a 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -29,6 +29,8 @@ #include #include +#include +#include #include #ifdef FindResource @@ -417,46 +419,73 @@ RefCntAutoPtr PipelineStateD3D12Impl::CreateDefaultR struct UniqueResource { const D3DShaderResourceAttribs& Attribs; + const SHADER_TYPE ShaderStages; - // Resource index - const Uint32 DescIndex; + bool operator==(const UniqueResource& Res) const + { + return strcmp(Attribs.Name, Res.Attribs.Name) == 0 && ShaderStages == Res.ShaderStages; + } + + struct Hasher + { + size_t operator()(const UniqueResource& Res) const + { + return ComputeHash(CStringHash{}(Res.Attribs.Name), Uint32{Res.ShaderStages}); + } + }; }; - std::unordered_map UniqueNames; + std::unordered_set UniqueResources; std::vector Resources; const char* pCombinedSamplerSuffix = nullptr; for (auto& Stage : ShaderStages) { - UniqueNames.clear(); for (auto* pShader : Stage.Shaders) { const auto& ShaderResources = *pShader->GetShaderResources(); ShaderResources.ProcessResources( - [&](const D3DShaderResourceAttribs& Res, Uint32) // + [&](const D3DShaderResourceAttribs& Attribs, Uint32) // { - if (pLocalRootSig != nullptr && pLocalRootSig->IsShaderRecord(Res)) + if (pLocalRootSig != nullptr && pLocalRootSig->IsShaderRecord(Attribs)) return; - auto IterAndAssigned = UniqueNames.emplace(HashMapStringKey{Res.Name}, UniqueResource{Res, static_cast(Resources.size())}); + const char* const SamplerSuffix = + (ShaderResources.IsUsingCombinedTextureSamplers() && Attribs.GetInputType() == D3D_SIT_SAMPLER) ? + ShaderResources.GetCombinedSamplerSuffix() : + nullptr; + + auto ShaderStages = Stage.Type; + auto VarType = LayoutDesc.DefaultVariableType; + + const auto VarIndex = FindPipelineResourceLayoutVariable(LayoutDesc, Attribs.Name, Stage.Type, SamplerSuffix); + if (VarIndex != InvalidPipelineResourceLayoutVariableIndex) + { + const auto& Var = LayoutDesc.Variables[VarIndex]; + + ShaderStages = Var.ShaderStages; + VarType = Var.Type; + } + + auto IterAndAssigned = UniqueResources.emplace(UniqueResource{Attribs, ShaderStages}); if (IterAndAssigned.second) { - SHADER_RESOURCE_TYPE Type; - PIPELINE_RESOURCE_FLAGS Flags; - GetShaderResourceTypeAndFlags(Res, Type, Flags); + SHADER_RESOURCE_TYPE ResType = SHADER_RESOURCE_TYPE_UNKNOWN; + PIPELINE_RESOURCE_FLAGS Flags = PIPELINE_RESOURCE_FLAG_UNKNOWN; + GetShaderResourceTypeAndFlags(Attribs, ResType, Flags); - if (Res.BindCount == 0) + if (Attribs.BindCount == 0) { - LOG_ERROR_AND_THROW("Resource '", Res.Name, "' in shader '", pShader->GetDesc().Name, "' is a runtime-sized array. ", + LOG_ERROR_AND_THROW("Resource '", Attribs.Name, "' in shader '", pShader->GetDesc().Name, "' is a runtime-sized array. ", "Use explicit resource signature to specify the array size."); } - Resources.emplace_back(Stage.Type, Res.Name, Res.BindCount, Type, LayoutDesc.DefaultVariableType, Flags); + Resources.emplace_back(ShaderStages, Attribs.Name, Attribs.BindCount, ResType, VarType, Flags); } else { - VerifyResourceMerge(IterAndAssigned.first->second.Attribs, Res); + VerifyResourceMerge(IterAndAssigned.first->Attribs, Attribs); } } // ); @@ -474,29 +503,6 @@ RefCntAutoPtr PipelineStateD3D12Impl::CreateDefaultR pCombinedSamplerSuffix = ShaderResources.GetCombinedSamplerSuffix(); } } - - for (Uint32 i = 0; i < LayoutDesc.NumVariables; ++i) - { - const auto& Var = LayoutDesc.Variables[i]; - if (Var.ShaderStages & Stage.Type) - { - auto Iter = UniqueNames.find(HashMapStringKey{Var.Name}); - if (Iter != UniqueNames.end()) - { - auto& Res = Resources[Iter->second.DescIndex]; - Res.VarType = Var.Type; - - // apply new variable type to sampler too - if (ShaderResources.IsUsingCombinedTextureSamplers() && Res.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV) - { - auto SampName = String{Var.Name} + ShaderResources.GetCombinedSamplerSuffix(); - auto SampIter = UniqueNames.find(HashMapStringKey{SampName.c_str()}); - if (SampIter != UniqueNames.end()) - Resources[SampIter->second.DescIndex].VarType = Var.Type; - } - } - } - } } } @@ -550,33 +556,11 @@ void PipelineStateD3D12Impl::InitRootSignature(const PipelineStateCreateInfo& Cr SignatureCount = MaxSignatureBindingIndex + 1; m_ResourceSignatures.reset(new RefCntAutoPtr[SignatureCount]); - // TODO: move to base class - const auto PipelineType = CreateInfo.PSODesc.PipelineType; - for (Uint32 i = 0; i < CreateInfo.ResourceSignaturesCount; ++i) - { - auto* pSignature = ValidatedCast(CreateInfo.ppResourceSignatures[i]); - VERIFY(pSignature != nullptr, "Pipeline resource signature at index ", i, " is null. This error should've been caught by ValidatePipelineResourceSignatures."); - - const auto Index = pSignature->GetDesc().BindingIndex; - -#ifdef DILIGENT_DEBUG - VERIFY(m_ResourceSignatures[Index] == nullptr, - "Pipeline resource signature '", pSignature->GetDesc().Name, "' at index ", Uint32{Index}, - " conflicts with another resource signature '", m_ResourceSignatures[Index]->GetDesc().Name, - "' that uses the same index. This error should've been caught by ValidatePipelineResourceSignatures."); - - for (Uint32 s = 0, StageCount = pSignature->GetNumActiveShaderStages(); s < StageCount; ++s) - { - const auto ShaderType = pSignature->GetActiveShaderStageType(s); - VERIFY(IsConsistentShaderType(ShaderType, PipelineType), - "Pipeline resource signature '", pSignature->GetDesc().Name, "' at index ", Uint32{Index}, - " has shader stage '", GetShaderTypeLiteralName(ShaderType), "' that is not compatible with pipeline type '", - GetPipelineTypeString(PipelineType), "'."); - } -#endif - - m_ResourceSignatures[Index] = pSignature; - } + Uint8 DbgSignatureCount = 0; + PipelineResourceSignatureD3D12Impl::CopyResourceSignatures(CreateInfo.PSODesc.PipelineType, CreateInfo.ResourceSignaturesCount, + CreateInfo.ppResourceSignatures, m_ResourceSignatures.get(), SignatureCount, + DbgSignatureCount); + VERIFY_EXPR(DbgSignatureCount == SignatureCount); } m_RootSig = GetDevice()->GetRootSignatureCache().GetRootSig(m_ResourceSignatures.get(), SignatureCount); -- cgit v1.2.3