From 42b12901274c2aabee3ddbb9d3a012d28e5f5f7d Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Mon, 7 Oct 2019 09:19:35 -0700 Subject: Completely reworked shader resource binding implementation in OpenGL backend to make it function similar to other backends --- Graphics/GraphicsEngine/include/ShaderBase.h | 3 + .../include/ShaderResourceVariableBase.h | 68 ++++++++++++++-------- Graphics/GraphicsEngine/interface/Shader.h | 2 +- .../interface/ShaderResourceBinding.h | 6 ++ 4 files changed, 54 insertions(+), 25 deletions(-) (limited to 'Graphics/GraphicsEngine') diff --git a/Graphics/GraphicsEngine/include/ShaderBase.h b/Graphics/GraphicsEngine/include/ShaderBase.h index 892bd0cb..0ee22970 100644 --- a/Graphics/GraphicsEngine/include/ShaderBase.h +++ b/Graphics/GraphicsEngine/include/ShaderBase.h @@ -33,6 +33,7 @@ #include "STDAllocator.h" #include "PlatformMisc.h" #include "EngineMemory.h" +#include "Align.h" namespace Diligent { @@ -44,6 +45,8 @@ inline SHADER_TYPE GetShaderTypeFromIndex(Int32 Index) inline Int32 GetShaderTypeIndex(SHADER_TYPE Type) { + VERIFY(IsPowerOfTwo(Uint32{Type}), "Only single shader stage should be provided"); + Int32 ShaderIndex = PlatformMisc::GetLSB(Type); #ifdef _DEBUG diff --git a/Graphics/GraphicsEngine/include/ShaderResourceVariableBase.h b/Graphics/GraphicsEngine/include/ShaderResourceVariableBase.h index 3ed08df9..22d2d661 100644 --- a/Graphics/GraphicsEngine/include/ShaderResourceVariableBase.h +++ b/Graphics/GraphicsEngine/include/ShaderResourceVariableBase.h @@ -30,6 +30,7 @@ #include "ShaderResourceVariable.h" #include "PipelineState.h" +#include "StringTools.h" namespace Diligent { @@ -110,52 +111,71 @@ inline Uint32 GetAllowedTypeBits(const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVar return AllowedTypeBits; } -/// Base implementation of a shader variable -struct ShaderVariableBase : public IShaderResourceVariable +inline Int32 FindStaticSampler(const StaticSamplerDesc* StaticSamplers, + Uint32 NumStaticSamplers, + SHADER_TYPE ShaderType, + const char* ResourceName, + const char* SamplerSuffix) { - ShaderVariableBase(IObject& Owner) : - // Shader variables are always created as part of the shader, or - // shader resource binding, so we must provide owner pointer to - // the base class constructor - m_Owner(Owner) - { - } - - IObject& GetOwner() + for (Uint32 s=0; s < NumStaticSamplers; ++s) { - return m_Owner; + const auto& StSam = StaticSamplers[s]; + if ( ((StSam.ShaderStages & ShaderType) != 0) && StreqSuff(ResourceName, StSam.SamplerOrTextureName, SamplerSuffix) ) + return s; } - virtual IReferenceCounters* GetReferenceCounters()const override final - { - return m_Owner.GetReferenceCounters(); - } + return -1; +} - virtual Atomics::Long AddRef()override final +struct DefaultShaderVariableIDComparator +{ + bool operator() (const INTERFACE_ID& IID)const { - return m_Owner.AddRef(); + return IID == IID_ShaderResourceVariable || IID == IID_Unknown; } +}; - virtual Atomics::Long Release()override final +/// Base implementation of a shader variable +template +struct ShaderVariableBase : public ResourceVariableBaseInterface +{ + ShaderVariableBase(ResourceLayoutType& ParentResLayout) : + m_ParentResLayout(ParentResLayout) { - return m_Owner.Release(); } - virtual void QueryInterface( const INTERFACE_ID& IID, IObject** ppInterface )override final + void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override final { - if( ppInterface == nullptr ) + if (ppInterface == nullptr) return; *ppInterface = nullptr; - if( IID == IID_ShaderResourceVariable || IID == IID_Unknown ) + if (VariableIDComparator{}(IID)) { *ppInterface = this; (*ppInterface)->AddRef(); } } + virtual Atomics::Long AddRef()override final + { + return m_ParentResLayout.GetOwner().AddRef(); + } + + virtual Atomics::Long Release()override final + { + return m_ParentResLayout.GetOwner().Release(); + } + + virtual IReferenceCounters* GetReferenceCounters()const override final + { + return m_ParentResLayout.GetOwner().GetReferenceCounters(); + } + protected: - IObject& m_Owner; + ResourceLayoutType& m_ParentResLayout; }; } diff --git a/Graphics/GraphicsEngine/interface/Shader.h b/Graphics/GraphicsEngine/interface/Shader.h index c28fdc9e..c88e88fe 100644 --- a/Graphics/GraphicsEngine/interface/Shader.h +++ b/Graphics/GraphicsEngine/interface/Shader.h @@ -222,7 +222,7 @@ enum SHADER_RESOURCE_TYPE : Uint8 struct ShaderResourceDesc { /// Shader resource name - const char* Name = nullptr; + const char* Name = nullptr; /// Shader resource type, see Diligent::SHADER_RESOURCE_TYPE. SHADER_RESOURCE_TYPE Type = SHADER_RESOURCE_TYPE_UNKNOWN; diff --git a/Graphics/GraphicsEngine/interface/ShaderResourceBinding.h b/Graphics/GraphicsEngine/interface/ShaderResourceBinding.h index f568ee87..fe16d76c 100644 --- a/Graphics/GraphicsEngine/interface/ShaderResourceBinding.h +++ b/Graphics/GraphicsEngine/interface/ShaderResourceBinding.h @@ -67,6 +67,9 @@ public: /// \param [in] ShaderType - Type of the shader to look up the variable. /// Must be one of Diligent::SHADER_TYPE. /// \param [in] Name - Variable name + /// + /// \note This operation may potentially be expensive. If the variable will be used often, it is + /// recommended to store and reuse the pointer as it never changes. virtual IShaderResourceVariable* GetVariableByName(SHADER_TYPE ShaderType, const char* Name) = 0; /// Returns the total variable count for the specific shader stage. @@ -86,6 +89,9 @@ public: /// IShaderResourceBinding::GetVariableCount(). /// \remark Only mutable and dynamic variables can be accessed through this method. /// Static variables are accessed through the Shader object. + /// + /// \note This operation may potentially be expensive. If the variable will be used often, it is + /// recommended to store and reuse the pointer as it never changes. virtual IShaderResourceVariable* GetVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index) = 0; -- cgit v1.2.3