diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2021-02-24 03:39:00 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2021-03-19 00:38:10 +0000 |
| commit | 8813773d1df679d1a747a91e6be7afcdaa5b42c7 (patch) | |
| tree | 9371c6756d6265dcce359535447eb8a4c8a148d9 /Graphics/GraphicsEngine | |
| parent | Improved paramter packing for CommitRootTables and CommitRootViews methods of... (diff) | |
| download | DiligentCore-8813773d1df679d1a747a91e6be7afcdaa5b42c7.tar.gz DiligentCore-8813773d1df679d1a747a91e6be7afcdaa5b42c7.zip | |
Reworked ShaderResourceBindingVkImpl and ShaderResourceBindingD3D12Impl: moved common functionality to ShaderResourceBindingBase
Diffstat (limited to 'Graphics/GraphicsEngine')
| -rw-r--r-- | Graphics/GraphicsEngine/include/ShaderResourceBindingBase.hpp | 152 |
1 files changed, 116 insertions, 36 deletions
diff --git a/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.hpp b/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.hpp index 058e3c86..8282fa40 100644 --- a/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.hpp +++ b/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.hpp @@ -60,11 +60,22 @@ public: /// \param pPRS - Pipeline resource signature that this SRB belongs to. /// \param IsInternal - Flag indicating if the shader resource binding is an internal object and /// must not keep a strong reference to the pipeline resource signature. - ShaderResourceBindingBase(IReferenceCounters* pRefCounters, ResourceSignatureType* pPRS, bool IsInternal = false) : + ShaderResourceBindingBase(IReferenceCounters* pRefCounters, ResourceSignatureType* pPRS) : TObjectBase{pRefCounters}, - m_spPRS{IsInternal ? nullptr : pPRS}, m_pPRS{pPRS} - {} + { + m_ActiveShaderStageIndex.fill(-1); + + const auto NumShaders = GetNumShaders(); + const auto PipelineType = GetPipelineType(); + for (Uint32 s = 0; s < NumShaders; ++s) + { + const auto ShaderType = pPRS->GetActiveShaderStageType(s); + const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, PipelineType); + + m_ActiveShaderStageIndex[ShaderInd] = static_cast<Int8>(s); + } + } IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_ShaderResourceBinding, TObjectBase) @@ -75,7 +86,12 @@ public: PIPELINE_TYPE GetPipelineType() const { - return ValidatedCast<ResourceSignatureType>(m_pPRS)->GetPipelineType(); + return m_pPRS->GetPipelineType(); + } + + Uint32 GetNumShaders() const + { + return m_pPRS->GetNumActiveShaderStages(); } /// Implementation of IShaderResourceBinding::GetPipelineResourceSignature(). @@ -84,82 +100,146 @@ public: return m_pPRS; } + virtual void DILIGENT_CALL_TYPE InitializeStaticResources(const IPipelineState* pPipelineState) override + { + if (StaticResourcesInitialized()) + { + LOG_WARNING_MESSAGE("Static resources have already been initialized in this shader resource binding object. The operation will be ignored."); + return; + } + + const IPipelineResourceSignature* pResourceSignature = nullptr; + if (pPipelineState != nullptr) + { + pResourceSignature = pPipelineState->GetResourceSignature(GetBindingIndex()); + if (pResourceSignature == nullptr) + { + LOG_ERROR_MESSAGE("Shader resource binding is not compatible with pipeline state."); + return; + } + +#ifdef DILIGENT_DEVELOPMENT + if (!pResourceSignature->IsCompatibleWith(GetSignature())) + { + LOG_ERROR_MESSAGE("Shader resource binding is not compatible with pipeline state."); + return; + } +#endif + } + + InitializeStaticResourcesWithSignature(pResourceSignature); + } + ResourceSignatureType* GetSignature() const { - return ValidatedCast<ResourceSignatureType>(m_pPRS); + return m_pPRS.RawPtr<ResourceSignatureType>(); + } + + bool StaticResourcesInitialized() const + { + return m_bStaticResourcesInitialized; } protected: - Int8 GetVariableByNameHelper(SHADER_TYPE ShaderType, const char* Name, const std::array<Int8, MAX_SHADERS_IN_PIPELINE>& ResourceLayoutIndex) const + template <typename ShaderVarManagerType> + IShaderResourceVariable* GetVariableByNameImpl(SHADER_TYPE ShaderType, + const char* Name, + const ShaderVarManagerType ShaderVarMgrs[]) const { const auto PipelineType = GetPipelineType(); if (!IsConsistentShaderType(ShaderType, PipelineType)) { LOG_WARNING_MESSAGE("Unable to find mutable/dynamic variable '", Name, "' in shader stage ", GetShaderTypeLiteralName(ShaderType), " as the stage is invalid for ", GetPipelineTypeString(PipelineType), " pipeline resource signature '", m_pPRS->GetDesc().Name, "'."); - return -1; + return nullptr; } - const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, PipelineType); - const auto ResLayoutInd = ResourceLayoutIndex[ShaderInd]; - if (ResLayoutInd < 0) - { - LOG_WARNING_MESSAGE("Unable to find mutable/dynamic variable '", Name, "' in shader stage ", GetShaderTypeLiteralName(ShaderType), - " as the stage is inactive in pipeline resource signature '", m_pPRS->GetDesc().Name, "'."); - } + const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, PipelineType); + const auto MgrInd = m_ActiveShaderStageIndex[ShaderInd]; + if (MgrInd < 0) + return nullptr; - return ResLayoutInd; + VERIFY_EXPR(static_cast<Uint32>(MgrInd) < GetNumShaders()); + return ShaderVarMgrs[MgrInd].GetVariable(Name); } - Int8 GetVariableCountHelper(SHADER_TYPE ShaderType, const std::array<Int8, MAX_SHADERS_IN_PIPELINE>& ResourceLayoutIndex) const + template <typename ShaderVarManagerType> + Uint32 GetVariableCountImpl(SHADER_TYPE ShaderType, const ShaderVarManagerType ShaderVarMgrs[]) const { const auto PipelineType = GetPipelineType(); if (!IsConsistentShaderType(ShaderType, PipelineType)) { LOG_WARNING_MESSAGE("Unable to get the number of mutable/dynamic variables in shader stage ", GetShaderTypeLiteralName(ShaderType), " as the stage is invalid for ", GetPipelineTypeString(PipelineType), " pipeline resource signature '", m_pPRS->GetDesc().Name, "'."); - return -1; + return 0; } - const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, PipelineType); - const auto ResLayoutInd = ResourceLayoutIndex[ShaderInd]; - if (ResLayoutInd < 0) - { - LOG_WARNING_MESSAGE("Unable to get the number of mutable/dynamic variables in shader stage ", GetShaderTypeLiteralName(ShaderType), - " as the stage is inactive in pipeline resource signature '", m_pPRS->GetDesc().Name, "'."); - } + const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, PipelineType); + const auto MgrInd = m_ActiveShaderStageIndex[ShaderInd]; + if (MgrInd < 0) + return 0; - return ResLayoutInd; + VERIFY_EXPR(static_cast<Uint32>(MgrInd) < GetNumShaders()); + return ShaderVarMgrs[MgrInd].GetVariableCount(); } - Int8 GetVariableByIndexHelper(SHADER_TYPE ShaderType, Uint32 Index, const std::array<Int8, MAX_SHADERS_IN_PIPELINE>& ResourceLayoutIndex) const + template <typename ShaderVarManagerType> + IShaderResourceVariable* GetVariableByIndexImpl(SHADER_TYPE ShaderType, + Uint32 Index, + const ShaderVarManagerType ShaderVarMgrs[]) const + { const auto PipelineType = GetPipelineType(); if (!IsConsistentShaderType(ShaderType, PipelineType)) { LOG_WARNING_MESSAGE("Unable to get mutable/dynamic variable at index ", Index, " in shader stage ", GetShaderTypeLiteralName(ShaderType), " as the stage is invalid for ", GetPipelineTypeString(PipelineType), " pipeline resource signature '", m_pPRS->GetDesc().Name, "'."); - return -1; + return nullptr; } - const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, PipelineType); - const auto ResLayoutInd = ResourceLayoutIndex[ShaderInd]; - if (ResLayoutInd < 0) + const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, PipelineType); + const auto MgrInd = m_ActiveShaderStageIndex[ShaderInd]; + if (MgrInd < 0) + return nullptr; + + VERIFY_EXPR(static_cast<Uint32>(MgrInd) < GetNumShaders()); + return ShaderVarMgrs[MgrInd].GetVariable(Index); + } + + template <typename ShaderVarManagerType> + void BindResourcesImpl(Uint32 ShaderFlags, + IResourceMapping* pResMapping, + Uint32 Flags, + ShaderVarManagerType ShaderVarMgrs[]) const + { + const auto PipelineType = GetPipelineType(); + for (Int32 ShaderInd = 0; ShaderInd < static_cast<Int32>(m_ActiveShaderStageIndex.size()); ++ShaderInd) { - LOG_WARNING_MESSAGE("Unable to get mutable/dynamic variable at index ", Index, " in shader stage ", GetShaderTypeLiteralName(ShaderType), - " as the stage is inactive in pipeline resource signature '", m_pPRS->GetDesc().Name, "'."); + auto VarMngrInd = m_ActiveShaderStageIndex[ShaderInd]; + if (VarMngrInd >= 0) + { + // ShaderInd is the shader type pipeline index here + const auto ShaderType = GetShaderTypeFromPipelineIndex(ShaderInd, PipelineType); + if ((ShaderFlags & ShaderType) != 0) + { + ShaderVarMgrs[VarMngrInd].BindResources(pResMapping, Flags); + } + } } - - return ResLayoutInd; } protected: /// Strong reference to pipeline resource signature. We must use strong reference, because /// shader resource binding uses pipeline resource signature's memory allocator to allocate /// memory for shader resource cache. - RefCntAutoPtr<ResourceSignatureType> m_spPRS; + RefCntAutoPtr<ResourceSignatureType> m_pPRS; + + // Index of the active shader stage that has resources, for every shader + // type in the pipeline (given by GetShaderTypePipelineIndex(ShaderType, m_PipelineType)). + std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ActiveShaderStageIndex = {-1, -1, -1, -1, -1, -1}; + static_assert(MAX_SHADERS_IN_PIPELINE == 6, "Please update the initializer list above"); - IPipelineResourceSignature* m_pPRS = nullptr; + bool m_bStaticResourcesInitialized = false; }; } // namespace Diligent |
