From 9c8f8d79c5cd62489b14127979e3cb0e2c08911f Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Wed, 6 Mar 2019 08:25:01 -0800 Subject: Reworked shader resource management in OpenGL --- Graphics/GraphicsEngineOpenGL/include/GLProgram.h | 5 +- .../include/GLProgramResources.h | 416 ++++++++---- .../GraphicsEngineOpenGL/include/ShaderGLImpl.h | 5 +- .../src/DeviceContextGLImpl.cpp | 68 +- Graphics/GraphicsEngineOpenGL/src/GLProgram.cpp | 8 +- .../src/GLProgramResources.cpp | 726 +++++++++++++++------ .../src/PipelineStateGLImpl.cpp | 10 +- Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp | 4 +- .../src/ShaderResourceBindingGLImpl.cpp | 16 +- 9 files changed, 866 insertions(+), 392 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/include/GLProgram.h b/Graphics/GraphicsEngineOpenGL/include/GLProgram.h index dbc0c6c8..930e7aac 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLProgram.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLProgram.h @@ -39,10 +39,7 @@ namespace Diligent void InitResources(RenderDeviceGLImpl* pDeviceGLImpl, SHADER_TYPE ShaderStage, - IObject& Owner, - const PipelineResourceLayoutDesc* pResourceLayout, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes); + IObject& Owner); void BindConstantResources(IResourceMapping* pResourceMapping, Uint32 Flags); diff --git a/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h b/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h index d75bb2a5..4a9b6efe 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h @@ -22,12 +22,16 @@ */ #pragma once + +#include + #include "GLObjectWrapper.h" #include "HashUtils.h" #include "ShaderBase.h" #include "SamplerGLImpl.h" #include "HashUtils.h" #include "ShaderResourceVariableBase.h" +#include "StringPool.h" #ifdef _DEBUG # define VERIFY_RESOURCE_BINDINGS @@ -39,18 +43,17 @@ namespace Diligent { public: GLProgramResources(){} + ~GLProgramResources(); GLProgramResources (GLProgramResources&& Program)noexcept; GLProgramResources (const GLProgramResources&) = delete; GLProgramResources& operator = (const GLProgramResources&) = delete; GLProgramResources& operator = ( GLProgramResources&&) = delete; - void LoadUniforms(class RenderDeviceGLImpl* pDeviceGLImpl, + void LoadUniforms(IObject& Owner, + class RenderDeviceGLImpl* pDeviceGLImpl, SHADER_TYPE ShaderStages, - GLuint GLProgram, - const PipelineResourceLayoutDesc* pResourceLayout, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes); + GLuint GLProgram); void Clone(class RenderDeviceGLImpl* pDeviceGLImpl, @@ -60,143 +63,223 @@ namespace Diligent const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, Uint32 NumAllowedTypes); - struct GLProgramVariableBase + struct GLProgramVariableBase : ShaderVariableBase { - GLProgramVariableBase(String _Name, - size_t _ArraySize, - SHADER_RESOURCE_VARIABLE_TYPE _VarType, - SHADER_RESOURCE_TYPE _ResourceType) : - Name ( std::move(_Name) ), - pResources (_ArraySize), - VarType (_VarType), - ResourceType(_ResourceType) +/* 0 */ // ShaderVariableBase +/* 16 */ const Char* Name; +/* 24 */ const SHADER_RESOURCE_VARIABLE_TYPE VariableType; +/* 25 */ const SHADER_RESOURCE_TYPE ResourceType; +/* 26 */ const Uint16 VariableIndex; +/* 28 */ Uint32 ArraySize; +/* 32 */ RefCntAutoPtr* const pResources; +/* 40 */ //End of data + + GLProgramVariableBase(IObject& _Owner, + const Char* _Name, + SHADER_RESOURCE_VARIABLE_TYPE _VariableType, + SHADER_RESOURCE_TYPE _ResourceType, + Uint16 _VariableIndex, + Uint32 _ArraySize, + RefCntAutoPtr* _pResources) : + ShaderVariableBase(_Owner), + Name (_Name), + ArraySize (_ArraySize), + VariableType (_VariableType), + VariableIndex (_VariableIndex), + ResourceType (_ResourceType), + pResources (_pResources) { VERIFY_EXPR(_ArraySize >= 1); } - bool IsCompatibleWith(const GLProgramVariableBase &Var)const + bool IsCompatibleWith(const GLProgramVariableBase& Var)const { - return VarType == Var.VarType && - pResources.size() == Var.pResources.size(); + return VariableType == Var.VariableType && + ResourceType == Var.ResourceType && + ArraySize == Var.ArraySize; } size_t GetHash()const { - return ComputeHash(static_cast(VarType), pResources.size()); + return ComputeHash(static_cast(VariableType), static_cast(ResourceType), ArraySize); + } + + virtual void Set(IDeviceObject* pObject)override final + { + VERIFY(pResources != nullptr, "This variable has no resource cache attached"); + pResources[0] = pObject; + } + + virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements)override final + { + VERIFY(pResources, "This variable has no resource cache attached"); + VERIFY(FirstElement + NumElements <= ArraySize, "Array indices are out of range"); + for (Uint32 i=0; i < NumElements; ++i) + pResources[FirstElement + i] = ppObjects[i]; + } + + virtual SHADER_RESOURCE_VARIABLE_TYPE GetType()const override final + { + return VariableType; + } + + virtual Uint32 GetArraySize()const override final + { + return ArraySize; + } + + virtual const Char* GetName()const override final + { + return Name; + } + + virtual Uint32 GetIndex()const override final + { + return VariableIndex; } ShaderResourceDesc GetResourceDesc()const { ShaderResourceDesc ResourceDesc; - ResourceDesc.Name = Name.c_str(); - ResourceDesc.ArraySize = static_cast(pResources.size()); + ResourceDesc.Name = Name; + ResourceDesc.ArraySize = ArraySize; ResourceDesc.Type = ResourceType; return ResourceDesc; } - - String Name; - std::vector< RefCntAutoPtr > pResources; - const SHADER_RESOURCE_VARIABLE_TYPE VarType; - const SHADER_RESOURCE_TYPE ResourceType; }; struct UniformBufferInfo : GLProgramVariableBase { - UniformBufferInfo(String _Name, - size_t _ArraySize, - SHADER_RESOURCE_VARIABLE_TYPE _VarType, - SHADER_RESOURCE_TYPE _ResourceType, - GLint _Index) : - GLProgramVariableBase(std::move(_Name), _ArraySize, _VarType, _ResourceType), - Index(_Index) + UniformBufferInfo (const UniformBufferInfo&) = delete; + UniformBufferInfo& operator= (const UniformBufferInfo&) = delete; + UniformBufferInfo ( UniformBufferInfo&&) = default; + UniformBufferInfo& operator= ( UniformBufferInfo&&) = default; + + UniformBufferInfo(IObject& _Owner, + const Char* _Name, + SHADER_RESOURCE_VARIABLE_TYPE _VariableType, + SHADER_RESOURCE_TYPE _ResourceType, + Uint16 _VariableIndex, + Uint32 _ArraySize, + RefCntAutoPtr* _pResources, + GLuint _UBIndex) : + GLProgramVariableBase(_Owner, _Name, _VariableType, _ResourceType, _VariableIndex, _ArraySize, _pResources), + UBIndex(_UBIndex) {} bool IsCompatibleWith(const UniformBufferInfo& UBI)const { - return Index == UBI.Index && + return UBIndex == UBI.UBIndex && GLProgramVariableBase::IsCompatibleWith(UBI); } size_t GetHash()const { - return ComputeHash(Index, GLProgramVariableBase::GetHash()); + return ComputeHash(UBIndex, GLProgramVariableBase::GetHash()); } - const GLuint Index; + const GLuint UBIndex; }; - std::vector& GetUniformBlocks(){ return m_UniformBlocks; } + static_assert( (sizeof(UniformBufferInfo) % sizeof(void*)) == 0, "sizeof(UniformBufferInfo) must be multiple of sizeof(void*)"); + struct SamplerInfo : GLProgramVariableBase { - SamplerInfo(String _Name, - size_t _ArraySize, - SHADER_RESOURCE_VARIABLE_TYPE _VarType, - SHADER_RESOURCE_TYPE _ResourceType, - GLint _Location, - GLenum _Type, - class SamplerGLImpl* _pStaticSampler) : - GLProgramVariableBase(std::move(_Name), _ArraySize, _VarType, _ResourceType), + SamplerInfo (const SamplerInfo&) = delete; + SamplerInfo& operator= (const SamplerInfo&) = delete; + SamplerInfo ( SamplerInfo&&) = default; + SamplerInfo& operator= ( SamplerInfo&&) = default; + + SamplerInfo(IObject& _Owner, + const Char* _Name, + SHADER_RESOURCE_VARIABLE_TYPE _VariableType, + SHADER_RESOURCE_TYPE _ResourceType, + Uint16 _VariableIndex, + Uint32 _ArraySize, + RefCntAutoPtr* _pResources, + GLint _Location, + GLenum _SamplerType, + class SamplerGLImpl* _pStaticSampler) : + GLProgramVariableBase(_Owner, _Name, _VariableType, _ResourceType, _VariableIndex, _ArraySize, _pResources), Location (_Location), - Type (_Type), + SamplerType (_SamplerType), pStaticSampler(_pStaticSampler) {} bool IsCompatibleWith(const SamplerInfo& SI)const { - return Location == SI.Location && - Type == SI.Type && + return Location == SI.Location && + pStaticSampler == SI.pStaticSampler && GLProgramVariableBase::IsCompatibleWith(SI); } size_t GetHash()const { - return ComputeHash(Location, Type, GLProgramVariableBase::GetHash()); + return ComputeHash(Location, SamplerType, GLProgramVariableBase::GetHash()); } const GLint Location; - const GLenum Type; + const GLenum SamplerType; RefCntAutoPtr pStaticSampler; }; - std::vector& GetSamplers(){ return m_Samplers; } - + static_assert( (sizeof(SamplerInfo) % sizeof(void*)) == 0, "sizeof(SamplerInfo) must be multiple of sizeof(void*)"); + + struct ImageInfo : GLProgramVariableBase { - ImageInfo(String _Name, - size_t _ArraySize, - SHADER_RESOURCE_VARIABLE_TYPE _VarType, - SHADER_RESOURCE_TYPE _ResourceType, - GLint _BindingPoint, - GLenum _Type) : - GLProgramVariableBase(std::move(_Name), _ArraySize, _VarType, _ResourceType), + ImageInfo (const ImageInfo&) = delete; + ImageInfo& operator= (const ImageInfo&) = delete; + ImageInfo ( ImageInfo&&) = default; + ImageInfo& operator= ( ImageInfo&&) = default; + + ImageInfo(IObject& _Owner, + const Char* _Name, + SHADER_RESOURCE_VARIABLE_TYPE _VariableType, + SHADER_RESOURCE_TYPE _ResourceType, + Uint16 _VariableIndex, + Uint32 _ArraySize, + RefCntAutoPtr* _pResources, + GLint _BindingPoint, + GLenum _ImageType) : + GLProgramVariableBase(_Owner, _Name, _VariableType, _ResourceType, _VariableIndex, _ArraySize, _pResources), BindingPoint(_BindingPoint), - Type (_Type) + ImageType (_ImageType) {} bool IsCompatibleWith(const ImageInfo& II)const { return BindingPoint == II.BindingPoint && - Type == II.Type && + ImageType == II.ImageType && GLProgramVariableBase::IsCompatibleWith(II); } size_t GetHash()const { - return ComputeHash(BindingPoint, Type, GLProgramVariableBase::GetHash()); + return ComputeHash(BindingPoint, ImageType, GLProgramVariableBase::GetHash()); } const GLint BindingPoint; - const GLenum Type; + const GLenum ImageType; }; - std::vector& GetImages(){ return m_Images; } + static_assert( (sizeof(ImageInfo) % sizeof(void*)) == 0, "sizeof(ImageInfo) must be multiple of sizeof(void*)"); + struct StorageBlockInfo : GLProgramVariableBase { - StorageBlockInfo(String _Name, - size_t _ArraySize, - SHADER_RESOURCE_VARIABLE_TYPE _VarType, - SHADER_RESOURCE_TYPE _ResourceType, - GLint _Binding) : - GLProgramVariableBase(std::move(_Name), _ArraySize, _VarType, _ResourceType), + StorageBlockInfo (const StorageBlockInfo&) = delete; + StorageBlockInfo& operator= (const StorageBlockInfo&) = delete; + StorageBlockInfo ( StorageBlockInfo&&) = default; + StorageBlockInfo& operator= ( StorageBlockInfo&&) = default; + + StorageBlockInfo(IObject& _Owner, + const Char* _Name, + SHADER_RESOURCE_VARIABLE_TYPE _VariableType, + SHADER_RESOURCE_TYPE _ResourceType, + Uint16 _VariableIndex, + Uint32 _ArraySize, + RefCntAutoPtr* _pResources, + GLint _Binding) : + GLProgramVariableBase(_Owner, _Name, _VariableType, _ResourceType, _VariableIndex, _ArraySize, _pResources), Binding(_Binding) {} @@ -213,99 +296,160 @@ namespace Diligent const GLint Binding; }; - std::vector& GetStorageBlocks(){ return m_StorageBlocks; } + static_assert( (sizeof(StorageBlockInfo) % sizeof(void*)) == 0, "sizeof(StorageBlockInfo) must be multiple of sizeof(void*)"); - struct CGLShaderVariable : ShaderVariableBase - { - CGLShaderVariable(IObject& Owner, GLProgramResources::GLProgramVariableBase& ProgVar, Uint32 _Index) : - ShaderVariableBase(Owner), - ProgramVar (ProgVar), - VariableIndex (_Index) - {} - - virtual void Set(IDeviceObject *pObject)override final - { - ProgramVar.pResources[0] = pObject; - } - - virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements)override final - { - for(Uint32 i=0; i < NumElements; ++i) - ProgramVar.pResources[FirstElement + i] = ppObjects[i]; - } + Uint32 GetNumUniformBuffers()const { return m_NumUniformBuffers; } + Uint32 GetNumSamplers() const { return m_NumSamplers; } + Uint32 GetNumImages() const { return m_NumImages; } + Uint32 GetNumStorageBlocks() const { return m_NumStorageBlocks; } - virtual SHADER_RESOURCE_VARIABLE_TYPE GetType()const override final - { - return ProgramVar.VarType; - } + UniformBufferInfo& GetUniformBuffer(Uint32 Index) + { + VERIFY(Index < m_NumUniformBuffers, "Uniform buffer index (", Index, ") is out of range"); + return m_UniformBuffers[Index]; + } - virtual Uint32 GetArraySize()const override final - { - return static_cast(ProgramVar.pResources.size()); - } + SamplerInfo& GetSampler(Uint32 Index) + { + VERIFY(Index < m_NumSamplers, "Sampler index (", Index, ") is out of range"); + return m_Samplers[Index]; + } - virtual const Char* GetName()const override final - { - return ProgramVar.Name.c_str(); - } + ImageInfo& GetImage(Uint32 Index) + { + VERIFY(Index < m_NumImages, "Image index (", Index, ") is out of range"); + return m_Images[Index]; + } - virtual Uint32 GetIndex()const override final - { - return VariableIndex; - } + StorageBlockInfo& GetStorageBlock(Uint32 Index) + { + VERIFY(Index < m_NumStorageBlocks, "Storage block index (", Index, ") is out of range"); + return m_StorageBlocks[Index]; + } - ShaderResourceDesc GetResourceDesc() const - { - return ProgramVar.GetResourceDesc(); - } - private: - GLProgramVariableBase& ProgramVar; - const Uint32 VariableIndex; - }; - void BindResources(IResourceMapping *pResourceMapping, Uint32 Flags); + const UniformBufferInfo& GetUniformBuffer(Uint32 Index)const + { + VERIFY(Index < m_NumUniformBuffers, "Uniform buffer index (", Index, ") is out of range"); + return m_UniformBuffers[Index]; + } -#ifdef VERIFY_RESOURCE_BINDINGS - void dbgVerifyResourceBindings(); -#endif + const SamplerInfo& GetSampler(Uint32 Index)const + { + VERIFY(Index < m_NumSamplers, "Sampler index (", Index, ") is out of range"); + return m_Samplers[Index]; + } - CGLShaderVariable* GetShaderVariable(const Char* Name); - CGLShaderVariable* GetShaderVariable(Uint32 Index) + const ImageInfo& GetImage(Uint32 Index)const { - return Index < m_VariablesByIndex.size() ? m_VariablesByIndex[Index] : nullptr; + VERIFY(Index < m_NumImages, "Image index (", Index, ") is out of range"); + return m_Images[Index]; } - const CGLShaderVariable* GetShaderVariable(Uint32 Index)const + + const StorageBlockInfo& GetStorageBlock(Uint32 Index)const { - return Index < m_VariablesByIndex.size() ? m_VariablesByIndex[Index] : nullptr; + VERIFY(Index < m_NumStorageBlocks, "Storage block index (", Index, ") is out of range"); + return m_StorageBlocks[Index]; } - const std::unordered_map& GetVariables(){return m_VariableHash;} - + Uint32 GetVariableCount()const { - return static_cast(m_VariableHash.size()); + return m_NumUniformBuffers + m_NumSamplers + m_NumImages + m_NumStorageBlocks; } + void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags); + +#ifdef VERIFY_RESOURCE_BINDINGS + void dbgVerifyResourceBindings()const; +#endif + + GLProgramVariableBase* GetVariable(const Char* Name); + GLProgramVariableBase* GetVariable(Uint32 Index) + { + return const_cast(const_cast(this)->GetVariable(Index)); + } + const GLProgramVariableBase* GetVariable(Uint32 Index)const; + bool IsCompatibleWith(const GLProgramResources& Res)const; size_t GetHash()const; - void InitVariables(IObject &Owner); - SHADER_TYPE GetShaderStages() const {return m_ShaderStages;} + template + void ProcessConstResources(THandleUB HandleUB, + THandleSampler HandleSampler, + THandleImg HandleImg, + THandleSB HandleSB)const + { + for (Uint32 ub=0; ub < m_NumUniformBuffers; ++ub) + HandleUB(GetUniformBuffer(ub)); + + for (Uint32 s=0; s < m_NumSamplers; ++s) + HandleSampler(GetSampler(s)); + + for (Uint32 img=0; img < m_NumImages; ++img) + HandleImg(GetImage(img)); + + for (Uint32 sb=0; sb < m_NumStorageBlocks; ++sb) + HandleSB(GetStorageBlock(sb)); + } private: + void AllocateResources(IObject& Owner, + std::vector& UniformBlocks, + std::vector& Samplers, + std::vector& Images, + std::vector& StorageBlocks, + bool InitializeResourceCache); + + template + void ProcessResources(THandleUB HandleUB, + THandleSampler HandleSampler, + THandleImg HandleImg, + THandleSB HandleSB) + { + for (Uint32 ub=0; ub < m_NumUniformBuffers; ++ub) + HandleUB(GetUniformBuffer(ub)); + + for (Uint32 s=0; s < m_NumSamplers; ++s) + HandleSampler(GetSampler(s)); + + for (Uint32 img=0; img < m_NumImages; ++img) + HandleImg(GetImage(img)); + + for (Uint32 sb=0; sb < m_NumStorageBlocks; ++sb) + HandleSB(GetStorageBlock(sb)); + } + // There could be more than one stage is using non-separable programs - SHADER_TYPE m_ShaderStages = SHADER_TYPE_UNKNOWN; - - std::vector m_UniformBlocks; - std::vector m_Samplers; - std::vector m_Images; - std::vector m_StorageBlocks; - - /// Hash map to look up shader variables by name. - std::unordered_map m_VariableHash; - std::vector m_VariablesByIndex; + SHADER_TYPE m_ShaderStages = SHADER_TYPE_UNKNOWN; + + // Memory layout: + // + // | Uniform buffers | Samplers | Images | Storage Blocks | Resource Cache | String Pool Data | + // | + // end of string pool data may not be aligned + + UniformBufferInfo* m_UniformBuffers = nullptr; + SamplerInfo* m_Samplers = nullptr; + ImageInfo* m_Images = nullptr; + StorageBlockInfo* m_StorageBlocks = nullptr; + RefCntAutoPtr* m_ResourceCache = nullptr; + + StringPool m_StringPool; + + Uint32 m_NumUniformBuffers = 0; + Uint32 m_NumSamplers = 0; + Uint32 m_NumImages = 0; + Uint32 m_NumStorageBlocks = 0; + // When adding new member DO NOT FORGET TO UPDATE GLProgramResources( GLProgramResources&& ProgramResources )!!! }; } diff --git a/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h index d579ef46..a9170c86 100644 --- a/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h @@ -73,12 +73,11 @@ public: ShaderGLImpl( IReferenceCounters *pRefCounters, RenderDeviceGLImpl *pDeviceGL, const ShaderCreateInfo &ShaderCreateInfo, bool bIsDeviceInternal = false ); ~ShaderGLImpl(); + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override final; + virtual Uint32 GetResourceCount()const override final; virtual ShaderResourceDesc GetResource(Uint32 Index)const override final; - virtual void QueryInterface( const INTERFACE_ID &IID, IObject **ppInterface )override final; - - GLProgram& GetGlProgram(){return m_GlProgObj;} private: diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index cddce1ea..619c0b55 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -389,7 +389,7 @@ namespace Diligent #endif // When program pipelines are not supported, all resources are dynamic resources - for (int BindDynamicResources = (ProgramPipelineSupported ? 0 : 1); BindDynamicResources < (pShaderResBindingGL ? 2 : 1); ++BindDynamicResources) + for (int BindDynamicResources = 0; BindDynamicResources < (pShaderResBindingGL ? 2 : 1); ++BindDynamicResources) { GLProgramResources& ProgResources = BindDynamicResources ? *pDynamicResources : m_pPipelineState->GetStaticResources(ProgNum); @@ -398,12 +398,12 @@ namespace Diligent #endif GLuint GLProgID = GLProgramObj; - auto& UniformBlocks = ProgResources.GetUniformBlocks(); - for (auto it = UniformBlocks.begin(); it != UniformBlocks.end(); ++it) + for (Uint32 ub = 0; ub < ProgResources.GetNumUniformBuffers(); ++ub) { - for(Uint32 ArrInd = 0; ArrInd < it->pResources.size(); ++ArrInd) + auto& UB = ProgResources.GetUniformBuffer(ub); + for(Uint32 ArrInd = 0; ArrInd < UB.ArraySize; ++ArrInd) { - auto& Resource = it->pResources[ArrInd]; + auto& Resource = UB.pResources[ArrInd]; if (Resource) { auto* pBufferOGL = Resource.RawPtr(); @@ -416,7 +416,7 @@ namespace Diligent CHECK_GL_ERROR("Failed to bind uniform buffer"); //glBindBufferRange(GL_UNIFORM_BUFFER, it->Index, pBufferOGL->m_GlBuffer, 0, pBufferOGL->GetDesc().uiSizeInBytes); - glUniformBlockBinding(GLProgID, it->Index + ArrInd, UniformBuffBindPoint); + glUniformBlockBinding(GLProgID, UB.UBIndex + ArrInd, UniformBuffBindPoint); CHECK_GL_ERROR("glUniformBlockBinding() failed"); ++UniformBuffBindPoint; @@ -425,28 +425,28 @@ namespace Diligent { #define LOG_MISSING_BINDING(VarType, Res, ArrInd)\ do{ \ - if(Res->pResources.size()>1) \ - LOG_ERROR_MESSAGE( "No ", VarType, " is bound to '", Res->Name, '[', ArrInd, "]' variable in shader '", pShaderGL->GetDesc().Name, "'" );\ + if(Res.ArraySize > 1) \ + LOG_ERROR_MESSAGE( "No ", VarType, " is bound to '", Res.Name, '[', ArrInd, "]' variable in shader '", pShaderGL->GetDesc().Name, "'" );\ else \ - LOG_ERROR_MESSAGE( "No ", VarType, " is bound to '", Res->Name, "' variable in shader '", pShaderGL->GetDesc().Name, "'" );\ + LOG_ERROR_MESSAGE( "No ", VarType, " is bound to '", Res.Name, "' variable in shader '", pShaderGL->GetDesc().Name, "'" );\ }while(false) - LOG_MISSING_BINDING("uniform buffer", it, ArrInd); + LOG_MISSING_BINDING("uniform buffer", UB, ArrInd); } } } - auto& Samplers = ProgResources.GetSamplers(); - for (auto it = Samplers.begin(); it != Samplers.end(); ++it) + for (Uint32 sam = 0; sam < ProgResources.GetNumSamplers(); ++sam) { - for (Uint32 ArrInd = 0; ArrInd < it->pResources.size(); ++ArrInd) + auto& Sam = ProgResources.GetSampler(sam); + for (Uint32 ArrInd = 0; ArrInd < Sam.ArraySize; ++ArrInd) { - auto& Resource = it->pResources[ArrInd]; + auto& Resource = Sam.pResources[ArrInd]; if (Resource) { - if (it->Type == GL_SAMPLER_BUFFER || - it->Type == GL_INT_SAMPLER_BUFFER || - it->Type == GL_UNSIGNED_INT_SAMPLER_BUFFER) + if (Sam.SamplerType == GL_SAMPLER_BUFFER || + Sam.SamplerType == GL_INT_SAMPLER_BUFFER || + Sam.SamplerType == GL_UNSIGNED_INT_SAMPLER_BUFFER) { auto* pBufViewOGL = Resource.RawPtr(); auto* pBuffer = pBufViewOGL->GetBuffer(); @@ -473,9 +473,9 @@ namespace Diligent m_ContextState); SamplerGLImpl* pSamplerGL = nullptr; - if (it->pStaticSampler) + if (Sam.pStaticSampler) { - pSamplerGL = it->pStaticSampler; + pSamplerGL = Sam.pStaticSampler; } else { @@ -494,12 +494,12 @@ namespace Diligent if (ProgramPipelineSupported) { // glProgramUniform1i does not require program to be bound to the pipeline - glProgramUniform1i( GLProgramObj, it->Location + ArrInd, TextureIndex ); + glProgramUniform1i( GLProgramObj, Sam.Location + ArrInd, TextureIndex ); } else { // glUniform1i requires program to be bound to the pipeline - glUniform1i(it->Location + ArrInd, TextureIndex); + glUniform1i(Sam.Location + ArrInd, TextureIndex); } CHECK_GL_ERROR("Failed to bind sampler uniform to texture slot"); @@ -507,18 +507,18 @@ namespace Diligent } else { - LOG_MISSING_BINDING("texture sampler", it, ArrInd); + LOG_MISSING_BINDING("texture sampler", Sam, ArrInd); } } } #if GL_ARB_shader_image_load_store - auto& Images = ProgResources.GetImages(); - for (auto it = Images.begin(); it != Images.end(); ++it) + for (Uint32 img = 0; img < ProgResources.GetNumImages(); ++img) { - for (Uint32 ArrInd = 0; ArrInd < it->pResources.size(); ++ArrInd) + auto& Img = ProgResources.GetImage(img); + for (Uint32 ArrInd = 0; ArrInd < Img.ArraySize; ++ArrInd) { - auto& Resource = it->pResources[ArrInd]; + auto& Resource = Img.pResources[ArrInd]; if (Resource) { auto* pTexViewOGL = Resource.RawPtr(); @@ -566,23 +566,23 @@ namespace Diligent // That means that if an integer texture is being bound, its // GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER must be NEAREST, // otherwise it will be incomplete - m_ContextState.BindImage(it->BindingPoint + ArrInd, pTexViewOGL, ViewDesc.MostDetailedMip, Layered, Layer, GLAccess, GlTexFormat); + m_ContextState.BindImage(Img.BindingPoint + ArrInd, pTexViewOGL, ViewDesc.MostDetailedMip, Layered, Layer, GLAccess, GlTexFormat); } else { - LOG_MISSING_BINDING("image", it, ArrInd); + LOG_MISSING_BINDING("image", Img, ArrInd); } } } #endif #if GL_ARB_shader_storage_buffer_object - auto& StorageBlocks = ProgResources.GetStorageBlocks(); - for (auto it = StorageBlocks.begin(); it != StorageBlocks.end(); ++it) + for (Uint32 sb=0; sb < ProgResources.GetNumStorageBlocks(); ++sb) { - for (Uint32 ArrInd = 0; ArrInd < it->pResources.size(); ++ArrInd) + auto& SB = ProgResources.GetStorageBlock(sb); + for (Uint32 ArrInd = 0; ArrInd < SB.ArraySize; ++ArrInd) { - auto& Resource = it->pResources[ArrInd]; + auto& Resource = SB.pResources[ArrInd]; if (Resource) { auto* pBufferViewOGL = Resource.RawPtr(); @@ -595,7 +595,7 @@ namespace Diligent // will reflect writes prior to the barrier m_ContextState); - glBindBufferRange(GL_SHADER_STORAGE_BUFFER, it->Binding + ArrInd, pBufferOGL->m_GlBuffer, ViewDesc.ByteOffset, ViewDesc.ByteWidth); + glBindBufferRange(GL_SHADER_STORAGE_BUFFER, SB.Binding + ArrInd, pBufferOGL->m_GlBuffer, ViewDesc.ByteOffset, ViewDesc.ByteWidth); CHECK_GL_ERROR("Failed to bind shader storage buffer"); if (ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS) @@ -603,7 +603,7 @@ namespace Diligent } else { - LOG_MISSING_BINDING("shader storage block", it, ArrInd); + LOG_MISSING_BINDING("shader storage block", SB, ArrInd); } } } diff --git a/Graphics/GraphicsEngineOpenGL/src/GLProgram.cpp b/Graphics/GraphicsEngineOpenGL/src/GLProgram.cpp index f4650151..a49669ea 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLProgram.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLProgram.cpp @@ -39,13 +39,9 @@ namespace Diligent void GLProgram::InitResources(RenderDeviceGLImpl* pDeviceGLImpl, SHADER_TYPE ShaderStage, - IObject& Owner, - const PipelineResourceLayoutDesc* pResourceLayout, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes) + IObject& Owner) { GLuint GLProgram = static_cast(*this); - m_AllResources.LoadUniforms(pDeviceGLImpl, ShaderStage, GLProgram, pResourceLayout, AllowedVarTypes, NumAllowedTypes); - m_AllResources.InitVariables(Owner); + m_AllResources.LoadUniforms(Owner, pDeviceGLImpl, ShaderStage, GLProgram); } } diff --git a/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp b/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp index 42dbf43f..21a2ac5d 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp @@ -22,20 +22,37 @@ */ #include "pch.h" +#include #include "GLProgramResources.h" #include "RenderDeviceGLImpl.h" #include "ShaderResourceBindingBase.h" +#include "Align.h" namespace Diligent { - GLProgramResources::GLProgramResources( GLProgramResources&& Program )noexcept : - m_UniformBlocks (std::move(Program.m_UniformBlocks)), - m_Samplers (std::move(Program.m_Samplers) ), - m_Images (std::move(Program.m_Images) ), - m_StorageBlocks (std::move(Program.m_StorageBlocks)), - m_VariableHash (std::move(Program.m_VariableHash) ), - m_VariablesByIndex(std::move(Program.m_VariablesByIndex) ) + GLProgramResources::GLProgramResources(GLProgramResources&& Program)noexcept : + m_ShaderStages (Program.m_ShaderStages), + m_UniformBuffers (Program.m_UniformBuffers), + m_Samplers (Program.m_Samplers), + m_Images (Program.m_Images), + m_StorageBlocks (Program.m_StorageBlocks), + m_ResourceCache (Program.m_ResourceCache), + m_StringPool (std::move(Program.m_StringPool)), + m_NumUniformBuffers(Program.m_NumUniformBuffers), + m_NumSamplers (Program.m_NumSamplers), + m_NumImages (Program.m_NumImages), + m_NumStorageBlocks (Program.m_NumStorageBlocks) { + Program.m_UniformBuffers = nullptr; + Program.m_Samplers = nullptr; + Program.m_Images = nullptr; + Program.m_StorageBlocks = nullptr; + Program.m_ResourceCache = nullptr; + + Program.m_NumUniformBuffers = 0; + Program.m_NumSamplers = 0; + Program.m_NumImages = 0; + Program.m_NumStorageBlocks = 0; } inline void RemoveArrayBrackets(char *Str) @@ -45,17 +62,237 @@ namespace Diligent *OpenBacketPtr = 0; } - void GLProgramResources::LoadUniforms(RenderDeviceGLImpl* pDeviceGLImpl, - SHADER_TYPE ShaderStages, - GLuint GLProgram, - const PipelineResourceLayoutDesc* pResourceLayout, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes) + void GLProgramResources::AllocateResources(IObject& Owner, + std::vector& UniformBlocks, + std::vector& Samplers, + std::vector& Images, + std::vector& StorageBlocks, + bool InitializeResourceCache) { + VERIFY(m_UniformBuffers == nullptr, "Resources have already been allocated!"); + + m_NumUniformBuffers = static_cast(UniformBlocks.size()); + m_NumSamplers = static_cast(Samplers.size()); + m_NumImages = static_cast(Images.size()); + m_NumStorageBlocks = static_cast(StorageBlocks.size()); + + size_t StringPoolDataSize = 0; + size_t ResourceCacheSize = 0; + for (const auto& ub : UniformBlocks) + { + StringPoolDataSize += strlen(ub.Name) + 1; + ResourceCacheSize += ub.ArraySize; + } + + for (const auto& sam : Samplers) + { + StringPoolDataSize += strlen(sam.Name) + 1; + ResourceCacheSize += sam.ArraySize; + } + + for (const auto& img : Images) + { + StringPoolDataSize += strlen(img.Name) + 1; + ResourceCacheSize += img.ArraySize; + } + + for (const auto& sb : StorageBlocks) + { + StringPoolDataSize += strlen(sb.Name) + 1; + ResourceCacheSize += sb.ArraySize; + } + + auto AlignedStringPoolDataSize = Align(StringPoolDataSize, sizeof(void*)); + + size_t TotalMemorySize = + m_NumUniformBuffers * sizeof(UniformBufferInfo) + + m_NumSamplers * sizeof(SamplerInfo) + + m_NumImages * sizeof(ImageInfo) + + m_NumStorageBlocks * sizeof(StorageBlockInfo); + + if (TotalMemorySize == 0) + { + m_UniformBuffers = nullptr; + m_Samplers = nullptr; + m_Images = nullptr; + m_StorageBlocks = nullptr; + m_ResourceCache = nullptr; + + m_NumUniformBuffers = 0; + m_NumSamplers = 0; + m_NumImages = 0; + m_NumStorageBlocks = 0; + + return; + } + + if (InitializeResourceCache) + TotalMemorySize += ResourceCacheSize * sizeof(RefCntAutoPtr); + + TotalMemorySize += AlignedStringPoolDataSize * sizeof(Char); + + auto& MemAllocator = GetRawAllocator(); + void* RawMemory = ALLOCATE(MemAllocator, "Memory buffer for GLProgramResources", TotalMemorySize); + + m_UniformBuffers = reinterpret_cast(RawMemory); + m_Samplers = reinterpret_cast (m_UniformBuffers + m_NumUniformBuffers); + m_Images = reinterpret_cast (m_Samplers + m_NumSamplers); + m_StorageBlocks = reinterpret_cast(m_Images + m_NumImages); + void* EndOfResourceData = m_StorageBlocks + m_NumStorageBlocks; + Char* StringPoolData = nullptr; + if (InitializeResourceCache) + { + m_ResourceCache = reinterpret_cast*>(EndOfResourceData); + StringPoolData = reinterpret_cast(m_ResourceCache + ResourceCacheSize); + for (Uint32 res=0; res < ResourceCacheSize; ++res) + new (m_ResourceCache+res) RefCntAutoPtr{}; + } + else + { + m_ResourceCache = nullptr; + StringPoolData = reinterpret_cast(EndOfResourceData); + } + + m_StringPool.AssignMemory(StringPoolData, StringPoolDataSize); + + Uint16 VariableIndex = 0; + auto* pCurrResource = m_ResourceCache; + for (Uint32 ub=0; ub < m_NumUniformBuffers; ++ub) + { + auto& SrcUB = UniformBlocks[ub]; + new (m_UniformBuffers + ub) UniformBufferInfo + { + Owner, + m_StringPool.CopyString(SrcUB.Name), + SrcUB.VariableType, + SrcUB.ResourceType, + VariableIndex++, + SrcUB.ArraySize, + pCurrResource, + SrcUB.UBIndex + }; + if (pCurrResource != nullptr) + pCurrResource += SrcUB.ArraySize; + } + + for (Uint32 s=0; s < m_NumSamplers; ++s) + { + auto& SrcSam = Samplers[s]; + new (m_Samplers + s) SamplerInfo + { + Owner, + m_StringPool.CopyString(SrcSam.Name), + SrcSam.VariableType, + SrcSam.ResourceType, + VariableIndex++, + SrcSam.ArraySize, + pCurrResource, + SrcSam.Location, + SrcSam.SamplerType, + SrcSam.pStaticSampler + }; + if (pCurrResource != nullptr) + pCurrResource += SrcSam.ArraySize; + } + + for (Uint32 img=0; img < m_NumImages; ++img) + { + auto& SrcImg = Images[img]; + new (m_Images + img) ImageInfo + { + Owner, + m_StringPool.CopyString(SrcImg.Name), + SrcImg.VariableType, + SrcImg.ResourceType, + VariableIndex++, + SrcImg.ArraySize, + pCurrResource, + SrcImg.BindingPoint, + SrcImg.ImageType + }; + if (pCurrResource != nullptr) + pCurrResource += SrcImg.ArraySize; + } + + for (Uint32 sb=0; sb < m_NumStorageBlocks; ++sb) + { + auto& SrcSB = StorageBlocks[sb]; + new (m_StorageBlocks + sb) StorageBlockInfo + { + Owner, + m_StringPool.CopyString(SrcSB.Name), + SrcSB.VariableType, + SrcSB.ResourceType, + VariableIndex++, + SrcSB.ArraySize, + pCurrResource, + SrcSB.Binding + }; + + if (pCurrResource != nullptr) + pCurrResource += SrcSB.ArraySize; + } + + VERIFY_EXPR(VariableIndex == GetVariableCount()); + VERIFY_EXPR(m_StringPool.GetRemainingSize() == 0); + VERIFY_EXPR(pCurrResource == nullptr || static_cast(pCurrResource - m_ResourceCache) == ResourceCacheSize); + } + + GLProgramResources::~GLProgramResources() + { + Uint32 ResourceCacheSize = 0; + ProcessResources( + [&](UniformBufferInfo& UB) + { + ResourceCacheSize += UB.ArraySize; + UB.~UniformBufferInfo(); + }, + [&](SamplerInfo& Sam) + { + ResourceCacheSize += Sam.ArraySize; + Sam.~SamplerInfo(); + }, + [&](ImageInfo& Img) + { + ResourceCacheSize += Img.ArraySize; + Img.~ImageInfo(); + }, + [&](StorageBlockInfo& SB) + { + ResourceCacheSize += SB.ArraySize; + SB.~StorageBlockInfo(); + } + ); + + if (m_ResourceCache != nullptr) + { + for (Uint32 res=0; res < ResourceCacheSize; ++res) + m_ResourceCache[res].~RefCntAutoPtr(); + } + + void* RawMemory = m_UniformBuffers; + if (RawMemory != nullptr) + { + auto& MemAllocator = GetRawAllocator(); + MemAllocator.Free(RawMemory); + } + } + + + void GLProgramResources::LoadUniforms(IObject& Owner, + RenderDeviceGLImpl* pDeviceGLImpl, + SHADER_TYPE ShaderStages, + GLuint GLProgram) + { + std::vector UniformBlocks; + std::vector Samplers; + std::vector Images; + std::vector StorageBlocks; + std::unordered_set NamesPool; + VERIFY(GLProgram != 0, "Null GL program"); m_ShaderStages = ShaderStages; - const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); GLint numActiveUniforms = 0; glGetProgramiv( GLProgram, GL_ACTIVE_UNIFORMS, &numActiveUniforms ); @@ -179,23 +416,19 @@ namespace Diligent // The latter is only available in GL 4.4 and GLES 3.1 RemoveArrayBrackets(Name.data()); - SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; - - RefCntAutoPtr pStaticSampler; - if (pResourceLayout != nullptr) - { - VarType = GetShaderVariableType(ShaderStages, Name.data(), *pResourceLayout); - for (Uint32 s = 0; s < pResourceLayout->NumStaticSamplers; ++s) - { - const auto& StSam = pResourceLayout->StaticSamplers[s]; - if (strcmp(Name.data(), StSam.SamplerOrTextureName) == 0) - { - pDeviceGLImpl->CreateSampler(StSam.Desc, reinterpret_cast(static_cast(&pStaticSampler)) ); - break; - } - } - } - m_Samplers.emplace_back( Name.data(), size, VarType, SHADER_RESOURCE_TYPE_TEXTURE_SRV, UniformLocation, dataType, pStaticSampler ); + + Samplers.emplace_back( + Owner, + NamesPool.emplace(Name.data()).first->c_str(), + SHADER_RESOURCE_VARIABLE_TYPE_STATIC, + SHADER_RESOURCE_TYPE_TEXTURE_SRV, + Uint16{0xFFFF}, // Variable index is assigned by AllocateResources + static_cast(size), + nullptr, // pResources + UniformLocation, + dataType, + nullptr + ); break; } @@ -243,10 +476,17 @@ namespace Diligent VERIFY( BindingPoint >= 0, "Incorrect binding point" ); RemoveArrayBrackets(Name.data()); - SHADER_RESOURCE_VARIABLE_TYPE VarType = (pResourceLayout != nullptr) ? - GetShaderVariableType(ShaderStages, Name.data(), *pResourceLayout) : - SHADER_RESOURCE_VARIABLE_TYPE_STATIC; - m_Images.emplace_back( Name.data(), size, VarType, SHADER_RESOURCE_TYPE_TEXTURE_UAV, BindingPoint, dataType ); + + Images.emplace_back( + Owner, + NamesPool.emplace(Name.data()).first->c_str(), + SHADER_RESOURCE_VARIABLE_TYPE_STATIC, + SHADER_RESOURCE_TYPE_TEXTURE_UAV, + Uint16{0xFFFF}, // Variable index is assigned by AllocateResources + static_cast(size), + nullptr, // pResources + BindingPoint, + dataType ); break; } #endif @@ -276,37 +516,42 @@ namespace Diligent GLint ArraySize = 1; auto* OpenBacketPtr = strchr(Name.data(), '['); - if(OpenBacketPtr != nullptr) + if (OpenBacketPtr != nullptr) { auto Ind = atoi(OpenBacketPtr+1); ArraySize = std::max(ArraySize, Ind+1); *OpenBacketPtr = 0; - if (m_UniformBlocks.size() > 0) + if (UniformBlocks.size() > 0) { // Look at previous uniform block to check if it is the same array - auto &LastBlock = m_UniformBlocks.back(); - if (LastBlock.Name.compare(Name.data()) == 0) + auto& LastBlock = UniformBlocks.back(); + if ( strcmp(LastBlock.Name, Name.data()) == 0) { - ArraySize = std::max(ArraySize, static_cast(LastBlock.pResources.size())); - VERIFY(UniformBlockIndex == LastBlock.Index + Ind, "Uniform block indices are expected to be continuous"); - LastBlock.pResources.resize(ArraySize); + ArraySize = std::max(ArraySize, static_cast(LastBlock.ArraySize)); + VERIFY(UniformBlockIndex == LastBlock.UBIndex + Ind, "Uniform block indices are expected to be continuous"); + LastBlock.ArraySize = ArraySize; continue; } else { #ifdef _DEBUG - for(const auto &ub : m_UniformBlocks) - VERIFY(ub.Name.compare(Name.data()) != 0, "Uniform block with the name \"", ub.Name, "\" has already been enumerated"); + for(const auto& ub : UniformBlocks) + VERIFY( strcmp(ub.Name, Name.data()) != 0, "Uniform block with the name \"", ub.Name, "\" has already been enumerated"); #endif } } } - - SHADER_RESOURCE_VARIABLE_TYPE VarType = (pResourceLayout != nullptr) ? - GetShaderVariableType(ShaderStages, Name.data(), *pResourceLayout) : - SHADER_RESOURCE_VARIABLE_TYPE_STATIC; - m_UniformBlocks.emplace_back( Name.data(), ArraySize, VarType, SHADER_RESOURCE_TYPE_CONSTANT_BUFFER, UniformBlockIndex ); + UniformBlocks.emplace_back( + Owner, + NamesPool.emplace(Name.data()).first->c_str(), + SHADER_RESOURCE_VARIABLE_TYPE_STATIC, + SHADER_RESOURCE_TYPE_CONSTANT_BUFFER, + Uint16{0xFFFF}, // Variable index is assigned by AllocateResources + static_cast(ArraySize), + nullptr, // pResources + UniformBlockIndex + ); } #if GL_ARB_shader_storage_buffer_object @@ -332,33 +577,40 @@ namespace Diligent auto Ind = atoi(OpenBacketPtr+1); ArraySize = std::max(ArraySize, Ind+1); *OpenBacketPtr = 0; - if (m_StorageBlocks.size() > 0) + if (StorageBlocks.size() > 0) { // Look at previous storage block to check if it is the same array - auto &LastBlock = m_StorageBlocks.back(); - if (LastBlock.Name.compare(Name.data()) == 0) + auto& LastBlock = StorageBlocks.back(); + if ( strcmp(LastBlock.Name, Name.data()) == 0) { - ArraySize = std::max(ArraySize, static_cast(LastBlock.pResources.size())); + ArraySize = std::max(ArraySize, static_cast(LastBlock.ArraySize)); VERIFY(Binding == LastBlock.Binding + Ind, "Storage block bindings are expected to be continuous"); - LastBlock.pResources.resize(ArraySize); + LastBlock.ArraySize = ArraySize; continue; } else { #ifdef _DEBUG - for(const auto &sb : m_StorageBlocks) - VERIFY(sb.Name.compare(Name.data()) != 0, "Storage block with the name \"", sb.Name, "\" has already been enumerated"); + for(const auto& sb : StorageBlocks) + VERIFY( strcmp(sb.Name, Name.data()) != 0, "Storage block with the name \"", sb.Name, "\" has already been enumerated"); #endif } } } - SHADER_RESOURCE_VARIABLE_TYPE VarType = (pResourceLayout != nullptr) ? - GetShaderVariableType(ShaderStages, Name.data(), *pResourceLayout) : - SHADER_RESOURCE_VARIABLE_TYPE_STATIC; - m_StorageBlocks.emplace_back( Name.data(), ArraySize, VarType, SHADER_RESOURCE_TYPE_BUFFER_UAV, Binding ); + StorageBlocks.emplace_back( + Owner, + NamesPool.emplace(Name.data()).first->c_str(), + SHADER_RESOURCE_VARIABLE_TYPE_STATIC, + SHADER_RESOURCE_TYPE_BUFFER_UAV, + Uint16{0xFFFF}, // Variable index is assigned by AllocateResources + static_cast(ArraySize), + nullptr, // pResources + Binding + ); } #endif + AllocateResources(Owner, UniformBlocks, Samplers, Images, StorageBlocks, false); } @@ -369,129 +621,200 @@ namespace Diligent const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, Uint32 NumAllowedTypes) { + std::vector UniformBlocks; + std::vector Samplers; + std::vector Images; + std::vector StorageBlocks; + m_ShaderStages = SrcResources.m_ShaderStages; const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes); - for (auto& ub : SrcResources.m_UniformBlocks) + for (Uint32 ub=0; ub < SrcResources.GetNumUniformBuffers(); ++ub) { - auto VarType = GetShaderVariableType(m_ShaderStages, ub.Name.data(), ResourceLayout); - if (IsAllowedType(VarType, VarType)) + const auto& SrcUB = SrcResources.GetUniformBuffer(ub); + auto VarType = GetShaderVariableType(m_ShaderStages, SrcUB.Name, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) { - m_UniformBlocks.emplace_back(ub.Name, ub.pResources.size(), ub.VarType, ub.ResourceType, ub.Index); + UniformBlocks.emplace_back( + Owner, + SrcUB.Name, + VarType, + SrcUB.ResourceType, + Uint16{0xFFFF}, // Variable index is assigned by AllocateResources + SrcUB.ArraySize, + nullptr, // pResources + SrcUB.UBIndex + ); } } - for (auto& sam : SrcResources.m_Samplers) + for (Uint32 sam = 0; sam < SrcResources.GetNumSamplers(); ++sam) { - auto VarType = GetShaderVariableType(m_ShaderStages, sam.Name.data(), ResourceLayout); - if (IsAllowedType(VarType, VarType)) + const auto& SrcSam = SrcResources.GetSampler(sam); + auto VarType = GetShaderVariableType(m_ShaderStages, SrcSam.Name, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) { RefCntAutoPtr pStaticSampler; for (Uint32 s = 0; s < ResourceLayout.NumStaticSamplers; ++s) { const auto& StSam = ResourceLayout.StaticSamplers[s]; - if (strcmp(sam.Name.data(), StSam.SamplerOrTextureName) == 0) + if (strcmp(SrcSam.Name, StSam.SamplerOrTextureName) == 0) { pDeviceGLImpl->CreateSampler(StSam.Desc, &pStaticSampler); break; } } - m_Samplers.emplace_back(sam.Name, sam.pResources.size(), sam.VarType, sam.ResourceType, sam.Location, sam.Type, pStaticSampler.RawPtr()); + Samplers.emplace_back( + Owner, + SrcSam.Name, + VarType, + SrcSam.ResourceType, + Uint16{0xFFFF}, // Variable index is assigned by AllocateResources + SrcSam.ArraySize, + nullptr, // pResources + SrcSam.Location, + SrcSam.SamplerType, + pStaticSampler.RawPtr() + ); } } - for (auto& img : SrcResources.m_Images) + for (Uint32 img = 0; img < SrcResources.GetNumImages(); ++img) { - auto VarType = GetShaderVariableType(m_ShaderStages, img.Name.data(), ResourceLayout); - if (IsAllowedType(VarType, VarType)) + const auto& SrcImg = SrcResources.GetImage(img); + auto VarType = GetShaderVariableType(m_ShaderStages, SrcImg.Name, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) { - m_Images.emplace_back(img.Name, img.pResources.size(), img.VarType, img.ResourceType, img.BindingPoint, img.Type); + Images.emplace_back( + Owner, + SrcImg.Name, + VarType, + SrcImg.ResourceType, + Uint16{0xFFFF}, // Variable index is assigned by AllocateResources + SrcImg.ArraySize, + nullptr, // pResources + SrcImg.BindingPoint, + SrcImg.ImageType + ); } } - for (auto& sb : SrcResources.m_StorageBlocks) + for (Uint32 sb = 0; sb < SrcResources.GetNumStorageBlocks(); ++sb) { - auto VarType = GetShaderVariableType(m_ShaderStages, sb.Name.data(), ResourceLayout); - if (IsAllowedType(VarType, VarType)) + const auto& SrcSB = SrcResources.GetStorageBlock(sb); + auto VarType = GetShaderVariableType(m_ShaderStages, SrcSB.Name, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) { - m_StorageBlocks.emplace_back(sb.Name, sb.pResources.size(), sb.VarType, sb.ResourceType, sb.Binding); + StorageBlocks.emplace_back( + Owner, + SrcSB.Name, + VarType, + SrcSB.ResourceType, + Uint16{0xFFFF}, // Variable index is assigned by AllocateResources + SrcSB.ArraySize, + nullptr, // pResources + SrcSB.Binding + ); } } - InitVariables(Owner); + AllocateResources(Owner, UniformBlocks, Samplers, Images, StorageBlocks, true); } - void GLProgramResources::InitVariables(IObject& Owner) - { - // After all program resources are loaded, we can populate shader variable hash map. - // The map contains raw pointers, but none of the arrays will ever change. - auto TotalVars = m_UniformBlocks.size() + m_Samplers.size() + m_Images.size() + m_StorageBlocks.size(); - m_VariablesByIndex.reserve(TotalVars); - m_VariableHash.reserve(TotalVars); -#define STORE_SHADER_VARIABLES(ResArr)\ - { \ - for( auto& ProgVar : ResArr) \ - { \ - /* HashMapStringKey will make a copy of the string*/ \ - auto it = m_VariableHash.insert( std::make_pair( Diligent::HashMapStringKey(ProgVar.Name), CGLShaderVariable(Owner, ProgVar, static_cast(m_VariablesByIndex.size())) ) ); \ - VERIFY_EXPR(it.second); \ - m_VariablesByIndex.push_back(&it.first->second); \ - } \ - } - - STORE_SHADER_VARIABLES(m_UniformBlocks) - STORE_SHADER_VARIABLES(m_Samplers) - STORE_SHADER_VARIABLES(m_Images) - STORE_SHADER_VARIABLES(m_StorageBlocks) -#undef STORE_SHADER_VARIABLES - } - GLProgramResources::CGLShaderVariable* GLProgramResources::GetShaderVariable( const Char* Name ) + + GLProgramResources::GLProgramVariableBase* GLProgramResources::GetVariable(const Char* Name) { // Name will be implicitly converted to HashMapStringKey without making a copy - auto it = m_VariableHash.find( Name ); - if( it == m_VariableHash.end() ) + for (Uint32 ub=0; ub < m_NumUniformBuffers; ++ub) { - return nullptr; + auto& UB = GetUniformBuffer(ub); + if (strcmp(UB.Name, Name) == 0) + return &UB; } - return &it->second; + + for (Uint32 s=0; s < m_NumSamplers; ++s) + { + auto& Sam = GetSampler(s); + if (strcmp(Sam.Name, Name) == 0) + return &Sam; + } + + for (Uint32 img=0; img < m_NumImages; ++img) + { + auto& Img = GetImage(img); + if (strcmp(Img.Name, Name) == 0) + return &Img; + } + + for (Uint32 sb=0; sb < m_NumStorageBlocks; ++sb) + { + auto& SB = GetStorageBlock(sb); + if (strcmp(SB.Name, Name) == 0) + return &SB; + } + + return nullptr; } - template - void BindResourcesHelper(TResArrayType &ResArr, IResourceMapping *pResourceMapping, Uint32 Flags) + const GLProgramResources::GLProgramVariableBase* GLProgramResources::GetVariable(Uint32 Index)const { - for (auto& res : ResArr) - { - if ( (Flags & (1 << res.VarType)) == 0 ) - continue; + if (Index < GetNumUniformBuffers()) + return &GetUniformBuffer(Index); + else + Index -= GetNumUniformBuffers(); + + if (Index < GetNumSamplers()) + return &GetSampler(Index); + else + Index -= GetNumSamplers(); + + if (Index < GetNumImages()) + return &GetImage(Index); + else + Index -= GetNumImages(); + + if (Index < GetNumStorageBlocks()) + return &GetStorageBlock(Index); + else + Index -= GetNumStorageBlocks(); + + return nullptr; + } - auto &Name = res.Name; - for(Uint32 ArrInd = 0; ArrInd < res.pResources.size(); ++ArrInd) - { - auto &CurrResource = res.pResources[ArrInd]; - if( (Flags & BIND_SHADER_RESOURCES_KEEP_EXISTING) && CurrResource ) - continue; // Skip already resolved resources + static void BindResourcesHelper(GLProgramResources::GLProgramVariableBase& res, IResourceMapping* pResourceMapping, Uint32 Flags) + { + if ( (Flags & (1 << res.VariableType)) == 0 ) + return; - RefCntAutoPtr pNewRes; - pResourceMapping->GetResource( Name.c_str(), static_cast(&pNewRes), ArrInd ); + auto& Name = res.Name; + for(Uint32 ArrInd = 0; ArrInd < res.ArraySize; ++ArrInd) + { + auto& CurrResource = res.pResources[ArrInd]; - if (pNewRes != nullptr) - { - if(res.VarType == SHADER_RESOURCE_VARIABLE_TYPE_STATIC && CurrResource != nullptr && CurrResource != pNewRes ) - LOG_ERROR_MESSAGE( "Updating binding for static variable \"", Name, "\" is invalid and may result in an undefined behavior" ); - CurrResource = pNewRes; - } - else - { - if ( CurrResource == nullptr && (Flags & BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED) ) - LOG_ERROR_MESSAGE("Resource \"", Name, "\" is not found in the resource mapping"); - } + if( (Flags & BIND_SHADER_RESOURCES_KEEP_EXISTING) != 0 && CurrResource ) + continue; // Skip already resolved resources + + RefCntAutoPtr pNewRes; + pResourceMapping->GetResource( Name, static_cast(&pNewRes), ArrInd ); + + if (pNewRes != nullptr) + { + if(res.VariableType == SHADER_RESOURCE_VARIABLE_TYPE_STATIC && CurrResource != nullptr && CurrResource != pNewRes ) + LOG_ERROR_MESSAGE( "Updating binding for static variable \"", Name, "\" is invalid and may result in an undefined behavior" ); + CurrResource = pNewRes; + } + else + { + if ( CurrResource == nullptr && (Flags & BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED) ) + LOG_ERROR_MESSAGE("Resource \"", Name, "\" is not found in the resource mapping"); } } } - void GLProgramResources::BindResources( IResourceMapping *pResourceMapping, Uint32 Flags ) + + void GLProgramResources::BindResources(IResourceMapping* pResourceMapping, Uint32 Flags ) { if( !pResourceMapping ) return; @@ -499,48 +822,63 @@ namespace Diligent if ( (Flags & BIND_SHADER_RESOURCES_UPDATE_ALL) == 0 ) Flags |= BIND_SHADER_RESOURCES_UPDATE_ALL; - BindResourcesHelper( m_UniformBlocks, pResourceMapping, Flags ); - BindResourcesHelper( m_Samplers, pResourceMapping, Flags ); - BindResourcesHelper( m_Images, pResourceMapping, Flags ); - BindResourcesHelper( m_StorageBlocks, pResourceMapping, Flags ); + ProcessResources( + [&](UniformBufferInfo& UB) + { + BindResourcesHelper(UB, pResourceMapping, Flags); + }, + [&](SamplerInfo& Sam) + { + BindResourcesHelper(Sam, pResourceMapping, Flags); + }, + [&](ImageInfo& Img) + { + BindResourcesHelper(Img, pResourceMapping, Flags); + }, + [&](StorageBlockInfo& SB) + { + BindResourcesHelper(SB, pResourceMapping, Flags); + } + ); } + bool GLProgramResources::IsCompatibleWith(const GLProgramResources& Res)const { - if (m_UniformBlocks.size() != Res.m_UniformBlocks.size() || - m_Samplers.size() != Res.m_Samplers.size() || - m_Images.size() != Res.m_Images.size() || - m_StorageBlocks.size() != Res.m_StorageBlocks.size()) + if (GetNumUniformBuffers() != Res.GetNumUniformBuffers() || + GetNumSamplers() != Res.GetNumSamplers() || + GetNumImages() != Res.GetNumImages() || + GetNumStorageBlocks() != Res.GetNumStorageBlocks()) return false; - for (size_t ub = 0; ub < m_UniformBlocks.size(); ++ub) + for (Uint32 ub = 0; ub < GetNumUniformBuffers(); ++ub) { - const auto &UB0 = m_UniformBlocks[ub]; - const auto &UB1 = Res.m_UniformBlocks[ub]; + const auto& UB0 = GetUniformBuffer(ub); + const auto& UB1 = Res.GetUniformBuffer(ub); if(!UB0.IsCompatibleWith(UB1)) return false; } - for (size_t sam = 0; sam < m_Samplers.size(); ++sam) + for (Uint32 sam = 0; sam < GetNumSamplers(); ++sam) { - const auto &Sam0 = m_Samplers[sam]; - const auto &Sam1 = Res.m_Samplers[sam]; + const auto& Sam0 = GetSampler(sam); + const auto& Sam1 = Res.GetSampler(sam); if (!Sam0.IsCompatibleWith(Sam1)) return false; } - for (size_t img = 0; img < m_Images.size(); ++img) + for (Uint32 img = 0; img < GetNumImages(); ++img) { - const auto &Img0 = m_Images[img]; - const auto &Img1 = Res.m_Images[img]; + const auto& Img0 = GetImage(img); + const auto& Img1 = Res.GetImage(img); if (!Img0.IsCompatibleWith(Img1)) return false; } - for (size_t sb = 0; sb < m_StorageBlocks.size(); ++sb) + for (Uint32 sb = 0; sb < GetNumStorageBlocks(); ++sb) { - const auto &SB0 = m_StorageBlocks[sb]; - const auto &SB1 = Res.m_StorageBlocks[sb]; + const auto& SB0 = GetStorageBlock(sb); + const auto& SB1 = Res.GetStorageBlock(sb); if (!SB0.IsCompatibleWith(SB1)) return false; } @@ -548,58 +886,68 @@ namespace Diligent return true; } + size_t GLProgramResources::GetHash()const { - size_t hash = ComputeHash(m_UniformBlocks.size(), m_Samplers.size(), m_Images.size(), m_StorageBlocks.size()); - - for (auto ub = m_UniformBlocks.begin(); ub != m_UniformBlocks.end(); ++ub) - { - HashCombine(hash, ub->GetHash()); - } - - for (auto sam = m_Samplers.begin(); sam != m_Samplers.end(); ++sam) - { - HashCombine(hash, sam->GetHash()); - } - - for (auto img = m_Images.begin(); img != m_Images.end(); ++img) - { - HashCombine(hash, img->GetHash()); - } + size_t hash = ComputeHash(GetNumUniformBuffers(), GetNumSamplers(), GetNumImages(), GetNumStorageBlocks()); - for (auto sb = m_StorageBlocks.begin(); sb != m_StorageBlocks.end(); ++sb) - { - HashCombine(hash, sb->GetHash()); - } + ProcessConstResources( + [&](const UniformBufferInfo& UB) + { + HashCombine(hash, UB.GetHash()); + }, + [&](const SamplerInfo& Sam) + { + HashCombine(hash, Sam.GetHash()); + }, + [&](const ImageInfo& Img) + { + HashCombine(hash, Img.GetHash()); + }, + [&](const StorageBlockInfo& SB) + { + HashCombine(hash, SB.GetHash()); + } + ); return hash; } #ifdef VERIFY_RESOURCE_BINDINGS - template - void dbgVerifyResourceBindingsHelper(TResArrayType &ResArr, const Char *VarType) + static void dbgVerifyResourceBindingsHelper(const GLProgramResources::GLProgramVariableBase& res, const Char* VarTypeName) { - for( auto res = ResArr.begin(); res != ResArr.end(); ++res ) + for(Uint32 ArrInd = 0; ArrInd < res.ArraySize; ++ArrInd) { - for(Uint32 ArrInd = 0; ArrInd < res->pResources.size(); ++ArrInd) + if( !res.pResources[ArrInd] ) { - if( !res->pResources[ArrInd] ) - { - if( res->pResources.size() > 1) - LOG_ERROR_MESSAGE( "No resource is bound to ", VarType, " variable \"", res->Name, "[", ArrInd, "]\"" ); - else - LOG_ERROR_MESSAGE( "No resource is bound to ", VarType, " variable \"", res->Name, "\"" ); - } + if( res.ArraySize > 1) + LOG_ERROR_MESSAGE( "No resource is bound to ", VarTypeName, " variable \"", res.Name, "[", ArrInd, "]\"" ); + else + LOG_ERROR_MESSAGE( "No resource is bound to ", VarTypeName, " variable \"", res.Name, "\"" ); } } } - void GLProgramResources::dbgVerifyResourceBindings() + void GLProgramResources::dbgVerifyResourceBindings()const { - dbgVerifyResourceBindingsHelper( m_UniformBlocks, "uniform block" ); - dbgVerifyResourceBindingsHelper( m_Samplers, "sampler" ); - dbgVerifyResourceBindingsHelper( m_Images, "image" ); - dbgVerifyResourceBindingsHelper( m_StorageBlocks, "shader storage block" ); + ProcessConstResources( + [&](const UniformBufferInfo& UB) + { + dbgVerifyResourceBindingsHelper(UB, "uniform block"); + }, + [&](const SamplerInfo& Sam) + { + dbgVerifyResourceBindingsHelper(Sam, "sampler"); + }, + [&](const ImageInfo& Img) + { + dbgVerifyResourceBindingsHelper(Img, "image"); + }, + [&](const StorageBlockInfo& SB) + { + dbgVerifyResourceBindingsHelper(SB, "shader storage block"); + } + ); } #endif diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp index 25ee1d17..86109db4 100644 --- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp @@ -116,7 +116,7 @@ void PipelineStateGLImpl::LinkGLProgram(bool bIsProgramPipelineSupported) } auto pDeviceGL = GetDevice(); - m_GLProgram.InitResources(pDeviceGL, ShaderStages, *this, &m_Desc.ResourceLayout, nullptr, 0); + m_GLProgram.InitResources(pDeviceGL, ShaderStages, *this); m_StaticResources.resize(1); const SHADER_RESOURCE_VARIABLE_TYPE StaticVars[] = {SHADER_RESOURCE_VARIABLE_TYPE_STATIC}; @@ -212,12 +212,12 @@ IShaderResourceVariable* PipelineStateGLImpl::GetStaticShaderVariable(SHADER_TYP { if (m_GLProgram) { - return m_StaticResources[0].GetShaderVariable(Name); + return m_StaticResources[0].GetVariable(Name); } else { const auto LayoutInd = m_ResourceLayoutIndex[GetShaderTypeIndex(ShaderType)]; - return LayoutInd >= 0 ? m_StaticResources[LayoutInd].GetShaderVariable(Name) : nullptr; + return LayoutInd >= 0 ? m_StaticResources[LayoutInd].GetVariable(Name) : nullptr; } } @@ -225,12 +225,12 @@ IShaderResourceVariable* PipelineStateGLImpl::GetStaticShaderVariable(SHADER_TYP { if (m_GLProgram) { - return m_StaticResources[0].GetShaderVariable(Index); + return m_StaticResources[0].GetVariable(Index); } else { const auto LayoutInd = m_ResourceLayoutIndex[GetShaderTypeIndex(ShaderType)]; - return LayoutInd >= 0 ? m_StaticResources[LayoutInd].GetShaderVariable(Index) : nullptr; + return LayoutInd >= 0 ? m_StaticResources[LayoutInd].GetVariable(Index) : nullptr; } } diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp index 278f79de..e42ca9ef 100644 --- a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp @@ -160,7 +160,7 @@ ShaderGLImpl::ShaderGLImpl(IReferenceCounters* pRefCounters, // boolean status bit DELETE_STATUS is set to true ShaderObj.Release(); - m_GlProgObj.InitResources(pDeviceGL, m_Desc.ShaderType, *this, nullptr, nullptr, 0); + m_GlProgObj.InitResources(pDeviceGL, m_Desc.ShaderType, *this); } else { @@ -194,7 +194,7 @@ ShaderResourceDesc ShaderGLImpl::GetResource(Uint32 Index)const if (m_GlProgObj) { DEV_CHECK_ERR(Index < GetResourceCount(), "Index is out of range"); - ResourceDesc = m_GlProgObj.GetResources().GetShaderVariable(Index)->GetResourceDesc(); + ResourceDesc = m_GlProgObj.GetResources().GetVariable(Index)->GetResourceDesc(); } else { diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp index 15086b05..2028b5eb 100644 --- a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp @@ -53,8 +53,7 @@ ShaderResourceBindingGLImpl::ShaderResourceBindingGLImpl(IReferenceCounters* pRe } else { - // Clone all variable types - SHADER_RESOURCE_VARIABLE_TYPE VarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_STATIC, SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}; + SHADER_RESOURCE_VARIABLE_TYPE VarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}; m_DynamicProgResources[0].Clone(pPSO->GetDevice(), *this, pPSO->GetGLProgram().GetResources(), pPSO->GetDesc().ResourceLayout, VarTypes, _countof(VarTypes)); } } @@ -97,7 +96,7 @@ void ShaderResourceBindingGLImpl::BindResources(Uint32 ShaderFlags, IResourceMap IShaderResourceVariable* ShaderResourceBindingGLImpl::GetVariable(SHADER_TYPE ShaderType, const char* Name) { auto ShaderInd = IsUsingSeparatePrograms() ? GetShaderTypeIndex(ShaderType) : 0; - return m_DynamicProgResources[ShaderInd].GetShaderVariable(Name); + return m_DynamicProgResources[ShaderInd].GetVariable(Name); } Uint32 ShaderResourceBindingGLImpl::GetVariableCount(SHADER_TYPE ShaderType) const @@ -109,7 +108,7 @@ Uint32 ShaderResourceBindingGLImpl::GetVariableCount(SHADER_TYPE ShaderType) con IShaderResourceVariable* ShaderResourceBindingGLImpl::GetVariable(SHADER_TYPE ShaderType, Uint32 Index) { auto ShaderInd = IsUsingSeparatePrograms() ? GetShaderTypeIndex(ShaderType) : 0; - return m_DynamicProgResources[ShaderInd].GetShaderVariable(Index); + return m_DynamicProgResources[ShaderInd].GetVariable(Index); } static GLProgramResources NullProgramResources; @@ -127,15 +126,6 @@ GLProgramResources& ShaderResourceBindingGLImpl::GetProgramResources(SHADER_TYPE void ShaderResourceBindingGLImpl::InitializeStaticResources(const IPipelineState* pPipelineState) { - if (!IsUsingSeparatePrograms()) - { - //if (pPipelineState != nullptr) - //{ - // const auto* PSOGL = ValidatedCast(pPipelineState); - // ResourceMappingProxy StaticResMapping(*PSOGL); - // m_DynamicProgResources[0].BindResources(&StaticResMapping, 0); - //} - } } } -- cgit v1.2.3