From 1e138ea5cd724747ff21a852cc25550e436da633 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Wed, 27 Feb 2019 23:48:25 -0800 Subject: Finished refactoring pipeline layout definition in Vk backend --- .../GraphicsEngine/include/PipelineStateBase.h | 76 ++++++- Graphics/GraphicsEngine/interface/PipelineState.h | 117 ++++++++++- Graphics/GraphicsEngine/interface/Shader.h | 221 ++++----------------- .../interface/ShaderResourceBinding.h | 25 +-- .../interface/ShaderResourceVariable.h | 134 +++++++++++++ 5 files changed, 367 insertions(+), 206 deletions(-) create mode 100644 Graphics/GraphicsEngine/interface/ShaderResourceVariable.h (limited to 'Graphics/GraphicsEngine') diff --git a/Graphics/GraphicsEngine/include/PipelineStateBase.h b/Graphics/GraphicsEngine/include/PipelineStateBase.h index 2683d63c..3dde7b85 100644 --- a/Graphics/GraphicsEngine/include/PipelineStateBase.h +++ b/Graphics/GraphicsEngine/include/PipelineStateBase.h @@ -34,6 +34,7 @@ #include "STDAllocator.h" #include "EngineMemory.h" #include "GraphicsAccessories.h" +#include "StringPool.h" namespace Diligent { @@ -65,6 +66,62 @@ public: m_LayoutElements (PSODesc.GraphicsPipeline.InputLayout.NumElements, LayoutElement{}, STD_ALLOCATOR_RAW_MEM(LayoutElement, GetRawAllocator(), "Allocator for vector")), m_NumShaders(0) { + const auto& SrcLayout = PSODesc.Layout; + size_t StringPoolSize = 0; + if (SrcLayout.Variables != nullptr) + { + for (Uint32 i=0; i < SrcLayout.NumVariables; ++i) + StringPoolSize += strlen(SrcLayout.Variables[i].Name) + 1; + } + + if (SrcLayout.StaticSamplers != nullptr) + { + for (Uint32 i=0; i < SrcLayout.NumStaticSamplers; ++i) + StringPoolSize += strlen(SrcLayout.StaticSamplers[i].SamplerOrTextureName) + 1; + } + m_StringPool.Allocate(StringPoolSize); + + auto& DstLayout = this->m_Desc.Layout; + if (SrcLayout.Variables != nullptr) + { + ShaderResourceVariableDesc* Variables = + reinterpret_cast(ALLOCATE(GetRawAllocator(), "Memory for ShaderResourceVariableDesc array", sizeof(ShaderResourceVariableDesc) * SrcLayout.NumVariables)); + DstLayout.Variables = Variables; + for (Uint32 i=0; i < SrcLayout.NumVariables; ++i) + { + VERIFY(SrcLayout.Variables[i].Name != nullptr, "Variable name can't be null"); + Variables[i] = SrcLayout.Variables[i]; + Variables[i].Name = m_StringPool.CopyString(SrcLayout.Variables[i].Name); + } + } + + if (SrcLayout.StaticSamplers != nullptr) + { + StaticSamplerDesc* StaticSamplers = + reinterpret_cast(ALLOCATE(GetRawAllocator(), "Memory for StaticSamplerDesc array", sizeof(StaticSamplerDesc) * SrcLayout.NumStaticSamplers)); + DstLayout.StaticSamplers = StaticSamplers; + for (Uint32 i=0; i < SrcLayout.NumStaticSamplers; ++i) + { + VERIFY(SrcLayout.StaticSamplers[i].SamplerOrTextureName != nullptr, "Static sampler or texture name can't be null"); +#ifdef DEVELOPMENT + const auto &BorderColor = SrcLayout.StaticSamplers[i].Desc.BorderColor; + if( !( (BorderColor[0] == 0 && BorderColor[1] == 0 && BorderColor[2] == 0 && BorderColor[3] == 0) || + (BorderColor[0] == 0 && BorderColor[1] == 0 && BorderColor[2] == 0 && BorderColor[3] == 1) || + (BorderColor[0] == 1 && BorderColor[1] == 1 && BorderColor[2] == 1 && BorderColor[3] == 1) ) ) + { + LOG_WARNING_MESSAGE("Static sampler for variable \"", SrcLayout.StaticSamplers[i].SamplerOrTextureName, "\" specifies border color (", + BorderColor[0], ", ", BorderColor[1], ", ", BorderColor[2], ", ", BorderColor[3], "). " + "D3D12 static samplers only allow transparent black (0,0,0,0), opaque black (0,0,0,1) or opaque white (1,1,1,1) as border colors"); + } +#endif + + StaticSamplers[i] = SrcLayout.StaticSamplers[i]; + StaticSamplers[i].SamplerOrTextureName = m_StringPool.CopyString(SrcLayout.StaticSamplers[i].SamplerOrTextureName); + } + } + VERIFY_EXPR(m_StringPool.GetRemainingSize() == 0); + + if (this->m_Desc.IsComputePipeline) { const auto &ComputePipeline = PSODesc.ComputePipeline; @@ -206,6 +263,12 @@ public: RasterizerStateRegistry.ReportDeletedObject(); DSSRegistry.ReportDeletedObject(); */ + + auto& RawAllocator = GetRawAllocator(); + if (this->m_Desc.Layout.Variables != nullptr) + RawAllocator.Free(const_cast(this->m_Desc.Layout.Variables)); + if (this->m_Desc.Layout.StaticSamplers != nullptr) + RawAllocator.Free(const_cast(this->m_Desc.Layout.StaticSamplers)); } IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_PipelineState, TDeviceObjectBase ) @@ -250,21 +313,19 @@ public: return m_ShaderResourceLayoutHash != ValidatedCast(pPSO)->m_ShaderResourceLayoutHash; } - virtual void BindShaderResources( IResourceMapping* pResourceMapping, Uint32 Flags )override - { - for(Uint32 s=0; s < m_NumShaders; ++s) - m_ppShaders[s]->BindResources(pResourceMapping, Flags); - } - protected: + // TODO: rework this std::vector > m_LayoutElements; Uint32 m_BufferSlotsUsed = 0; + Uint32 m_NumShaders = 0; ///< Number of shaders that this PSO uses + // The size of this array must be equal to the // maximum number of buffer slots, because a layout // element can refer to any input slot - std::array m_Strides = {}; + std::array m_Strides = {}; // TODO: rework this + StringPool m_StringPool; RefCntAutoPtr m_pVS; ///< Strong reference to the vertex shader RefCntAutoPtr m_pPS; ///< Strong reference to the pixel shader RefCntAutoPtr m_pGS; ///< Strong reference to the geometry shader @@ -272,7 +333,6 @@ protected: RefCntAutoPtr m_pHS; ///< Strong reference to the hull shader RefCntAutoPtr m_pCS; ///< Strong reference to the compute shader IShader* m_ppShaders[5] = {}; ///< Array of pointers to the shaders used by this PSO - Uint32 m_NumShaders = 0; ///< Number of shaders that this PSO uses size_t m_ShaderResourceLayoutHash = 0;///< Hash computed from the shader resource layout }; diff --git a/Graphics/GraphicsEngine/interface/PipelineState.h b/Graphics/GraphicsEngine/interface/PipelineState.h index 4bbbbe9e..39064c75 100644 --- a/Graphics/GraphicsEngine/interface/PipelineState.h +++ b/Graphics/GraphicsEngine/interface/PipelineState.h @@ -34,6 +34,8 @@ #include "DepthStencilState.h" #include "InputLayout.h" #include "ShaderResourceBinding.h" +#include "ShaderResourceVariable.h" +#include "Shader.h" namespace Diligent { @@ -51,14 +53,82 @@ struct SampleDesc SampleDesc()noexcept{} - SampleDesc(Uint8 _Count, - Uint8 _Quality) : + SampleDesc(Uint8 _Count, Uint8 _Quality) noexcept : Count (_Count), Quality (_Quality) {} }; +/// Describes shader variable +struct ShaderResourceVariableDesc +{ + /// Shader stages this resources variable applies to. More than one shader stage can be specified. + SHADER_TYPE ShaderStages = SHADER_TYPE_UNKNOWN; + + /// Shader variable name + const Char* Name = nullptr; + + /// Shader variable type. See Diligent::SHADER_RESOURCE_VARIABLE_TYPE for a list of allowed types + SHADER_RESOURCE_VARIABLE_TYPE Type = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; + + ShaderResourceVariableDesc()noexcept{} + + ShaderResourceVariableDesc(SHADER_TYPE _ShaderStages, const Char* _Name, SHADER_RESOURCE_VARIABLE_TYPE _Type)noexcept : + ShaderStages(_ShaderStages), + Name (_Name), + Type (_Type) + {} +}; + + +/// Static sampler description +struct StaticSamplerDesc +{ + /// Shader stages that this static sampler applies to. More than one shader stage can be specified. + SHADER_TYPE ShaderStages = SHADER_TYPE_UNKNOWN; + + /// The name of the sampler itself or the name of the texture variable that + /// this static sampler is assigned to if combined texture samplers are used. + const Char* SamplerOrTextureName = nullptr; + + /// Sampler description + SamplerDesc Desc; + + StaticSamplerDesc()noexcept{} + + StaticSamplerDesc(SHADER_TYPE _ShaderStages, + const Char* _SamplerOrTextureName, + const SamplerDesc& _Desc)noexcept : + ShaderStages (_ShaderStages), + SamplerOrTextureName(_SamplerOrTextureName), + Desc (_Desc) + {} +}; + + +/// Pipeline layout description +struct PipelineLayoutDesc +{ + /// Default shader resource variable type. This type will be used if shader + /// variable description is not found in the Variables array + /// or if Variables == nullptr + SHADER_RESOURCE_VARIABLE_TYPE DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; + + /// Number of elements in Variables array + Uint32 NumVariables = 0; + + /// Array of shader resource variable descriptions + const ShaderResourceVariableDesc* Variables = nullptr; + + /// Number of static samplers in StaticSamplers array + Uint32 NumStaticSamplers = 0; + + /// Array of static sampler descriptions + const StaticSamplerDesc* StaticSamplers = nullptr; +}; + + /// Graphics pipeline state description /// This structure describes the graphics pipeline state and is part of the PipelineStateDesc structure. @@ -150,6 +220,9 @@ struct PipelineStateDesc : DeviceObjectAttribs /// Defines which command queues this pipeline state can be used with Uint64 CommandQueueMask = 1; + /// Pipeline layout description + PipelineLayoutDesc Layout; + /// Graphics pipeline state description. This memeber is ignored if IsComputePipeline == True GraphicsPipelineDesc GraphicsPipeline; @@ -170,14 +243,49 @@ public: /// Queries the specific interface, see IObject::QueryInterface() for details virtual void QueryInterface( const INTERFACE_ID& IID, IObject** ppInterface ) = 0; + /// Returns the blend state description used to create the object virtual const PipelineStateDesc& GetDesc()const = 0; + /// Binds resources for all shaders in the pipeline state /// \param [in] pResourceMapping - Pointer to the resource mapping interface. /// \param [in] Flags - Additional flags. See Diligent::BIND_SHADER_RESOURCES_FLAGS. - virtual void BindShaderResources( IResourceMapping* pResourceMapping, Uint32 Flags ) = 0; + virtual void BindStaticResources(IResourceMapping* pResourceMapping, Uint32 Flags) = 0; + + + /// Returns the number of static shader resource variables. + + /// \param [in] ShaderType - Type of the shader. + /// \remark Only static variables (that can be accessed directly through the PSO) are counted. + /// Mutable and dynamic variables are accessed through Shader Resource Binding object. + virtual Uint32 GetStaticVariableCount(SHADER_TYPE ShaderType) const = 0; + + + /// Returns static shader resource variable. If the variable is not found, + /// returns nullptr. + + /// \param [in] ShaderType - Type of the shader to look up the variable. + /// Must be one of Diligent::SHADER_TYPE. + /// \param [in] Name - Name of the variable. + /// \remark The method does not increment the reference counter + /// of the returned interface. + virtual IShaderResourceVariable* GetStaticShaderVariable(SHADER_TYPE ShaderType, const Char* Name) = 0; + + + /// Returns static shader resource variable by its index. + + /// \param [in] ShaderType - Type of the shader to look up the variable. + /// Must be one of Diligent::SHADER_TYPE. + /// \param [in] Index - Shader variable index. The index must be between + /// 0 and the total number of variables returned by + /// GetStaticVariableCount(). + /// \remark Only static shader resource variables can be accessed through this method. + /// Mutable and dynamic variables are accessed through Shader Resource + /// Binding object + virtual IShaderResourceVariable* GetStaticShaderVariable(SHADER_TYPE ShaderType, Uint32 Index) = 0; + /// Creates a shader resource binding object @@ -186,7 +294,8 @@ public: /// \param [in] InitStaticResources - if set to true, the method will initialize static resources in /// the created object, which has the exact same effect as calling /// IShaderResourceBinding::InitializeStaticResources(). - virtual void CreateShaderResourceBinding( IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources = false ) = 0; + virtual void CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources = false) = 0; + /// Checks if this pipeline state object is compatible with another PSO diff --git a/Graphics/GraphicsEngine/interface/Shader.h b/Graphics/GraphicsEngine/interface/Shader.h index d9e90d87..43d6021a 100644 --- a/Graphics/GraphicsEngine/interface/Shader.h +++ b/Graphics/GraphicsEngine/interface/Shader.h @@ -28,8 +28,6 @@ #include "../../../Primitives/interface/FileStream.h" #include "DeviceObject.h" -#include "ResourceMapping.h" -#include "Sampler.h" namespace Diligent { @@ -38,10 +36,6 @@ namespace Diligent static constexpr INTERFACE_ID IID_Shader = { 0x2989b45c, 0x143d, 0x4886, { 0xb8, 0x9c, 0xc3, 0x27, 0x1c, 0x2d, 0xcc, 0x5d } }; -// {0D57DF3F-977D-4C8F-B64C-6675814BC80C} -static constexpr INTERFACE_ID IID_ShaderVariable = -{ 0xd57df3f, 0x977d, 0x4c8f, { 0xb6, 0x4c, 0x66, 0x75, 0x81, 0x4b, 0xc8, 0xc } }; - /// Describes the shader type enum SHADER_TYPE : Uint32 { @@ -76,128 +70,16 @@ enum SHADER_SOURCE_LANGUAGE : Uint32 SHADER_SOURCE_LANGUAGE_GLSL }; -/// Describes shader variable type that is used by ShaderVariableDesc -enum SHADER_VARIABLE_TYPE : Uint8 -{ - /// Shader variable is constant across all shader instances. - /// It must be set *once* directly through IShader::BindResources() or through - /// the shader variable. - SHADER_VARIABLE_TYPE_STATIC = 0, - - /// Shader variable is constant across shader resource bindings instance (see IShaderResourceBinding). - /// It must be set *once* through IShaderResourceBinding::BindResources() or through - /// the shader variable. It cannot be set through IShader interface - SHADER_VARIABLE_TYPE_MUTABLE, - - /// Shader variable is dynamic. It can be set multiple times for every instance of shader resource - /// bindings (see IShaderResourceBinding). It cannot be set through IShader interface - SHADER_VARIABLE_TYPE_DYNAMIC, - - /// Total number of shader variable types - SHADER_VARIABLE_TYPE_NUM_TYPES -}; - - -static_assert(SHADER_VARIABLE_TYPE_STATIC == 0 && SHADER_VARIABLE_TYPE_MUTABLE == 1 && SHADER_VARIABLE_TYPE_DYNAMIC == 2 && SHADER_VARIABLE_TYPE_NUM_TYPES == 3, "BIND_SHADER_RESOURCES_UPDATE_* flags rely on shader variable SHADER_VARIABLE_TYPE_* values being 0,1,2"); -/// Describes flags that can be given to IShader::BindResources(), -/// IPipelineState::BindShaderResources(), and IDeviceContext::BindShaderResources() methods. -enum BIND_SHADER_RESOURCES_FLAGS : Uint32 -{ - /// Indicates that static variable bindings are to be updated. - BIND_SHADER_RESOURCES_UPDATE_STATIC = (0x01 << SHADER_VARIABLE_TYPE_STATIC), - - /// Indicates that mutable variable bindings are to be updated. - BIND_SHADER_RESOURCES_UPDATE_MUTABLE = (0x01 << SHADER_VARIABLE_TYPE_MUTABLE), - - /// Indicates that dynamic variable bindings are to be updated. - BIND_SHADER_RESOURCES_UPDATE_DYNAMIC = (0x01 << SHADER_VARIABLE_TYPE_DYNAMIC), - - /// Indicates that all variable types (static, mutable and dynamic) are to be updated. - /// \note If none of BIND_SHADER_RESOURCES_UPDATE_STATIC, BIND_SHADER_RESOURCES_UPDATE_MUTABLE, - /// and BIND_SHADER_RESOURCES_UPDATE_DYNAMIC flags are set, all variable types are updated - /// as if BIND_SHADER_RESOURCES_UPDATE_ALL was specified. - BIND_SHADER_RESOURCES_UPDATE_ALL = (BIND_SHADER_RESOURCES_UPDATE_STATIC | BIND_SHADER_RESOURCES_UPDATE_MUTABLE | BIND_SHADER_RESOURCES_UPDATE_DYNAMIC), - - /// If this flag is specified, all existing bindings will be preserved and - /// only unresolved ones will be updated. - /// If this flag is not specified, every shader variable will be - /// updated if the mapping contains corresponding resource. - BIND_SHADER_RESOURCES_KEEP_EXISTING = 0x08, - - /// If this flag is specified, all shader bindings are expected - /// to be resolved after the call. If this is not the case, debug message - /// will be displayed. - /// \note Only these variables are verified that are being updated by setting - /// BIND_SHADER_RESOURCES_UPDATE_STATIC, BIND_SHADER_RESOURCES_UPDATE_MUTABLE, and - /// BIND_SHADER_RESOURCES_UPDATE_DYNAMIC flags. - BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED = 0x10 -}; - -/// Describes shader variable -struct ShaderVariableDesc -{ - /// Shader variable name - const Char* Name = nullptr; - - /// Shader variable type. See Diligent::SHADER_VARIABLE_TYPE for a list of allowed types - SHADER_VARIABLE_TYPE Type = SHADER_VARIABLE_TYPE_STATIC; - - ShaderVariableDesc()noexcept{} - - ShaderVariableDesc(const Char* _Name, - SHADER_VARIABLE_TYPE _Type) : - Name(_Name), - Type(_Type) - {} -}; - - -/// Static sampler description -struct StaticSamplerDesc -{ - /// The name of the sampler itself or the name of the texture variable that - /// this static sampler is assigned to if combined texture samplers are used. - const Char* SamplerOrTextureName = nullptr; - - /// Sampler description - SamplerDesc Desc; - - StaticSamplerDesc()noexcept{} - StaticSamplerDesc(const Char* _SamplerOrTextureName, - const SamplerDesc& _Desc)noexcept : - SamplerOrTextureName(_SamplerOrTextureName), - Desc (_Desc) - {} -}; - /// Shader description struct ShaderDesc : DeviceObjectAttribs { - /// Shader type. See Diligent::SHADER_TYPE - SHADER_TYPE ShaderType = SHADER_TYPE_VERTEX; - - Bool bCacheCompiledShader = False; - - SHADER_PROFILE TargetProfile = SHADER_PROFILE_DEFAULT; + /// Shader type. See Diligent::SHADER_TYPE. + SHADER_TYPE ShaderType = SHADER_TYPE_VERTEX; - /// Default shader variable type. This type will be used if shader - /// variable description is not found in array VariableDesc points to - /// or if VariableDesc == nullptr - SHADER_VARIABLE_TYPE DefaultVariableType = SHADER_VARIABLE_TYPE_STATIC; - - /// Array of shader variable descriptions - const ShaderVariableDesc* VariableDesc = nullptr; - - /// Number of elements in VariableDesc array - Uint32 NumVariables = 0; - - /// Number of static samplers in StaticSamplers array - Uint32 NumStaticSamplers = 0; - - /// Array of static sampler descriptions - const StaticSamplerDesc* StaticSamplers = nullptr; + SHADER_PROFILE TargetProfile = SHADER_PROFILE_DEFAULT; }; + /// Shader source stream factory interface class IShaderSourceInputStreamFactory { @@ -219,7 +101,7 @@ struct ShaderMacro }; /// Shader creation attributes -struct ShaderCreationAttribs +struct ShaderCreateInfo { /// Source file path @@ -258,7 +140,7 @@ struct ShaderCreationAttribs /// backend expects SPIRV bytecode. /// The bytecode must contain reflection information. If shaders were compiled /// using fxc, make sure that /Qstrip_reflect option is *not* specified. - /// Also, shaders need to be compiled against 4.0 profile or higher. + /// HLSL shaders need to be compiled against 4.0 profile or higher. const void* ByteCode = nullptr; /// Size of the compiled shader bytecode @@ -305,41 +187,42 @@ struct ShaderCreationAttribs IDataBlob** ppCompilerOutput = nullptr; }; - -/// Shader resource variable -class IShaderVariable : public IObject +/// Describes shader resource type +enum SHADER_RESOURCE_TYPE { -public: - /// Sets the variable to the given value + /// Shader resource type is unknown + SHADER_RESOURCE_TYPE_UNKNOWN = 0, + + /// Constant (uniform) buffer + SHADER_RESOURCE_TYPE_CONSTANT_BUFFER, - /// \remark The method performs run-time correctness checks. - /// For instance, shader resource view cannot - /// be assigned to a constant buffer variable. - virtual void Set(IDeviceObject* pObject) = 0; + /// Shader resource view of a texture (sampled image) + SHADER_RESOURCE_TYPE_TEXTURE_SRV, - /// Sets the variable array + /// Shader resource view of a buffer (read-only storage image) + SHADER_RESOURCE_TYPE_BUFFER_SRV, - /// \param [in] ppObjects - pointer to the array of objects - /// \param [in] FirstElement - first array element to set - /// \param [in] NumElements - number of objects in ppObjects array - /// - /// \remark The method performs run-time correctness checks. - /// For instance, shader resource view cannot - /// be assigned to a constant buffer variable. - virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements) = 0; + /// Unordered access view of a texture (sotrage image) + SHADER_RESOURCE_TYPE_TEXTURE_UAV, - /// Returns shader variable type - virtual SHADER_VARIABLE_TYPE GetType()const = 0; + /// Unordered access view of a buffer (storage buffer) + SHADER_RESOURCE_TYPE_BUFFER_UAV, - /// Returns array size. For non-array variables returns one. - virtual Uint32 GetArraySize()const = 0; + /// Sampler (separate sampler) + SHADER_RESOURCE_TYPE_SAMPLER +}; + +/// Shader resource description +struct ShaderResourceDesc +{ + /// Shader resource name + const char* Name = nullptr; - /// Returns the variable name - virtual const Char* GetName()const = 0; + /// Shader resource type, see Diligent::SHADER_RESOURCE_TYPE. + SHADER_RESOURCE_TYPE Type = SHADER_RESOURCE_TYPE_UNKNOWN; - /// Returns variable index that can be used to access the variable through - /// shader or shader resource binding object - virtual Uint32 GetIndex()const = 0; + /// Array size. For non-array resource this value is 1. + Uint32 ArraySize = 0; }; /// Shader interface @@ -347,42 +230,16 @@ class IShader : public IDeviceObject { public: /// Queries the specific interface, see IObject::QueryInterface() for details - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ) = 0; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) = 0; /// Returns the shader description virtual const ShaderDesc& GetDesc()const = 0; - /// Binds shader resources. - /// \param [in] pResourceMapping - Pointer to IResourceMapping interface to - /// look for resources. - /// \param [in] Flags - Additional flags for the operation. See - /// Diligent::BIND_SHADER_RESOURCES_FLAGS for details. - /// \remark The shader will keep strong references to all resources bound to it. - virtual void BindResources( IResourceMapping* pResourceMapping, Uint32 Flags ) = 0; + /// Returns the total number of shader resources + virtual Uint32 GetResourceCount()const = 0; - /// Returns an interface to a shader variable. If the shader variable - /// is not found, an interface to a dummy variable will be returned. - - /// \param [in] Name - Name of the variable. - /// \remark The method does not increment the reference counter - /// of the returned interface. - virtual IShaderVariable* GetShaderVariable(const Char* Name) = 0; - - /// Returns the number of shader variables. - - /// \remark Only static variables (that can be accessed directly through the shader) are counted. - /// Mutable and dynamic variables are accessed through Shader Resource Binding object. - virtual Uint32 GetVariableCount() const = 0; - - /// Returns shader variable by its index. - - /// \param [in] Index - Shader variable index. The index must be between - /// 0 and the total number of variables returned by - /// GetVariableCount(). - /// \remark Only static shader variables can be accessed through this method. - /// Mutable and dynamic variables are accessed through Shader Resource - /// Binding object - virtual IShaderVariable* GetShaderVariable(Uint32 Index) = 0; + /// Returns the pointer to the array of shader resources + virtual const ShaderResourceDesc* GetResources()const = 0; }; } diff --git a/Graphics/GraphicsEngine/interface/ShaderResourceBinding.h b/Graphics/GraphicsEngine/interface/ShaderResourceBinding.h index 8671c3f7..970f1ff1 100644 --- a/Graphics/GraphicsEngine/interface/ShaderResourceBinding.h +++ b/Graphics/GraphicsEngine/interface/ShaderResourceBinding.h @@ -27,7 +27,7 @@ /// Definition of the Diligent::IShaderResourceBinding interface and related data structures #include "../../../Primitives/interface/Object.h" -#include "Shader.h" +#include "ShaderResourceVariable.h" namespace Diligent { @@ -44,7 +44,7 @@ class IShaderResourceBinding : public IObject { public: /// Queries the specific interface, see IObject::QueryInterface() for details - virtual void QueryInterface( const INTERFACE_ID& IID, IObject** ppInterface ) = 0; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) = 0; /// Returns pointer to the referenced buffer object. @@ -52,20 +52,20 @@ public: /// so Release() must be called to avoid memory leaks. virtual IPipelineState* GetPipelineState() = 0; - /// Binds all resource using the resource mapping + /// Binds mutable and dynamice resources using the resource mapping /// \param [in] ShaderFlags - Flags for the shader stages, for which resources will be bound. /// Any combination of Diligent::SHADER_TYPE may be specified. /// \param [in] pResMapping - Shader resource mapping, where required resources will be looked up - /// \param [in] Flags - Additional flags. See Diligent::BIND_SHADER_RESOURCES_FLAGS. + /// \param [in] Flags - Additional flags. See Diligent::BIND_SHADER_RESOURCES_FLAGS. virtual void BindResources(Uint32 ShaderFlags, IResourceMapping* pResMapping, Uint32 Flags) = 0; /// Returns variable /// \param [in] ShaderType - Type of the shader to look up the variable. /// Must be one of Diligent::SHADER_TYPE. - /// \param Name - Variable name - virtual IShaderVariable* GetVariable(SHADER_TYPE ShaderType, const char *Name) = 0; + /// \param [in] Name - Variable name + virtual IShaderResourceVariable* GetVariable(SHADER_TYPE ShaderType, const char* Name) = 0; /// Returns the total variable count for the specific shader stage. @@ -79,20 +79,21 @@ public: /// \param [in] ShaderType - Type of the shader to look up the variable. /// Must be one of Diligent::SHADER_TYPE. - /// \param Index - Variable index. The index must be between 0 and the total number - /// of variables in this shader stage as returned by GetVariableCount(). + /// \param [in] Index - Variable index. The index must be between 0 and the total number + /// of variables in this shader stage as returned by + /// IShaderResourceBinding::GetVariableCount(). /// \remark Only mutable and dynamic variables can be accessed through this method. /// Static variables are accessed through the Shader object. - virtual IShaderVariable* GetVariable(SHADER_TYPE ShaderType, Uint32 Index) = 0; + virtual IShaderResourceVariable* GetVariable(SHADER_TYPE ShaderType, Uint32 Index) = 0; /// Initializes static resources - /// If shaders in the pipeline state contain static resources - /// (see Diligent::SHADER_VARIABLE_TYPE_STATIC), this method must be called + /// If the parent pipeline state object contain static resources + /// (see Diligent::SHADER_RESOURCE_VARIABLE_TYPE_STATIC), this method must be called /// once to initialize static resources in this shader resource binding object. /// The method must be called after all static variables are initialized - /// in the shaders. + /// in the PSO. /// \param [in] pPipelineState - Pipeline state to copy static shader resource /// bindings from. The pipeline state must be compatible /// with this shader resource binding object. diff --git a/Graphics/GraphicsEngine/interface/ShaderResourceVariable.h b/Graphics/GraphicsEngine/interface/ShaderResourceVariable.h new file mode 100644 index 00000000..95b6eae5 --- /dev/null +++ b/Graphics/GraphicsEngine/interface/ShaderResourceVariable.h @@ -0,0 +1,134 @@ +/* Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Definition of the Diligent::IShaderResourceVariable interface and related data structures + +#include "../../../Primitives/interface/BasicTypes.h" +#include "../../../Primitives/interface/Object.h" +#include "DeviceObject.h" + +namespace Diligent +{ + +// {0D57DF3F-977D-4C8F-B64C-6675814BC80C} +static constexpr INTERFACE_ID IID_ShaderResourceVariable = +{ 0xd57df3f, 0x977d, 0x4c8f, { 0xb6, 0x4c, 0x66, 0x75, 0x81, 0x4b, 0xc8, 0xc } }; + + +/// Describes the type of the shader resource variable +enum SHADER_RESOURCE_VARIABLE_TYPE : Uint8 +{ + /// Shader resource bound to the variable is the same for all SRB instances. + /// It must be set *once* directly through Pipeline State object. + SHADER_RESOURCE_VARIABLE_TYPE_STATIC = 0, + + /// Shader resource bound to the variable is specific to the shader resource binding + /// instance (see Diligent::IShaderResourceBinding). It must be set *once* through + /// Diligent::IShaderResourceBinding interface. It cannot be set through Diligent::IPipelineState + /// interface and cannot be change once bound. + SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, + + /// Shader variable binding is dynamic. It can be set multiple times for every instance of shader resource + /// binding (see Diligent::IShaderResourceBinding). It cannot be set through Diligent::IPipelineState interface. + SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC, + + /// Total number of shader variable types + SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES +}; + + +static_assert(SHADER_RESOURCE_VARIABLE_TYPE_STATIC == 0 && SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE == 1 && SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC == 2 && SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES == 3, "BIND_SHADER_RESOURCES_UPDATE_* flags rely on shader variable SHADER_RESOURCE_VARIABLE_TYPE_* values being 0,1,2"); + +/// Shader resource binding flags +enum BIND_SHADER_RESOURCES_FLAGS : Uint32 +{ + /// Indicates that static shader variable bindings are to be updated. + BIND_SHADER_RESOURCES_UPDATE_STATIC = (0x01 << SHADER_RESOURCE_VARIABLE_TYPE_STATIC), + + /// Indicates that mutable shader variable bindings are to be updated. + BIND_SHADER_RESOURCES_UPDATE_MUTABLE = (0x01 << SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE), + + /// Indicates that dynamic shader variable bindings are to be updated. + BIND_SHADER_RESOURCES_UPDATE_DYNAMIC = (0x01 << SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC), + + /// Indicates that all shader variable types (static, mutable and dynamic) are to be updated. + /// \note If none of BIND_SHADER_RESOURCES_UPDATE_STATIC, BIND_SHADER_RESOURCES_UPDATE_MUTABLE, + /// and BIND_SHADER_RESOURCES_UPDATE_DYNAMIC flags are set, all variable types are updated + /// as if BIND_SHADER_RESOURCES_UPDATE_ALL was specified. + BIND_SHADER_RESOURCES_UPDATE_ALL = (BIND_SHADER_RESOURCES_UPDATE_STATIC | BIND_SHADER_RESOURCES_UPDATE_MUTABLE | BIND_SHADER_RESOURCES_UPDATE_DYNAMIC), + + /// If this flag is specified, all existing bindings will be preserved and + /// only unresolved ones will be updated. + /// If this flag is not specified, every shader variable will be + /// updated if the mapping contains corresponding resource. + BIND_SHADER_RESOURCES_KEEP_EXISTING = 0x08, + + /// If this flag is specified, all shader bindings are expected + /// to be resolved after the call. If this is not the case, debug message + /// will be displayed. + /// \note Only these variables are verified that are being updated by setting + /// BIND_SHADER_RESOURCES_UPDATE_STATIC, BIND_SHADER_RESOURCES_UPDATE_MUTABLE, and + /// BIND_SHADER_RESOURCES_UPDATE_DYNAMIC flags. + BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED = 0x10 +}; + + +/// Shader resource variable +class IShaderResourceVariable : public IObject +{ +public: + /// Binds resource to the variable + + /// \remark The method performs run-time correctness checks. + /// For instance, shader resource view cannot + /// be assigned to a constant buffer variable. + virtual void Set(IDeviceObject* pObject) = 0; + + /// Binds resource array to the variable + + /// \param [in] ppObjects - pointer to the array of objects + /// \param [in] FirstElement - first array element to set + /// \param [in] NumElements - number of objects in ppObjects array + /// + /// \remark The method performs run-time correctness checks. + /// For instance, shader resource view cannot + /// be assigned to a constant buffer variable. + virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements) = 0; + + /// Returns the shader resource variable type + virtual SHADER_RESOURCE_VARIABLE_TYPE GetType()const = 0; + + /// Returns array size. For non-array variables returns one. + virtual Uint32 GetArraySize()const = 0; + + /// Returns the variable name + virtual const Char* GetName()const = 0; + + /// Returns the variable index that can be used to access the variable. + virtual Uint32 GetIndex()const = 0; +}; + +} -- cgit v1.2.3