From cf7b7505e93c96e3b63d9dc9a775b994a1572fa8 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 21 Jan 2021 06:21:32 +0300 Subject: pipeline resource signature for vulkan --- .../include/PipelineResourceSignatureBase.hpp | 115 ++++++--------------- .../GraphicsEngine/include/PipelineStateBase.hpp | 58 +++++------ .../include/ShaderResourceBindingBase.hpp | 18 ---- .../interface/PipelineResourceSignature.h | 32 ++++-- Graphics/GraphicsEngine/interface/PipelineState.h | 6 +- Graphics/GraphicsEngine/interface/Shader.h | 2 + 6 files changed, 88 insertions(+), 143 deletions(-) (limited to 'Graphics/GraphicsEngine') diff --git a/Graphics/GraphicsEngine/include/PipelineResourceSignatureBase.hpp b/Graphics/GraphicsEngine/include/PipelineResourceSignatureBase.hpp index 5fcc5a1b..20b2b563 100644 --- a/Graphics/GraphicsEngine/include/PipelineResourceSignatureBase.hpp +++ b/Graphics/GraphicsEngine/include/PipelineResourceSignatureBase.hpp @@ -63,8 +63,9 @@ public: bool bIsDeviceInternal = false) : TDeviceObjectBase{pRefCounters, pDevice, Desc, bIsDeviceInternal} { - this->m_Desc.Resources = nullptr; - this->m_Desc.ImmutableSamplers = nullptr; + this->m_Desc.Resources = nullptr; + this->m_Desc.ImmutableSamplers = nullptr; + this->m_Desc.CombinedSamplerSuffix = nullptr; } ~PipelineResourceSignatureBase() @@ -74,82 +75,20 @@ public: IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_PipelineResourceSignature, TDeviceObjectBase) - Uint32 GetVariableCount(SHADER_TYPE ShaderType) const - { - // AZ TODO: optimize - Uint32 Count = 0; - for (Uint32 i = 0; i < this->m_Desc.NumResources; ++i) - { - auto& Res = this->m_Desc.Resources[i]; - if (Res.VarType != SHADER_RESOURCE_VARIABLE_TYPE_STATIC && (Res.ShaderStages & ShaderType)) - ++Count; - } - return Count; - } - - Uint32 GetVariableGlobalIndexByName(SHADER_TYPE ShaderType, const char* Name) const - { - // AZ TODO: optimize - for (Uint32 i = 0; i < this->m_Desc.NumResources; ++i) - { - auto& Res = this->m_Desc.Resources[i]; - if (Res.VarType != SHADER_RESOURCE_VARIABLE_TYPE_STATIC && (Res.ShaderStages & ShaderType)) - { - if (strcmp(Name, Res.Name) == 0) - return i; - } - } - return ~0u; - } - - Uint32 GetVariableGlobalIndexByIndex(SHADER_TYPE ShaderType, Uint32 Index) const - { - // AZ TODO: optimize - Uint32 Count = 0; - for (Uint32 i = 0; i < this->m_Desc.NumResources; ++i) - { - auto& Res = this->m_Desc.Resources[i]; - if (Res.VarType != SHADER_RESOURCE_VARIABLE_TYPE_STATIC && (Res.ShaderStages & ShaderType)) - { - if (Index == Count) - return i; - - ++Count; - } - } - return ~0u; - } - - Uint32 GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE VarType) const - { - // AZ TODO: optimize - Uint32 Count = 0; - for (Uint32 i = 0; i < this->m_Desc.NumResources; ++i) - { - auto& Res = this->m_Desc.Resources[i]; - if (Res.VarType == VarType) - Count += Res.ArraySize; - } - return Count; - } - - PipelineResourceDesc GetResource(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 Index) const - { - return {}; - } - size_t GetHash() const { return m_Hash; } PIPELINE_TYPE GetPipelineType() const { return m_PipelineType; } + const char* GetCombinedSamplerSuffix() const { return this->m_Desc.CombinedSamplerSuffix; } + + bool IsUsingCombinedSamplers() const { return this->m_Desc.CombinedSamplerSuffix != nullptr; } + bool IsUsingSeparateSamplers() const { return !IsUsingCombinedSamplers(); } + protected: #define LOG_PRS_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of a pipeline resource signature '", (Desc.Name ? Desc.Name : ""), "' is invalid: ", ##__VA_ARGS__) - void ReserveSpaceForDescription(FixedLinearAllocator& Allocator, const PipelineResourceSignatureDesc& Desc) noexcept(false) + void ReserveSpaceForDescription(FixedLinearAllocator& Allocator, const PipelineResourceSignatureDesc& Desc) const noexcept(false) { - if (Desc.NumResources == 0) - LOG_PRS_ERROR_AND_THROW("AZ TODO"); - Allocator.AddSpace(Desc.NumResources); Allocator.AddSpace(Desc.NumImmutableSamplers); @@ -176,6 +115,8 @@ protected: Allocator.AddSpaceForString(Desc.ImmutableSamplers[i].SamplerOrTextureName); } + + Allocator.AddSpaceForString(Desc.CombinedSamplerSuffix); } void CopyDescription(FixedLinearAllocator& Allocator, const PipelineResourceSignatureDesc& Desc) noexcept(false) @@ -183,7 +124,7 @@ protected: PipelineResourceDesc* pResources = Allocator.Allocate(this->m_Desc.NumResources); ImmutableSamplerDesc* pSamplers = Allocator.Allocate(this->m_Desc.NumImmutableSamplers); - m_Hash = ComputeHash(Desc.NumResources, Desc.NumImmutableSamplers); + m_Hash = ComputeHash(Desc.NumResources, Desc.NumImmutableSamplers, Desc.BindingIndex); for (Uint32 i = 0; i < Desc.NumResources; ++i) { @@ -191,7 +132,7 @@ protected: Dst = Desc.Resources[i]; Dst.Name = Allocator.CopyString(Desc.Resources[i].Name); - HashCombine(m_Hash, CStringHash{}(Dst.Name), Dst.ArraySize, Dst.ResourceType, Dst.ShaderStages, Dst.VarType, Dst.Flags); + HashCombine(m_Hash, Dst.ArraySize, Dst.ResourceType, Dst.ShaderStages, Dst.VarType, Dst.Flags); } for (Uint32 i = 0; i < Desc.NumImmutableSamplers; ++i) @@ -200,19 +141,21 @@ protected: Dst = Desc.ImmutableSamplers[i]; Dst.SamplerOrTextureName = Allocator.CopyString(Desc.ImmutableSamplers[i].SamplerOrTextureName); - //HashCombine(m_Hash, CStringHash{}(Dst.Name), Dst.ShaderStages, Dst.Desc); // AZ TODO + HashCombine(m_Hash, Dst.ShaderStages, Dst.Desc); } - this->m_Desc.Resources = pResources; - this->m_Desc.ImmutableSamplers = pSamplers; + this->m_Desc.Resources = pResources; + this->m_Desc.ImmutableSamplers = pSamplers; + this->m_Desc.CombinedSamplerSuffix = Allocator.CopyString(Desc.CombinedSamplerSuffix); } void Destruct() { VERIFY(!m_IsDestructed, "This object has already been destructed"); - this->m_Desc.Resources = nullptr; - this->m_Desc.ImmutableSamplers = nullptr; + this->m_Desc.Resources = nullptr; + this->m_Desc.ImmutableSamplers = nullptr; + this->m_Desc.CombinedSamplerSuffix = nullptr; #if DILIGENT_DEBUG m_IsDestructed = true; @@ -231,14 +174,14 @@ protected: } const auto ShaderTypeInd = GetShaderTypePipelineIndex(ShaderType, m_PipelineType); - const auto LayoutInd = StaticVarIndex[ShaderTypeInd]; - if (LayoutInd < 0) + const auto VarMngrInd = StaticVarIndex[ShaderTypeInd]; + if (VarMngrInd < 0) { LOG_WARNING_MESSAGE("Unable to get the number of static variables in shader stage ", GetShaderTypeLiteralName(ShaderType), " as the stage is inactive in PSO '", this->m_Desc.Name, "'."); } - return LayoutInd; + return VarMngrInd; } Int8 GetStaticVariableByNameHelper(SHADER_TYPE ShaderType, const Char* Name, const std::array& StaticVarIndex) const @@ -251,14 +194,14 @@ protected: } const auto ShaderTypeInd = GetShaderTypePipelineIndex(ShaderType, m_PipelineType); - const auto LayoutInd = StaticVarIndex[ShaderTypeInd]; - if (LayoutInd < 0) + const auto VarMngrInd = StaticVarIndex[ShaderTypeInd]; + if (VarMngrInd < 0) { LOG_WARNING_MESSAGE("Unable to find static variable '", Name, "' in shader stage ", GetShaderTypeLiteralName(ShaderType), " as the stage is inactive in PSO '", this->m_Desc.Name, "'."); } - return LayoutInd; + return VarMngrInd; } Int8 GetStaticVariableByIndexHelper(SHADER_TYPE ShaderType, Uint32 Index, const std::array& StaticVarIndex) const @@ -271,14 +214,14 @@ protected: } const auto ShaderTypeInd = GetShaderTypePipelineIndex(ShaderType, m_PipelineType); - const auto LayoutInd = StaticVarIndex[ShaderTypeInd]; - if (LayoutInd < 0) + const auto VarMngrInd = StaticVarIndex[ShaderTypeInd]; + if (VarMngrInd < 0) { LOG_WARNING_MESSAGE("Unable to get static variable at index ", Index, " in shader stage ", GetShaderTypeLiteralName(ShaderType), " as the stage is inactive in PSO '", this->m_Desc.Name, "'."); } - return LayoutInd; + return VarMngrInd; } protected: diff --git a/Graphics/GraphicsEngine/include/PipelineStateBase.hpp b/Graphics/GraphicsEngine/include/PipelineStateBase.hpp index d5ab5fb7..4b8b3b8a 100644 --- a/Graphics/GraphicsEngine/include/PipelineStateBase.hpp +++ b/Graphics/GraphicsEngine/include/PipelineStateBase.hpp @@ -216,16 +216,8 @@ public: return m_BufferSlotsUsed; } - SHADER_TYPE GetShaderStageType(Uint32 Stage) const { return m_ShaderStageTypes[Stage]; } - Uint32 GetNumShaderStages() const { return m_NumShaderStages; } - - // This function only compares shader resource layout hashes, so - // it can potentially give false negatives - bool IsIncompatibleWith(const IPipelineState* pPSO) const - { - return false; - //return m_ShaderResourceLayoutHash != ValidatedCast(pPSO)->m_ShaderResourceLayoutHash; - } + //SHADER_TYPE GetShaderStageType(Uint32 Stage) const { return m_ShaderStageTypes[Stage]; } + //Uint32 GetNumShaderStages() const { return m_NumShaderStages; } virtual const GraphicsPipelineDesc& DILIGENT_CALL_TYPE GetGraphicsPipelineDesc() const override final { @@ -244,44 +236,46 @@ public: virtual void DILIGENT_CALL_TYPE CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources) override final { - auto* pSign = GetResourceSignature(0); - if (pSign) - return pSign->CreateShaderResourceBinding(ppShaderResourceBinding, InitStaticResources); + *ppShaderResourceBinding = nullptr; + + if (GetResourceSignatureCount() != 1) + return; + + return GetResourceSignature(0)->CreateShaderResourceBinding(ppShaderResourceBinding, InitStaticResources); } virtual IShaderResourceVariable* DILIGENT_CALL_TYPE GetStaticVariableByName(SHADER_TYPE ShaderType, const Char* Name) override final { - VERIFY_EXPR(GetResourceSignatureCount() == 1); - - auto* pSign = GetResourceSignature(0); - if (pSign) - return pSign->GetStaticVariableByName(ShaderType, Name); + if (GetResourceSignatureCount() != 1) + return nullptr; - return nullptr; + return GetResourceSignature(0)->GetStaticVariableByName(ShaderType, Name); } virtual IShaderResourceVariable* DILIGENT_CALL_TYPE GetStaticVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index) override final { - VERIFY_EXPR(GetResourceSignatureCount() == 1); + if (GetResourceSignatureCount() != 1) + return nullptr; - auto* pSign = GetResourceSignature(0); - if (pSign) - return pSign->GetStaticVariableByIndex(ShaderType, Index); - - return nullptr; + return GetResourceSignature(0)->GetStaticVariableByIndex(ShaderType, Index); } virtual Uint32 DILIGENT_CALL_TYPE GetStaticVariableCount(SHADER_TYPE ShaderType) const override final { - VERIFY_EXPR(GetResourceSignatureCount() == 1); + if (GetResourceSignatureCount() != 1) + return 0; + + return GetResourceSignature(0)->GetStaticVariableCount(ShaderType); + } - auto* pSign = GetResourceSignature(0); - if (pSign) - return pSign->GetStaticVariableCount(ShaderType); + virtual void DILIGENT_CALL_TYPE BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags) override final + { + if (GetResourceSignatureCount() != 1) + return; - return 0; + return GetResourceSignature(0)->BindStaticResources(ShaderFlags, pResourceMapping, Flags); } inline void CopyShaderHandle(const char* Name, void* pData, size_t DataSize) const @@ -729,13 +723,15 @@ private: } protected: + //size_t m_ShaderResourceLayoutHash = 0; + Uint32* m_pStrides = nullptr; Uint8 m_BufferSlotsUsed = 0; Uint8 m_NumShaderStages = 0; ///< Number of shader stages in this PSO /// Array of shader types for every shader stage used by this PSO - std::array m_ShaderStageTypes = {}; + std::array m_ShaderStageTypes = {}; // AZ TODO: remove ? RefCntAutoPtr m_pRenderPass; ///< Strong reference to the render pass object diff --git a/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.hpp b/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.hpp index e69b785b..897ba560 100644 --- a/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.hpp +++ b/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.hpp @@ -67,24 +67,6 @@ public: IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_ShaderResourceBinding, TObjectBase) - /// Implementation of IShaderResourceBinding::GetPipelineState(). - //virtual IPipelineState* DILIGENT_CALL_TYPE GetPipelineState() override final - //{ - // return m_pPSO; - //} - - //template - //PSOType* GetPipelineState() - //{ - // return ValidatedCast(m_pPSO); - //} - - //template - //PSOType* GetPipelineState() const - //{ - // return ValidatedCast(m_pPSO); - //} - Uint32 GetBindingIndex() const { return m_pPRS->GetDesc().BindingIndex; diff --git a/Graphics/GraphicsEngine/interface/PipelineResourceSignature.h b/Graphics/GraphicsEngine/interface/PipelineResourceSignature.h index d4c58e92..4406e004 100644 --- a/Graphics/GraphicsEngine/interface/PipelineResourceSignature.h +++ b/Graphics/GraphicsEngine/interface/PipelineResourceSignature.h @@ -106,9 +106,6 @@ struct PipelineResourceDesc /// AZ TODO: comment PIPELINE_RESOURCE_FLAGS Flags DEFAULT_INITIALIZER(PIPELINE_RESOURCE_FLAG_UNKNOWN); - - /// AZ TODO: comment - RESOURCE_DIMENSION ResourceDim DEFAULT_INITIALIZER(RESOURCE_DIM_UNDEFINED); #if DILIGENT_CPP_INTERFACE PipelineResourceDesc()noexcept{} @@ -118,15 +115,13 @@ struct PipelineResourceDesc SHADER_RESOURCE_TYPE _ResourceType, SHADER_TYPE _ShaderStages, SHADER_RESOURCE_VARIABLE_TYPE _VarType, - RESOURCE_DIMENSION _Dim = RESOURCE_DIM_UNDEFINED, PIPELINE_RESOURCE_FLAGS _Flags = PIPELINE_RESOURCE_FLAG_UNKNOWN)noexcept : Name {_Name }, ArraySize {_ArraySize }, ResourceType{_ResourceType}, ShaderStages{_ShaderStages}, VarType {_VarType }, - Flags {_Flags }, - ResourceDim {_Dim } + Flags {_Flags } {} #endif }; @@ -153,6 +148,13 @@ struct PipelineResourceSignatureDesc DILIGENT_DERIVE(DeviceObjectAttribs) /// AZ TODO: comment Uint16 BindingOffsets [SHADER_RESOURCE_TYPE_LAST + 1] DEFAULT_INITIALIZER({}); + + /// If UseCombinedTextureSamplers is true, defines the suffix added to the + /// texture variable name to get corresponding sampler name. For example, + /// for default value "_sampler", a texture named "tex" will be combined + /// with sampler named "tex_sampler". + /// If UseCombinedTextureSamplers is false, this member is ignored. + const Char* CombinedSamplerSuffix DEFAULT_INITIALIZER("_sampler"); /// Shader resource binding allocation granularity @@ -196,6 +198,18 @@ DILIGENT_BEGIN_INTERFACE(IPipelineResourceSignature, IDeviceObject) bool InitStaticResources DEFAULT_VALUE(false)) PURE; + /// Binds resources for all shaders in the pipeline resource signature + + /// \param [in] ShaderFlags - Flags that specify shader stages, for which resources will be bound. + /// Any combination of Diligent::SHADER_TYPE may be used. + /// \param [in] pResourceMapping - Pointer to the resource mapping interface. + /// \param [in] Flags - Additional flags. See Diligent::BIND_SHADER_RESOURCES_FLAGS. + VIRTUAL void METHOD(BindStaticResources)(THIS_ + Uint32 ShaderFlags, + IResourceMapping* pResourceMapping, + Uint32 Flags) PURE; + + /// Returns static shader resource variable. If the variable is not found, /// returns nullptr. @@ -231,6 +245,10 @@ DILIGENT_BEGIN_INTERFACE(IPipelineResourceSignature, IDeviceObject) /// Mutable and dynamic variables are accessed through Shader Resource Binding object. VIRTUAL Uint32 METHOD(GetStaticVariableCount)(THIS_ SHADER_TYPE ShaderType) CONST PURE; + + /// AZ TODO: comment + VIRTUAL bool METHOD(IsCompatibleWith)(THIS_ + const struct IPipelineResourceSignature* pPRS) CONST PURE; }; DILIGENT_END_INTERFACE @@ -243,9 +261,11 @@ DILIGENT_END_INTERFACE # define IPipelineResourceSignature_GetDesc(This) (const struct PipelineResourceSignatureDesc*)IDeviceObject_GetDesc(This) # define IPipelineResourceSignature_CreateShaderResourceBinding(This, ...) CALL_IFACE_METHOD(PipelineResourceSignature, CreateShaderResourceBinding, This, __VA_ARGS__) +# define IPipelineResourceSignature_BindStaticResources(This, ...) CALL_IFACE_METHOD(PipelineResourceSignature, BindStaticResources, This, __VA_ARGS__) # define IPipelineResourceSignature_GetStaticVariableByName(This, ...) CALL_IFACE_METHOD(PipelineResourceSignature, GetStaticVariableByName, This, __VA_ARGS__) # define IPipelineResourceSignature_GetStaticVariableByIndex(This, ...) CALL_IFACE_METHOD(PipelineResourceSignature, GetStaticVariableByIndex, This, __VA_ARGS__) # define IPipelineResourceSignature_GetStaticVariableCount(This, ...) CALL_IFACE_METHOD(PipelineResourceSignature, GetStaticVariableCount, This, __VA_ARGS__) +# define IPipelineResourceSignature_IsCompatibleWith(This, ...) CALL_IFACE_METHOD(PipelineResourceSignature, IsCompatibleWith, This, __VA_ARGS__) // clang-format on diff --git a/Graphics/GraphicsEngine/interface/PipelineState.h b/Graphics/GraphicsEngine/interface/PipelineState.h index f780d4d6..fe44e8b8 100644 --- a/Graphics/GraphicsEngine/interface/PipelineState.h +++ b/Graphics/GraphicsEngine/interface/PipelineState.h @@ -316,6 +316,7 @@ struct PipelineStateDesc DILIGENT_DERIVE(DeviceObjectAttribs) /// This member defines allocation granularity for internal resources required by the shader resource /// binding object instances. + /// Has no effect if used pipeline resource signature. Uint32 SRBAllocationGranularity DEFAULT_INITIALIZER(1); /// Defines which command queues this pipeline state can be used with @@ -367,10 +368,10 @@ struct PipelineStateCreateInfo /// Pipeline state creation flags, see Diligent::PSO_CREATE_FLAGS. PSO_CREATE_FLAGS Flags DEFAULT_INITIALIZER(PSO_CREATE_FLAG_NONE); - /// AZ TODO + /// AZ TODO: comment IPipelineResourceSignature** ppResourceSignatures DEFAULT_INITIALIZER(nullptr); - /// AZ TODO + /// AZ TODO: comment Uint32 ResourceSignaturesCount DEFAULT_INITIALIZER(0); }; typedef struct PipelineStateCreateInfo PipelineStateCreateInfo; @@ -567,6 +568,7 @@ DILIGENT_BEGIN_INTERFACE(IPipelineState, IDeviceObject) /// Checks if this pipeline state object is compatible with another PSO + // Deprecated: use IsCompatibleWith() for pipeline resource signature. /// If two pipeline state objects are compatible, they can use shader resource binding /// objects interchangebly, i.e. SRBs created by one PSO can be committed diff --git a/Graphics/GraphicsEngine/interface/Shader.h b/Graphics/GraphicsEngine/interface/Shader.h index 9a0baf7c..de267e14 100644 --- a/Graphics/GraphicsEngine/interface/Shader.h +++ b/Graphics/GraphicsEngine/interface/Shader.h @@ -285,6 +285,7 @@ struct ShaderCreateInfo /// the sampler assigned to the shader resource view is automatically set when /// the view is bound. Otherwise samplers need to be explicitly set similar to other /// shader variables. + /// Has no effect if used pipeline resource signature. bool UseCombinedTextureSamplers DEFAULT_INITIALIZER(false); /// If UseCombinedTextureSamplers is true, defines the suffix added to the @@ -292,6 +293,7 @@ struct ShaderCreateInfo /// for default value "_sampler", a texture named "tex" will be combined /// with sampler named "tex_sampler". /// If UseCombinedTextureSamplers is false, this member is ignored. + /// Has no effect if used pipeline resource signature. const Char* CombinedSamplerSuffix DEFAULT_INITIALIZER("_sampler"); /// Shader description. See Diligent::ShaderDesc. -- cgit v1.2.3