summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineOpenGL
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2019-03-06 16:25:01 +0000
committerEgor Yusov <egor.yusov@gmail.com>2019-03-06 16:25:01 +0000
commit9c8f8d79c5cd62489b14127979e3cb0e2c08911f (patch)
tree55c879da017669b88a19d25d3ef7e641efec08ff /Graphics/GraphicsEngineOpenGL
parentFixed swap chain build error on iOS (diff)
downloadDiligentCore-9c8f8d79c5cd62489b14127979e3cb0e2c08911f.tar.gz
DiligentCore-9c8f8d79c5cd62489b14127979e3cb0e2c08911f.zip
Reworked shader resource management in OpenGL
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/GLProgram.h5
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h416
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h5
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp68
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/GLProgram.cpp8
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp726
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp10
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp4
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp16
9 files changed, 866 insertions, 392 deletions
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 <vector>
+
#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<IDeviceObject>* 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<IDeviceObject>* _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<Int32>(VarType), pResources.size());
+ return ComputeHash(static_cast<Int32>(VariableType), static_cast<Int32>(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<Uint32>(pResources.size());
+ ResourceDesc.Name = Name;
+ ResourceDesc.ArraySize = ArraySize;
ResourceDesc.Type = ResourceType;
return ResourceDesc;
}
-
- String Name;
- std::vector< RefCntAutoPtr<IDeviceObject> > 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<IDeviceObject>* _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<UniformBufferInfo>& 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<IDeviceObject>* _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<class SamplerGLImpl> pStaticSampler;
};
- std::vector<SamplerInfo>& 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<IDeviceObject>* _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<ImageInfo>& 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<IDeviceObject>* _pResources,
+ GLint _Binding) :
+ GLProgramVariableBase(_Owner, _Name, _VariableType, _ResourceType, _VariableIndex, _ArraySize, _pResources),
Binding(_Binding)
{}
@@ -213,99 +296,160 @@ namespace Diligent
const GLint Binding;
};
- std::vector<StorageBlockInfo>& 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<Uint32>(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<HashMapStringKey, CGLShaderVariable, HashMapStringKey::Hasher>& GetVariables(){return m_VariableHash;}
-
+
Uint32 GetVariableCount()const
{
- return static_cast<Uint32>(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<GLProgramVariableBase*>(const_cast<const GLProgramResources*>(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<typename THandleUB,
+ typename THandleSampler,
+ typename THandleImg,
+ typename THandleSB>
+ 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<UniformBufferInfo>& UniformBlocks,
+ std::vector<SamplerInfo>& Samplers,
+ std::vector<ImageInfo>& Images,
+ std::vector<StorageBlockInfo>& StorageBlocks,
+ bool InitializeResourceCache);
+
+ template<typename THandleUB,
+ typename THandleSampler,
+ typename THandleImg,
+ typename THandleSB>
+ 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<UniformBufferInfo> m_UniformBlocks;
- std::vector<SamplerInfo> m_Samplers;
- std::vector<ImageInfo> m_Images;
- std::vector<StorageBlockInfo> m_StorageBlocks;
-
- /// Hash map to look up shader variables by name.
- std::unordered_map<HashMapStringKey, CGLShaderVariable, HashMapStringKey::Hasher> m_VariableHash;
- std::vector<CGLShaderVariable*> 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<IDeviceObject>* 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<BufferGLImpl>();
@@ -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<BufferViewGLImpl>();
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<TextureViewGLImpl>();
@@ -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<BufferViewGLImpl>();
@@ -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<GLuint>(*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 <unordered_set>
#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<UniformBufferInfo>& UniformBlocks,
+ std::vector<SamplerInfo>& Samplers,
+ std::vector<ImageInfo>& Images,
+ std::vector<StorageBlockInfo>& StorageBlocks,
+ bool InitializeResourceCache)
{
+ VERIFY(m_UniformBuffers == nullptr, "Resources have already been allocated!");
+
+ m_NumUniformBuffers = static_cast<Uint32>(UniformBlocks.size());
+ m_NumSamplers = static_cast<Uint32>(Samplers.size());
+ m_NumImages = static_cast<Uint32>(Images.size());
+ m_NumStorageBlocks = static_cast<Uint32>(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<IDeviceObject>);
+
+ TotalMemorySize += AlignedStringPoolDataSize * sizeof(Char);
+
+ auto& MemAllocator = GetRawAllocator();
+ void* RawMemory = ALLOCATE(MemAllocator, "Memory buffer for GLProgramResources", TotalMemorySize);
+
+ m_UniformBuffers = reinterpret_cast<UniformBufferInfo*>(RawMemory);
+ m_Samplers = reinterpret_cast<SamplerInfo*> (m_UniformBuffers + m_NumUniformBuffers);
+ m_Images = reinterpret_cast<ImageInfo*> (m_Samplers + m_NumSamplers);
+ m_StorageBlocks = reinterpret_cast<StorageBlockInfo*>(m_Images + m_NumImages);
+ void* EndOfResourceData = m_StorageBlocks + m_NumStorageBlocks;
+ Char* StringPoolData = nullptr;
+ if (InitializeResourceCache)
+ {
+ m_ResourceCache = reinterpret_cast<RefCntAutoPtr<IDeviceObject>*>(EndOfResourceData);
+ StringPoolData = reinterpret_cast<Char*>(m_ResourceCache + ResourceCacheSize);
+ for (Uint32 res=0; res < ResourceCacheSize; ++res)
+ new (m_ResourceCache+res) RefCntAutoPtr<IDeviceObject>{};
+ }
+ else
+ {
+ m_ResourceCache = nullptr;
+ StringPoolData = reinterpret_cast<Char*>(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<size_t>(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<UniformBufferInfo> UniformBlocks;
+ std::vector<SamplerInfo> Samplers;
+ std::vector<ImageInfo> Images;
+ std::vector<StorageBlockInfo> StorageBlocks;
+ std::unordered_set<String> 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<SamplerGLImpl> 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<ISampler**>(static_cast<SamplerGLImpl**>(&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<Uint32>(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<Uint32>(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<GLint>(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<GLint>(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<Uint32>(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<GLint>(LastBlock.pResources.size()));
+ ArraySize = std::max(ArraySize, static_cast<GLint>(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<Uint32>(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<UniformBufferInfo> UniformBlocks;
+ std::vector<SamplerInfo> Samplers;
+ std::vector<ImageInfo> Images;
+ std::vector<StorageBlockInfo> 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<ISampler> 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<SamplerGLImpl>());
+ 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<SamplerGLImpl>()
+ );
}
}
- 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<Uint32>(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<typename TResArrayType>
- 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<IDeviceObject> pNewRes;
- pResourceMapping->GetResource( Name.c_str(), static_cast<IDeviceObject**>(&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<IDeviceObject> pNewRes;
+ pResourceMapping->GetResource( Name, static_cast<IDeviceObject**>(&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<typename TResArrayType>
- 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<const PipelineStateGLImpl>(pPipelineState);
- // ResourceMappingProxy StaticResMapping(*PSOGL);
- // m_DynamicProgResources[0].BindResources(&StaticResMapping, 0);
- //}
- }
}
}