diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2019-03-07 02:58:56 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2019-03-07 02:58:56 +0000 |
| commit | bc9fc76496034a50faf3d7fe7be868d5d62f6663 (patch) | |
| tree | e9438fe09533409c57c9c63b2f69a895e2cf8615 /Graphics/GraphicsEngineOpenGL | |
| parent | Merge pull request #67 from StarshipVendingMachine/android-vulkan (diff) | |
| parent | Minor comment updates (diff) | |
| download | DiligentCore-bc9fc76496034a50faf3d7fe7be868d5d62f6663.tar.gz DiligentCore-bc9fc76496034a50faf3d7fe7be868d5d62f6663.zip | |
Merged var_type_refactor into master
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
38 files changed, 1229 insertions, 960 deletions
diff --git a/Graphics/GraphicsEngineOpenGL/CMakeLists.txt b/Graphics/GraphicsEngineOpenGL/CMakeLists.txt index bfde3d05..6f69366b 100644 --- a/Graphics/GraphicsEngineOpenGL/CMakeLists.txt +++ b/Graphics/GraphicsEngineOpenGL/CMakeLists.txt @@ -39,10 +39,9 @@ set(INTERFACE interface/BufferGL.h interface/BufferViewGL.h interface/DeviceContextGL.h - interface/EngineGLAttribs.h + interface/EngineFactoryOpenGL.h interface/FenceGL.h interface/PipelineStateGL.h - interface/RenderDeviceFactoryOpenGL.h interface/RenderDeviceGL.h interface/SamplerGL.h interface/ShaderGL.h @@ -56,6 +55,7 @@ set(SOURCE src/BufferGLImpl.cpp src/BufferViewGLImpl.cpp src/DeviceContextGLImpl.cpp + src/EngineFactoryOpenGL.cpp src/FBOCache.cpp src/FenceGLImpl.cpp src/GLContextState.cpp @@ -64,7 +64,6 @@ set(SOURCE src/GLProgramResources.cpp src/GLTypeConversions.cpp src/PipelineStateGLImpl.cpp - src/RenderDeviceFactoryOpenGL.cpp src/RenderDeviceGLImpl.cpp src/SamplerGLImpl.cpp src/ShaderGLImpl.cpp diff --git a/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.h index 0961179c..639b3456 100644 --- a/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/BufferViewGLImpl.h @@ -53,7 +53,7 @@ public: bool bIsDefaultView); /// Queries the specific interface, see IObject::QueryInterface() for details - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface )override final; const GLObjectWrappers::GLTextureObj& GetTexBufferHandle(){ return m_GLTexBuffer; } diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h index fe70d286..2be0a192 100644 --- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h @@ -51,7 +51,7 @@ public: DeviceContextGLImpl( IReferenceCounters *pRefCounters, class RenderDeviceGLImpl *pDeviceGL, bool bIsDeferred ); /// Queries the specific interface, see IObject::QueryInterface() for details. - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface )override final; virtual void SetPipelineState(IPipelineState *pPipelineState)override final; diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextAndroid.h b/Graphics/GraphicsEngineOpenGL/include/GLContextAndroid.h index 30107937..8f7e6956 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextAndroid.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextAndroid.h @@ -33,7 +33,7 @@ namespace Diligent public: typedef EGLContext NativeGLContextType; - GLContext(const struct EngineGLAttribs& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); + GLContext(const struct EngineGLCreateInfo& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); ~GLContext(); bool Init( ANativeWindow* window ); diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextIOS.h b/Graphics/GraphicsEngineOpenGL/include/GLContextIOS.h index a71b16ea..d1e5f571 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextIOS.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextIOS.h @@ -30,7 +30,7 @@ namespace Diligent public: typedef void* NativeGLContextType; // EAGLContext* - GLContext(const struct EngineGLAttribs& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); + GLContext(const struct EngineGLCreateInfo& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); NativeGLContextType GetCurrentNativeGLContext(); }; diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextLinux.h b/Graphics/GraphicsEngineOpenGL/include/GLContextLinux.h index b17d8827..c5d9408e 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextLinux.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextLinux.h @@ -30,7 +30,7 @@ namespace Diligent public: typedef GLXContext NativeGLContextType; - GLContext(const struct EngineGLAttribs& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); + GLContext(const struct EngineGLCreateInfo& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); ~GLContext(); void SwapBuffers(); diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextMacOS.h b/Graphics/GraphicsEngineOpenGL/include/GLContextMacOS.h index b67513e2..8a279719 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextMacOS.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextMacOS.h @@ -30,7 +30,7 @@ namespace Diligent public: typedef void* NativeGLContextType; // NSOpenGLContext* - GLContext(const struct EngineGLAttribs& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); + GLContext(const struct EngineGLCreateInfo& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); NativeGLContextType GetCurrentNativeGLContext(); }; diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextWindows.h b/Graphics/GraphicsEngineOpenGL/include/GLContextWindows.h index 870449b1..5cb8ecc3 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextWindows.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextWindows.h @@ -30,7 +30,7 @@ namespace Diligent public: typedef HGLRC NativeGLContextType; - GLContext(const struct EngineGLAttribs& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); + GLContext(const struct EngineGLCreateInfo& InitAttribs, struct DeviceCaps& DeviceCaps, const struct SwapChainDesc* pSCDesc); ~GLContext(); void SwapBuffers(); diff --git a/Graphics/GraphicsEngineOpenGL/include/GLProgram.h b/Graphics/GraphicsEngineOpenGL/include/GLProgram.h index 296ff4fd..930e7aac 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLProgram.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLProgram.h @@ -37,30 +37,16 @@ namespace Diligent GLProgram& operator = (const GLProgram&) = delete; GLProgram& operator = ( GLProgram&&) = delete; - void InitResources(RenderDeviceGLImpl* pDeviceGLImpl, - SHADER_VARIABLE_TYPE DefaultVariableType, - const ShaderVariableDesc* VariableDesc, - Uint32 NumVars, - const StaticSamplerDesc* StaticSamplers, - Uint32 NumStaticSamplers, - IObject& Owner); + void InitResources(RenderDeviceGLImpl* pDeviceGLImpl, + SHADER_TYPE ShaderStage, + IObject& Owner); void BindConstantResources(IResourceMapping* pResourceMapping, Uint32 Flags); - const GLProgramResources& GetAllResources() const{return m_AllResources;} - GLProgramResources& GetConstantResources() {return m_ConstantResources;} - const GLProgramResources& GetConstantResources()const{return m_ConstantResources;} - - -#ifdef VERIFY_RESOURCE_BINDINGS - template<typename TResArrayType> - void dbgVerifyBindingCompletenessHelper(TResArrayType& ResArr, GLProgramResources* pDynamicResources); - void dbgVerifyBindingCompleteness(GLProgramResources* pDynamicResources, class PipelineStateGLImpl* pPSO); -#endif + const GLProgramResources& GetResources() const { return m_AllResources; } private: GLProgramResources m_AllResources; - GLProgramResources m_ConstantResources; // When adding new member DO NOT FORGET TO UPDATE GLProgram( GLProgram&& Program )!!! }; } diff --git a/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h b/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h index 5cf2efe0..95659276 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLProgramResources.h @@ -22,11 +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 @@ -38,146 +43,243 @@ 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, - GLuint GLProgram, - const SHADER_VARIABLE_TYPE DefaultVariableType, - const ShaderVariableDesc* VariableDesc, - Uint32 NumVars, - const StaticSamplerDesc* StaticSamplers, - Uint32 NumStaticSamplers); + void LoadUniforms(IObject& Owner, + class RenderDeviceGLImpl* pDeviceGLImpl, + SHADER_TYPE ShaderStages, + GLuint GLProgram); + - void Clone(const GLProgramResources& SrcLayout, - SHADER_VARIABLE_TYPE* VarTypes, - Uint32 NumVarTypes, - IObject& Owner); + void Clone(class RenderDeviceGLImpl* pDeviceGLImpl, + IObject& Owner, + const GLProgramResources& SrcResources, + const PipelineResourceLayoutDesc& ResourceLayout, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes); - struct GLProgramVariableBase + struct GLProgramVariableBase : ShaderVariableBase { - GLProgramVariableBase(String _Name, - size_t _ArraySize, - SHADER_VARIABLE_TYPE _VarType) : - Name ( std::move(_Name) ), - pResources(_ArraySize), - VarType (_VarType) +/* 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), + VariableType (_VariableType), + ResourceType (_ResourceType), + VariableIndex (_VariableIndex), + ArraySize (_ArraySize), + 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; } - String Name; - std::vector< RefCntAutoPtr<IDeviceObject> > pResources; - const SHADER_VARIABLE_TYPE VarType; + ShaderResourceDesc GetResourceDesc()const + { + ShaderResourceDesc ResourceDesc; + ResourceDesc.Name = Name; + ResourceDesc.ArraySize = ArraySize; + ResourceDesc.Type = ResourceType; + return ResourceDesc; + } }; - struct UniformBufferInfo : GLProgramVariableBase + struct UniformBufferInfo final : GLProgramVariableBase { - UniformBufferInfo(String _Name, - size_t _ArraySize, - SHADER_VARIABLE_TYPE _VarType, - GLint _Index) : - GLProgramVariableBase(std::move(_Name), _ArraySize, _VarType), - 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 + struct SamplerInfo final : GLProgramVariableBase { - SamplerInfo(String _Name, - size_t _ArraySize, - SHADER_VARIABLE_TYPE _VarType, - GLint _Location, - GLenum _Type, - class SamplerGLImpl* _pStaticSampler) : - GLProgramVariableBase(std::move(_Name), _ArraySize, _VarType), + 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; } - - struct ImageInfo : GLProgramVariableBase + static_assert( (sizeof(SamplerInfo) % sizeof(void*)) == 0, "sizeof(SamplerInfo) must be multiple of sizeof(void*)"); + + + struct ImageInfo final : GLProgramVariableBase { - ImageInfo(String _Name, - size_t _ArraySize, - SHADER_VARIABLE_TYPE _VarType, - GLint _BindingPoint, - GLenum _Type) : - GLProgramVariableBase(std::move(_Name), _ArraySize, _VarType), + 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 + struct StorageBlockInfo final : GLProgramVariableBase { - StorageBlockInfo(String _Name, - size_t _ArraySize, - SHADER_VARIABLE_TYPE _VarType, - GLint _Binding) : - GLProgramVariableBase(std::move(_Name), _ArraySize, _VarType), + 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) {} @@ -194,86 +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*)"); + + Uint32 GetNumUniformBuffers()const { return m_NumUniformBuffers; } + Uint32 GetNumSamplers() const { return m_NumSamplers; } + Uint32 GetNumImages() const { return m_NumImages; } + Uint32 GetNumStorageBlocks() const { return m_NumStorageBlocks; } - struct CGLShaderVariable : ShaderVariableBase + UniformBufferInfo& GetUniformBuffer(Uint32 Index) { - CGLShaderVariable(IObject& Owner, GLProgramResources::GLProgramVariableBase& ProgVar, Uint32 _Index) : - ShaderVariableBase(Owner), - ProgramVar (ProgVar), - VariableIndex (_Index) - {} + VERIFY(Index < m_NumUniformBuffers, "Uniform buffer index (", Index, ") is out of range"); + return m_UniformBuffers[Index]; + } - virtual void Set(IDeviceObject *pObject)override final - { - ProgramVar.pResources[0] = pObject; - } + SamplerInfo& GetSampler(Uint32 Index) + { + VERIFY(Index < m_NumSamplers, "Sampler index (", Index, ") is out of range"); + return m_Samplers[Index]; + } - 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]; - } + ImageInfo& GetImage(Uint32 Index) + { + VERIFY(Index < m_NumImages, "Image index (", Index, ") is out of range"); + return m_Images[Index]; + } - virtual SHADER_VARIABLE_TYPE GetType()const override final - { - return ProgramVar.VarType; - } + StorageBlockInfo& GetStorageBlock(Uint32 Index) + { + VERIFY(Index < m_NumStorageBlocks, "Storage block index (", Index, ") is out of range"); + return m_StorageBlocks[Index]; + } - virtual Uint32 GetArraySize()const override final - { - return static_cast<Uint32>(ProgramVar.pResources.size()); - } - virtual const Char* GetName()const override final - { - return ProgramVar.Name.c_str(); - } + const UniformBufferInfo& GetUniformBuffer(Uint32 Index)const + { + VERIFY(Index < m_NumUniformBuffers, "Uniform buffer index (", Index, ") is out of range"); + return m_UniformBuffers[Index]; + } - virtual Uint32 GetIndex()const override final - { - return VariableIndex; - } + const SamplerInfo& GetSampler(Uint32 Index)const + { + VERIFY(Index < m_NumSamplers, "Sampler index (", Index, ") is out of range"); + return m_Samplers[Index]; + } - private: - GLProgramVariableBase& ProgramVar; - const Uint32 VariableIndex; - }; + const ImageInfo& GetImage(Uint32 Index)const + { + VERIFY(Index < m_NumImages, "Image index (", Index, ") is out of range"); + return m_Images[Index]; + } - void BindResources(IResourceMapping *pResourceMapping, Uint32 Flags); + const StorageBlockInfo& GetStorageBlock(Uint32 Index)const + { + VERIFY(Index < m_NumStorageBlocks, "Storage block index (", Index, ") is out of range"); + return m_StorageBlocks[Index]; + } -#ifdef VERIFY_RESOURCE_BINDINGS - void dbgVerifyResourceBindings(); -#endif - IShaderVariable* GetShaderVariable(const Char* Name); - IShaderVariable* GetShaderVariable(Uint32 Index) + Uint32 GetVariableCount()const { - return Index < m_VariablesByIndex.size() ? m_VariablesByIndex[Index] : nullptr; + return m_NumUniformBuffers + m_NumSamplers + m_NumImages + m_NumStorageBlocks; } - const std::unordered_map<HashMapStringKey, CGLShaderVariable, HashMapStringKey::Hasher>& GetVariables(){return m_VariableHash;} - - Uint32 GetVariableCount()const + void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags); + +#ifdef VERIFY_RESOURCE_BINDINGS + void dbgVerifyResourceBindings()const; +#endif + + GLProgramVariableBase* GetVariable(const Char* Name); + GLProgramVariableBase* GetVariable(Uint32 Index) { - return static_cast<Uint32>(m_VariableHash.size()); + 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; + 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 InitVariables(IObject &Owner); - - 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; + 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; + + // 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/PipelineStateGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h index 3e1bbbb1..0c98d838 100644 --- a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h @@ -23,6 +23,7 @@ #pragma once +#include <vector> #include "PipelineStateGL.h" #include "PipelineStateBase.h" #include "RenderDevice.h" @@ -49,10 +50,16 @@ public: ~PipelineStateGLImpl(); /// Queries the specific interface, see IObject::QueryInterface() for details - virtual void QueryInterface( const INTERFACE_ID& IID, IObject** ppInterface )override; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override; - virtual void BindShaderResources( IResourceMapping* pResourceMapping, Uint32 Flags )override final; + virtual void BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags)override final; + virtual Uint32 GetStaticVariableCount(SHADER_TYPE ShaderType) const override final; + + virtual IShaderResourceVariable* GetStaticShaderVariable(SHADER_TYPE ShaderType, const Char* Name) override final; + + virtual IShaderResourceVariable* GetStaticShaderVariable(SHADER_TYPE ShaderType, Uint32 Index) override final; + virtual void CreateShaderResourceBinding( IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources )override final; virtual bool IsCompatibleWith(const IPipelineState* pPSO)const override final; @@ -60,12 +67,19 @@ public: GLProgram& GetGLProgram(){return m_GLProgram;} GLObjectWrappers::GLPipelineObj& GetGLProgramPipeline(GLContext::NativeGLContextType Context); + GLProgramResources& GetStaticResources(Uint32 s) + { + return m_StaticResources[s]; + } + private: void LinkGLProgram(bool bIsProgramPipelineSupported); GLProgram m_GLProgram; ThreadingTools::LockFlag m_ProgPipelineLockFlag; - std::unordered_map<GLContext::NativeGLContextType, GLObjectWrappers::GLPipelineObj> m_GLProgPipelines; + std::vector< std::pair<GLContext::NativeGLContextType, GLObjectWrappers::GLPipelineObj > > m_GLProgPipelines; + std::vector<GLProgramResources> m_StaticResources; + Int8 m_ResourceLayoutIndex[6] = {-1, -1, -1, -1, -1, -1}; }; } diff --git a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h index bc56c5d8..cb278aa8 100644 --- a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h @@ -29,7 +29,6 @@ #include "BaseInterfacesGL.h" #include "FBOCache.h" #include "TexRegionRender.h" -#include "EngineGLAttribs.h" enum class GPU_VENDOR { @@ -55,18 +54,18 @@ class RenderDeviceGLImpl : public RenderDeviceBase<IGLDeviceBaseInterface> public: using TRenderDeviceBase = RenderDeviceBase<IGLDeviceBaseInterface>; - RenderDeviceGLImpl(IReferenceCounters* pRefCounters, - IMemoryAllocator& RawMemAllocator, - const EngineGLAttribs& InitAttribs, - const SwapChainDesc* pSCDesc = nullptr); + RenderDeviceGLImpl(IReferenceCounters* pRefCounters, + IMemoryAllocator& RawMemAllocator, + const EngineGLCreateInfo& InitAttribs, + const SwapChainDesc* pSCDesc = nullptr); ~RenderDeviceGLImpl(); virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override; void CreateBuffer(const BufferDesc& BuffDesc, const BufferData* pBuffData, IBuffer** ppBufferLayout, bool bIsDeviceInternal); virtual void CreateBuffer(const BufferDesc& BuffDesc, const BufferData* BuffData, IBuffer** ppBufferLayout)override final; - void CreateShader(const ShaderCreationAttribs& ShaderCreationAttribs, IShader** ppShader, bool bIsDeviceInternal ); - virtual void CreateShader(const ShaderCreationAttribs& ShaderCreationAttribs, IShader** ppShader)override final; + void CreateShader(const ShaderCreateInfo& ShaderCreateInfo, IShader **ppShader, bool bIsDeviceInternal ); + virtual void CreateShader(const ShaderCreateInfo& ShaderCreateInfo, IShader **ppShader)override final; void CreateTexture(const TextureDesc& TexDesc, const TextureData* pData, ITexture** ppTexture, bool bIsDeviceInternal); virtual void CreateTexture(const TextureDesc& TexDesc, const TextureData* Data, ITexture** ppTexture)override final; diff --git a/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.h index 43d85b64..82ec8082 100644 --- a/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/SamplerGLImpl.h @@ -43,7 +43,7 @@ public: SamplerGLImpl( IReferenceCounters *pRefCounters, RenderDeviceGLImpl *pDeviceGL, const SamplerDesc& SamplerDesc, bool bIsDeviceInternal = false ); ~SamplerGLImpl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface ); + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface )override final; const GLObjectWrappers::GLSamplerObj& GetHandle(){ return m_GlSampler; } diff --git a/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h index 77c5f554..a9170c86 100644 --- a/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/ShaderGLImpl.h @@ -70,70 +70,16 @@ class ShaderGLImpl final : public ShaderBase<IShaderGL, RenderDeviceGLImpl> public: using TShaderBase = ShaderBase<IShaderGL, RenderDeviceGLImpl>; - ShaderGLImpl( IReferenceCounters *pRefCounters, RenderDeviceGLImpl *pDeviceGL, const ShaderCreationAttribs &ShaderCreationAttribs, bool bIsDeviceInternal = false ); + ShaderGLImpl( IReferenceCounters *pRefCounters, RenderDeviceGLImpl *pDeviceGL, const ShaderCreateInfo &ShaderCreateInfo, bool bIsDeviceInternal = false ); ~ShaderGLImpl(); - virtual void BindResources( IResourceMapping* pResourceMapping, Uint32 Flags )override final; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override final; - virtual void QueryInterface( const INTERFACE_ID &IID, IObject **ppInterface )override final; - - // If separate shaders are not available, the method can optionally create - // a placeholder for static resource variable - IShaderVariable* GetShaderVariable(const Char* Name, bool CreatePlaceholder); - virtual IShaderVariable* GetShaderVariable(const Char* Name)override final; - - virtual Uint32 GetVariableCount() const override final; - - virtual IShaderVariable* GetShaderVariable(Uint32 Index) override final; + virtual Uint32 GetResourceCount()const override final; + virtual ShaderResourceDesc GetResource(Uint32 Index)const override final; GLProgram& GetGlProgram(){return m_GlProgObj;} - // This class is used to keep references to static resources when separate shaders are not available - class StaticVarPlaceholder final : public ObjectBase<IShaderVariable> - { - public: - StaticVarPlaceholder(IReferenceCounters* pRefCounters, String Name, Uint32 Index) : - ObjectBase<IShaderVariable>(pRefCounters), - m_Name (std::move(Name)), - m_Index (Index) - {} - - virtual void Set(IDeviceObject* pObject)override final - { - SetArray(&pObject, 0, 1); - } - virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements)override final - { - if (m_Objects.size() < FirstElement + NumElements) - m_Objects.resize(FirstElement + NumElements); - for (Uint32 i=0; i < NumElements; ++i) - m_Objects[FirstElement + i] = ppObjects[i]; - } - virtual SHADER_VARIABLE_TYPE GetType()const override final - { - return SHADER_VARIABLE_TYPE_STATIC; - } - virtual Uint32 GetArraySize()const override final - { - return static_cast<Uint32>(m_Objects.size()); - } - virtual const Char* GetName()const override final - { - return m_Name.c_str(); - } - virtual Uint32 GetIndex()const override final - { - return m_Index; - } - IDeviceObject* Get(Uint32 ArrayIndex) - { - return ArrayIndex < m_Objects.size() ? m_Objects[ArrayIndex].RawPtr() : nullptr; - } - private: - const String m_Name; - const Uint32 m_Index; - std::vector<RefCntAutoPtr<IDeviceObject>> m_Objects; - }; private: friend class PipelineStateGLImpl; @@ -141,9 +87,6 @@ private: GLProgram m_GlProgObj; // Used if program pipeline supported GLObjectWrappers::GLShaderObj m_GLShaderObj; // Used if program pipelines are not supported - - std::vector<RefCntAutoPtr<StaticVarPlaceholder>> m_StaticResources; // Used only if program pipelines are not supported to - // hold static resources. }; } diff --git a/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h index ac76461b..ebea5624 100644 --- a/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h @@ -51,20 +51,21 @@ public: virtual void BindResources(Uint32 ShaderFlags, IResourceMapping* pResMapping, Uint32 Flags)override final; - virtual IShaderVariable* GetVariable(SHADER_TYPE ShaderType, const char *Name)override final; + virtual IShaderResourceVariable* GetVariable(SHADER_TYPE ShaderType, const char *Name)override final; virtual Uint32 GetVariableCount(SHADER_TYPE ShaderType) const override final; - virtual IShaderVariable* GetVariable(SHADER_TYPE ShaderType, Uint32 Index)override final; + virtual IShaderResourceVariable* GetVariable(SHADER_TYPE ShaderType, Uint32 Index)override final; virtual void InitializeStaticResources(const IPipelineState* pPipelineState)override final; - GLProgramResources& GetProgramResources(SHADER_TYPE ShaderType, PipelineStateGLImpl* pdbgPSO); + GLProgramResources& GetResources(Uint32 Ind, PipelineStateGLImpl* pdbgPSO); private: bool IsUsingSeparatePrograms()const; - GLProgramResources m_DynamicProgResources[6]; + Int8 m_ResourceIndex[6] = {-1, -1, -1, -1, -1, -1}; + std::vector<GLProgramResources> m_Resources; }; } diff --git a/Graphics/GraphicsEngineOpenGL/include/SwapChainGLIOS.h b/Graphics/GraphicsEngineOpenGL/include/SwapChainGLIOS.h index 51d34a47..db321e70 100644 --- a/Graphics/GraphicsEngineOpenGL/include/SwapChainGLIOS.h +++ b/Graphics/GraphicsEngineOpenGL/include/SwapChainGLIOS.h @@ -23,7 +23,6 @@ #pragma once -#include "EngineGLAttribs.h" #include "SwapChainGL.h" #include "SwapChainBase.h" #include "GLObjectWrapper.h" @@ -38,11 +37,11 @@ class SwapChainGLIOS final : public SwapChainBase<ISwapChainGL> public: typedef SwapChainBase<ISwapChainGL> TSwapChainBase; - SwapChainGLIOS(IReferenceCounters *pRefCounters, - const EngineGLAttribs &InitAttribs, - const SwapChainDesc& SwapChainDesc, - class RenderDeviceGLImpl* pRenderDeviceGL, - class DeviceContextGLImpl* pImmediateContextGL); + SwapChainGLIOS(IReferenceCounters* pRefCounters, + const EngineGLCreateInfo& InitAttribs, + const SwapChainDesc& SwapChainDesc, + class RenderDeviceGLImpl* pRenderDeviceGL, + class DeviceContextGLImpl* pImmediateContextGL); SwapChainGLIOS(); virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final; diff --git a/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h index e92bc0a5..18e43a4b 100644 --- a/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h @@ -23,7 +23,6 @@ #pragma once -#include "EngineGLAttribs.h" #include "SwapChainGL.h" #include "SwapChainBase.h" #include "GLObjectWrapper.h" @@ -38,14 +37,14 @@ class SwapChainGLImpl final : public SwapChainBase<ISwapChainGL> public: using TSwapChainBase = SwapChainBase<ISwapChainGL>; - SwapChainGLImpl(IReferenceCounters *pRefCounters, - const EngineGLAttribs &InitAttribs, - const SwapChainDesc& SwapChainDesc, - class RenderDeviceGLImpl* pRenderDeviceGL, - class DeviceContextGLImpl* pImmediateContextGL); + SwapChainGLImpl(IReferenceCounters* pRefCounters, + const EngineGLCreateInfo& InitAttribs, + const SwapChainDesc& SwapChainDesc, + class RenderDeviceGLImpl* pRenderDeviceGL, + class DeviceContextGLImpl* pImmediateContextGL); ~SwapChainGLImpl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override final; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface )override final; virtual void Present(Uint32 SyncInterval)override final; diff --git a/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h b/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h index 91c31b08..72c64d91 100644 --- a/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h +++ b/Graphics/GraphicsEngineOpenGL/include/TexRegionRender.h @@ -48,7 +48,7 @@ private: RefCntAutoPtr<IBuffer> m_pConstantBuffer; RefCntAutoPtr<IPipelineState> m_pPSO[RESOURCE_DIM_NUM_DIMENSIONS * 3]; RefCntAutoPtr<IShaderResourceBinding> m_pSRB; - IShaderVariable* m_pSrcTexVar = nullptr; + IShaderResourceVariable* m_pSrcTexVar = nullptr; RefCntAutoPtr<IPipelineState> m_pOrigPSO; Uint32 m_OrigStencilRef = 0; diff --git a/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h index 06c71841..cae8a8d8 100644 --- a/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h @@ -48,7 +48,7 @@ public: bool bIsDefaultView ); ~TextureViewGLImpl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface )override final; const GLObjectWrappers::GLTextureObj& GetHandle(); GLenum GetBindTarget(); diff --git a/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceFactoryOpenGL.h b/Graphics/GraphicsEngineOpenGL/interface/EngineFactoryOpenGL.h index 93b8d8f4..63627856 100644 --- a/Graphics/GraphicsEngineOpenGL/interface/RenderDeviceFactoryOpenGL.h +++ b/Graphics/GraphicsEngineOpenGL/interface/EngineFactoryOpenGL.h @@ -34,7 +34,6 @@ #include "../../HLSL2GLSLConverterLib/interface/HLSL2GLSLConverter.h" -#include "EngineGLAttribs.h" #if PLATFORM_ANDROID || PLATFORM_LINUX || PLATFORM_MACOS || PLATFORM_IOS || (PLATFORM_WIN32 && !defined(_MSC_VER)) @@ -55,16 +54,16 @@ namespace Diligent class IEngineFactoryOpenGL { public: - virtual void CreateDeviceAndSwapChainGL(const EngineGLAttribs& CreationAttribs, - IRenderDevice **ppDevice, - IDeviceContext **ppImmediateContext, - const SwapChainDesc& SCDesc, - ISwapChain **ppSwapChain ) = 0; - virtual void CreateHLSL2GLSLConverter(IHLSL2GLSLConverter **ppConverter) = 0; + virtual void CreateDeviceAndSwapChainGL(const EngineGLCreateInfo& EngineCI, + IRenderDevice** ppDevice, + IDeviceContext** ppImmediateContext, + const SwapChainDesc& SCDesc, + ISwapChain** ppSwapChain ) = 0; + virtual void CreateHLSL2GLSLConverter(IHLSL2GLSLConverter** ppConverter) = 0; - virtual void AttachToActiveGLContext( const EngineGLAttribs& CreationAttribs, - IRenderDevice **ppDevice, - IDeviceContext **ppImmediateContext ) = 0; + virtual void AttachToActiveGLContext(const EngineGLCreateInfo& EngineCI, + IRenderDevice** ppDevice, + IDeviceContext** ppImmediateContext) = 0; }; @@ -74,7 +73,7 @@ public: typedef IEngineFactoryOpenGL* (*GetEngineFactoryOpenGLType)(); - static bool LoadGraphicsEngineOpenGL(GetEngineFactoryOpenGLType &GetFactoryFunc) + static bool LoadGraphicsEngineOpenGL(GetEngineFactoryOpenGLType& GetFactoryFunc) { GetFactoryFunc = nullptr; std::string LibName = "GraphicsEngineOpenGL_"; diff --git a/Graphics/GraphicsEngineOpenGL/interface/EngineGLAttribs.h b/Graphics/GraphicsEngineOpenGL/interface/EngineGLAttribs.h deleted file mode 100644 index 9f3b6dd0..00000000 --- a/Graphics/GraphicsEngineOpenGL/interface/EngineGLAttribs.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Definition of the Engine OpenGL/GLES attribs - -#include "../../GraphicsEngine/interface/GraphicsTypes.h" - -namespace Diligent -{ - /// Attributes of the OpenGL-based engine implementation - struct EngineGLAttribs : public EngineCreationAttribs - { - /// Native window handle - - /// * On Win32 platform, this is a window handle (HWND) - /// * On Android platform, this is a pointer to the native window (ANativeWindow*) - /// * On Linux, this is the native window (Window) - void* pNativeWndHandle = nullptr; - -#if PLATFORM_LINUX - /// For linux platform only, this is the pointer to the display - void* pDisplay = nullptr; -#endif - }; -} diff --git a/Graphics/GraphicsEngineOpenGL/readme.md b/Graphics/GraphicsEngineOpenGL/readme.md index dfa2109d..ab987dad 100644 --- a/Graphics/GraphicsEngineOpenGL/readme.md +++ b/Graphics/GraphicsEngineOpenGL/readme.md @@ -23,7 +23,7 @@ RefCntAutoPtr<IDeviceContext> pImmediateContext; SwapChainDesc SCDesc; RefCntAutoPtr<ISwapChain> pSwapChain; auto *pFactoryOpenGL = GetEngineFactoryOpenGL(); -EngineGLAttribs CreationAttribs; +EngineGLCreateInfo CreationAttribs; CreationAttribs.pNativeWndHandle = NativeWindowHandle; pFactoryOpenGL->CreateDeviceAndSwapChainGL( CreationAttribs, &pRenderDevice, &pImmediateContext, SCDesc, &pSwapChain); diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index d7ff2b32..22823f51 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -383,27 +383,26 @@ namespace Diligent auto* pShaderGL = m_pPipelineState->GetShader<ShaderGLImpl>(ProgNum); auto& GLProgramObj = ProgramPipelineSupported ? pShaderGL->m_GlProgObj : Prog; - GLProgramResources* pDynamicResources = pShaderResBindingGL ? &pShaderResBindingGL->GetProgramResources(pShaderGL->GetDesc().ShaderType, m_pPipelineState) : nullptr; + GLProgramResources* pSRBResources = pShaderResBindingGL ? &pShaderResBindingGL->GetResources(ProgNum, m_pPipelineState) : nullptr; #ifdef VERIFY_RESOURCE_BINDINGS - GLProgramObj.dbgVerifyBindingCompleteness(pDynamicResources, m_pPipelineState); + //GLProgramObj.dbgVerifyBindingCompleteness(pDynamicResources, m_pPipelineState); #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 BindSRBResources = 0; BindSRBResources < (pShaderResBindingGL ? 2 : 1); ++BindSRBResources) { - GLProgramResources& ProgResources = BindDynamicResources ? *pDynamicResources : GLProgramObj.GetConstantResources(); + GLProgramResources& ProgResources = BindSRBResources ? *pSRBResources : m_pPipelineState->GetStaticResources(ProgNum); #ifdef VERIFY_RESOURCE_BINDINGS ProgResources.dbgVerifyResourceBindings(); #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 +415,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 +424,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 +472,9 @@ namespace Diligent m_ContextState); SamplerGLImpl* pSamplerGL = nullptr; - if (it->pStaticSampler) + if (Sam.pStaticSampler) { - pSamplerGL = it->pStaticSampler; + pSamplerGL = Sam.pStaticSampler; } else { @@ -494,12 +493,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 +506,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 +565,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 +594,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 +602,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/RenderDeviceFactoryOpenGL.cpp b/Graphics/GraphicsEngineOpenGL/src/EngineFactoryOpenGL.cpp index 601595e0..0b376f0c 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceFactoryOpenGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/EngineFactoryOpenGL.cpp @@ -25,7 +25,7 @@ /// Routines that initialize OpenGL/GLES-based engine implementation #include "pch.h" -#include "RenderDeviceFactoryOpenGL.h" +#include "EngineFactoryOpenGL.h" #include "RenderDeviceGLImpl.h" #include "DeviceContextGLImpl.h" #include "EngineMemory.h" @@ -67,24 +67,24 @@ public: return &TheFactory; } - virtual void CreateDeviceAndSwapChainGL(const EngineGLAttribs& CreationAttribs, - IRenderDevice** ppDevice, - IDeviceContext** ppImmediateContext, - const SwapChainDesc& SCDesc, - ISwapChain** ppSwapChain )override final; + virtual void CreateDeviceAndSwapChainGL(const EngineGLCreateInfo& EngineCI, + IRenderDevice** ppDevice, + IDeviceContext** ppImmediateContext, + const SwapChainDesc& SCDesc, + ISwapChain** ppSwapChain )override final; virtual void CreateHLSL2GLSLConverter(IHLSL2GLSLConverter** ppConverter)override final; - virtual void AttachToActiveGLContext( const EngineGLAttribs& CreationAttribs, - IRenderDevice** ppDevice, - IDeviceContext** ppImmediateContext )override final; + virtual void AttachToActiveGLContext(const EngineGLCreateInfo& EngineCI, + IRenderDevice** ppDevice, + IDeviceContext** ppImmediateContext )override final; }; /// Creates render device, device context and swap chain for OpenGL/GLES-based engine implementation -/// \param [in] CreationAttribs - Engine creation attributes. +/// \param [in] EngineCI - Engine creation attributes. /// \param [out] ppDevice - Address of the memory location where pointer to /// the created device will be written. /// \param [out] ppImmediateContext - Address of the memory location where pointers to @@ -92,14 +92,14 @@ public: /// \param [in] SCDesc - Swap chain description. /// \param [out] ppSwapChain - Address of the memory location where pointer to the new /// swap chain will be written. -void EngineFactoryOpenGLImpl::CreateDeviceAndSwapChainGL(const EngineGLAttribs& CreationAttribs, - IRenderDevice** ppDevice, - IDeviceContext** ppImmediateContext, - const SwapChainDesc& SCDesc, - ISwapChain** ppSwapChain) +void EngineFactoryOpenGLImpl::CreateDeviceAndSwapChainGL(const EngineGLCreateInfo& EngineCI, + IRenderDevice** ppDevice, + IDeviceContext** ppImmediateContext, + const SwapChainDesc& SCDesc, + ISwapChain** ppSwapChain) { - if (CreationAttribs.DebugMessageCallback != nullptr) - SetDebugMessageCallback(CreationAttribs.DebugMessageCallback); + if (EngineCI.DebugMessageCallback != nullptr) + SetDebugMessageCallback(EngineCI.DebugMessageCallback); VERIFY( ppDevice && ppImmediateContext && ppSwapChain, "Null pointer provided" ); if( !ppDevice || !ppImmediateContext || !ppSwapChain ) @@ -111,10 +111,10 @@ void EngineFactoryOpenGLImpl::CreateDeviceAndSwapChainGL(const EngineGLAttribs& try { - SetRawAllocator(CreationAttribs.pRawMemAllocator); + SetRawAllocator(EngineCI.pRawMemAllocator); auto &RawMemAllocator = GetRawAllocator(); - RenderDeviceGLImpl* pRenderDeviceOpenGL( NEW_RC_OBJ(RawMemAllocator, "TRenderDeviceGLImpl instance", TRenderDeviceGLImpl)(RawMemAllocator, CreationAttribs, &SCDesc) ); + RenderDeviceGLImpl *pRenderDeviceOpenGL( NEW_RC_OBJ(RawMemAllocator, "TRenderDeviceGLImpl instance", TRenderDeviceGLImpl)(RawMemAllocator, EngineCI, &SCDesc) ); pRenderDeviceOpenGL->QueryInterface(IID_RenderDevice, reinterpret_cast<IObject**>(ppDevice) ); DeviceContextGLImpl* pDeviceContextOpenGL( NEW_RC_OBJ(RawMemAllocator, "DeviceContextGLImpl instance", DeviceContextGLImpl)(pRenderDeviceOpenGL, false ) ); @@ -123,7 +123,7 @@ void EngineFactoryOpenGLImpl::CreateDeviceAndSwapChainGL(const EngineGLAttribs& pDeviceContextOpenGL->QueryInterface(IID_DeviceContext, reinterpret_cast<IObject**>(ppImmediateContext) ); pRenderDeviceOpenGL->SetImmediateContext(pDeviceContextOpenGL); - TSwapChain *pSwapChainGL = NEW_RC_OBJ(RawMemAllocator, "SwapChainGLImpl instance", TSwapChain)(CreationAttribs, SCDesc, pRenderDeviceOpenGL, pDeviceContextOpenGL ); + TSwapChain *pSwapChainGL = NEW_RC_OBJ(RawMemAllocator, "SwapChainGLImpl instance", TSwapChain)(EngineCI, SCDesc, pRenderDeviceOpenGL, pDeviceContextOpenGL ); pSwapChainGL->QueryInterface(IID_SwapChain, reinterpret_cast<IObject**>(ppSwapChain) ); pDeviceContextOpenGL->SetSwapChain(pSwapChainGL); @@ -158,17 +158,17 @@ void EngineFactoryOpenGLImpl::CreateDeviceAndSwapChainGL(const EngineGLAttribs& /// Creates render device, device context and attaches to existing GL context -/// \param [in] CreationAttribs - Engine creation attributes. +/// \param [in] EngineCI - Engine creation attributes. /// \param [out] ppDevice - Address of the memory location where pointer to /// the created device will be written. /// \param [out] ppImmediateContext - Address of the memory location where pointers to /// the immediate context will be written. -void EngineFactoryOpenGLImpl::AttachToActiveGLContext( const EngineGLAttribs& CreationAttribs, - IRenderDevice** ppDevice, - IDeviceContext** ppImmediateContext ) +void EngineFactoryOpenGLImpl::AttachToActiveGLContext(const EngineGLCreateInfo& EngineCI, + IRenderDevice** ppDevice, + IDeviceContext** ppImmediateContext ) { - if (CreationAttribs.DebugMessageCallback != nullptr) - SetDebugMessageCallback(CreationAttribs.DebugMessageCallback); + if (EngineCI.DebugMessageCallback != nullptr) + SetDebugMessageCallback(EngineCI.DebugMessageCallback); VERIFY( ppDevice && ppImmediateContext, "Null pointer provided" ); if( !ppDevice || !ppImmediateContext ) @@ -179,10 +179,10 @@ void EngineFactoryOpenGLImpl::AttachToActiveGLContext( const EngineGLAttribs& Cr try { - SetRawAllocator(CreationAttribs.pRawMemAllocator); + SetRawAllocator(EngineCI.pRawMemAllocator); auto &RawMemAllocator = GetRawAllocator(); - RenderDeviceGLImpl* pRenderDeviceOpenGL( NEW_RC_OBJ(RawMemAllocator, "TRenderDeviceGLImpl instance", TRenderDeviceGLImpl)(RawMemAllocator, CreationAttribs) ); + RenderDeviceGLImpl *pRenderDeviceOpenGL( NEW_RC_OBJ(RawMemAllocator, "TRenderDeviceGLImpl instance", TRenderDeviceGLImpl)(RawMemAllocator, EngineCI) ); pRenderDeviceOpenGL->QueryInterface(IID_RenderDevice, reinterpret_cast<IObject**>(ppDevice) ); DeviceContextGLImpl* pDeviceContextOpenGL( NEW_RC_OBJ(RawMemAllocator, "DeviceContextGLImpl instance", DeviceContextGLImpl)(pRenderDeviceOpenGL, false ) ); @@ -228,7 +228,7 @@ void LoadGraphicsEngineOpenGL(GetEngineFactoryOpenGLType &GetFactoryFunc) } #endif -void EngineFactoryOpenGLImpl::CreateHLSL2GLSLConverter(IHLSL2GLSLConverter **ppConverter) +void EngineFactoryOpenGLImpl::CreateHLSL2GLSLConverter(IHLSL2GLSLConverter** ppConverter) { HLSL2GLSLConverterObject *pConverter( NEW_RC_OBJ(GetRawAllocator(), "HLSL2GLSLConverterObject instance", HLSL2GLSLConverterObject)() ); pConverter->QueryInterface( IID_HLSL2GLSLConverter, reinterpret_cast<IObject**>(ppConverter) ); diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextAndroid.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextAndroid.cpp index 738ba5c8..3dbae218 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextAndroid.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextAndroid.cpp @@ -25,7 +25,6 @@ #include <utility> #include "GLContextAndroid.h" -#include "EngineGLAttribs.h" #ifndef EGL_CONTEXT_MINOR_VERSION_KHR #define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB @@ -229,7 +228,7 @@ namespace Diligent return true; } - GLContext::GLContext(const EngineGLAttribs& InitAttribs, DeviceCaps& DeviceCaps, const struct SwapChainDesc* /*pSCDesc*/) : + GLContext::GLContext(const EngineGLCreateInfo& InitAttribs, DeviceCaps& deviceCaps, const struct SwapChainDesc* /*pSCDesc*/) : display_( EGL_NO_DISPLAY ), surface_( EGL_NO_SURFACE ), context_( EGL_NO_CONTEXT ), @@ -241,7 +240,7 @@ namespace Diligent auto *NativeWindow = reinterpret_cast<ANativeWindow*>(InitAttribs.pNativeWndHandle); Init( NativeWindow ); - FillDeviceCaps(DeviceCaps); + FillDeviceCaps(deviceCaps); } GLContext::~GLContext() @@ -385,29 +384,29 @@ namespace Diligent return true; } - void GLContext::FillDeviceCaps( DeviceCaps &DeviceCaps ) + void GLContext::FillDeviceCaps( DeviceCaps& deviceCaps ) { const auto* Extensions = (char*)glGetString(GL_EXTENSIONS); LOG_INFO_MESSAGE( "Supported extensions: \n", Extensions); - DeviceCaps.DevType = DeviceType::OpenGLES; - DeviceCaps.MajorVersion = major_version_; - DeviceCaps.MinorVersion = minor_version_; + deviceCaps.DevType = DeviceType::OpenGLES; + deviceCaps.MajorVersion = major_version_; + deviceCaps.MinorVersion = minor_version_; bool IsGLES31OrAbove = (major_version_ >= 4 || (major_version_ == 3 && minor_version_ >= 1) ); bool IsGLES32OrAbove = (major_version_ >= 4 || (major_version_ == 3 && minor_version_ >= 2) ); - DeviceCaps.bSeparableProgramSupported = IsGLES31OrAbove || strstr(Extensions, "separate_shader_objects"); - DeviceCaps.bIndirectRenderingSupported = IsGLES31OrAbove || strstr(Extensions, "draw_indirect"); + deviceCaps.bSeparableProgramSupported = IsGLES31OrAbove || strstr(Extensions, "separate_shader_objects"); + deviceCaps.bIndirectRenderingSupported = IsGLES31OrAbove || strstr(Extensions, "draw_indirect"); - DeviceCaps.bComputeShadersSupported = IsGLES31OrAbove || strstr(Extensions, "compute_shader"); - DeviceCaps.bGeometryShadersSupported = IsGLES32OrAbove || strstr(Extensions, "geometry_shader"); - DeviceCaps.bTessellationSupported = IsGLES32OrAbove || strstr(Extensions, "tessellation_shader"); + deviceCaps.bComputeShadersSupported = IsGLES31OrAbove || strstr(Extensions, "compute_shader"); + deviceCaps.bGeometryShadersSupported = IsGLES32OrAbove || strstr(Extensions, "geometry_shader"); + deviceCaps.bTessellationSupported = IsGLES32OrAbove || strstr(Extensions, "tessellation_shader"); - auto &SamCaps = DeviceCaps.SamCaps; + auto &SamCaps = deviceCaps.SamCaps; SamCaps.bBorderSamplingModeSupported = GL_TEXTURE_BORDER_COLOR && (IsGLES32OrAbove || strstr(Extensions, "texture_border_clamp")); SamCaps.bAnisotropicFilteringSupported = GL_TEXTURE_MAX_ANISOTROPY_EXT && (IsGLES31OrAbove || strstr(Extensions, "texture_filter_anisotropic")); SamCaps.bLODBiasSupported = GL_TEXTURE_LOD_BIAS && IsGLES31OrAbove; - auto &TexCaps = DeviceCaps.TexCaps; + auto &TexCaps = deviceCaps.TexCaps; TexCaps.bTexture1DSupported = False; // Not supported in GLES 3.2 TexCaps.bTexture1DArraySupported = False; // Not supported in GLES 3.2 TexCaps.bTexture2DMSSupported = IsGLES31OrAbove || strstr(Extensions, "texture_storage_multisample"); @@ -415,6 +414,6 @@ namespace Diligent TexCaps.bTextureViewSupported = IsGLES31OrAbove || strstr(Extensions, "texture_view"); TexCaps.bCubemapArraysSupported = IsGLES32OrAbove || strstr(Extensions, "texture_cube_map_array"); - DeviceCaps.bMultithreadedResourceCreationSupported = False; + deviceCaps.bMultithreadedResourceCreationSupported = False; } } diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextIOS.mm b/Graphics/GraphicsEngineOpenGL/src/GLContextIOS.mm index cc96c671..812041c9 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextIOS.mm +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextIOS.mm @@ -28,11 +28,10 @@ #include "GLContextIOS.h" #include "DeviceCaps.h" #include "GLTypeConversions.h" -#include "EngineGLAttribs.h" namespace Diligent { - GLContext::GLContext(const EngineGLAttribs& Info, DeviceCaps& DeviceCaps, const struct SwapChainDesc* /*pSCDesc*/) + GLContext::GLContext(const EngineGLCreateInfo& Info, DeviceCaps& deviceCaps, const struct SwapChainDesc* /*pSCDesc*/) { if (GetCurrentNativeGLContext() == nullptr) { @@ -66,26 +65,26 @@ namespace Diligent //if( glGetError() != GL_NO_ERROR ) // LOG_ERROR_MESSAGE("Failed to enable SRGB framebuffers"); - DeviceCaps.DevType = DeviceType::OpenGLES; - DeviceCaps.MajorVersion = MajorVersion; - DeviceCaps.MinorVersion = MinorVersion; - DeviceCaps.bMultithreadedResourceCreationSupported = False; - DeviceCaps.bIndirectRenderingSupported = False; - DeviceCaps.bGeometryShadersSupported = False; - DeviceCaps.bTessellationSupported = False; - DeviceCaps.bWireframeFillSupported = False; - DeviceCaps.bComputeShadersSupported = False; + deviceCaps.DevType = DeviceType::OpenGLES; + deviceCaps.MajorVersion = MajorVersion; + deviceCaps.MinorVersion = MinorVersion; + deviceCaps.bMultithreadedResourceCreationSupported = False; + deviceCaps.bIndirectRenderingSupported = False; + deviceCaps.bGeometryShadersSupported = False; + deviceCaps.bTessellationSupported = False; + deviceCaps.bWireframeFillSupported = False; + deviceCaps.bComputeShadersSupported = False; - DeviceCaps.SamCaps.bLODBiasSupported = False; - DeviceCaps.SamCaps.bBorderSamplingModeSupported = False; + deviceCaps.SamCaps.bLODBiasSupported = False; + deviceCaps.SamCaps.bBorderSamplingModeSupported = False; - DeviceCaps.TexCaps.bTexture1DSupported = False; - DeviceCaps.TexCaps.bCubemapArraysSupported = False; - DeviceCaps.TexCaps.bTexture1DSupported = False; - DeviceCaps.TexCaps.bTexture1DArraySupported = False; - DeviceCaps.TexCaps.bTextureViewSupported = False; - DeviceCaps.TexCaps.bTexture2DMSSupported = False; - DeviceCaps.TexCaps.bTexture2DMSArraySupported = False; + deviceCaps.TexCaps.bTexture1DSupported = False; + deviceCaps.TexCaps.bCubemapArraysSupported = False; + deviceCaps.TexCaps.bTexture1DSupported = False; + deviceCaps.TexCaps.bTexture1DArraySupported = False; + deviceCaps.TexCaps.bTextureViewSupported = False; + deviceCaps.TexCaps.bTexture2DMSSupported = False; + deviceCaps.TexCaps.bTexture2DMSArraySupported = False; } GLContext::NativeGLContextType GLContext::GetCurrentNativeGLContext() diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextLinux.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextLinux.cpp index 00fcc65b..ec0f710a 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextLinux.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextLinux.cpp @@ -26,7 +26,6 @@ #include "GLContextLinux.h" #include "DeviceCaps.h" #include "GLTypeConversions.h" -#include "EngineGLAttribs.h" namespace Diligent { @@ -84,7 +83,7 @@ namespace Diligent LOG_INFO_MESSAGE( MessageSS.str().c_str() ); } - GLContext::GLContext(const EngineGLAttribs& InitAttribs, DeviceCaps& DeviceCaps, const struct SwapChainDesc* /*pSCDesc*/) : + GLContext::GLContext(const EngineGLCreateInfo& InitAttribs, DeviceCaps& deviceCaps, const struct SwapChainDesc* /*pSCDesc*/) : m_Context(0), m_pNativeWindow(InitAttribs.pNativeWndHandle), m_pDisplay(InitAttribs.pDisplay) @@ -145,16 +144,16 @@ namespace Diligent if( glGetError() != GL_NO_ERROR ) LOG_ERROR_MESSAGE("Failed to enable SRGB framebuffers"); - DeviceCaps.DevType = DeviceType::OpenGL; - DeviceCaps.MajorVersion = MajorVersion; - DeviceCaps.MinorVersion = MinorVersion; + deviceCaps.DevType = DeviceType::OpenGL; + deviceCaps.MajorVersion = MajorVersion; + deviceCaps.MinorVersion = MinorVersion; bool IsGL43OrAbove = MajorVersion >= 5 || MajorVersion == 4 && MinorVersion >= 3; - auto &TexCaps = DeviceCaps.TexCaps; + auto &TexCaps = deviceCaps.TexCaps; TexCaps.bTexture2DMSSupported = IsGL43OrAbove; TexCaps.bTexture2DMSArraySupported = IsGL43OrAbove; TexCaps.bTextureViewSupported = IsGL43OrAbove; TexCaps.bCubemapArraysSupported = IsGL43OrAbove; - DeviceCaps.bMultithreadedResourceCreationSupported = False; + deviceCaps.bMultithreadedResourceCreationSupported = False; } GLContext::~GLContext() diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextMacOS.mm b/Graphics/GraphicsEngineOpenGL/src/GLContextMacOS.mm index bb6e74da..c12609fc 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextMacOS.mm +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextMacOS.mm @@ -28,7 +28,6 @@ #include "GLContextMacOS.h" #include "DeviceCaps.h" #include "GLTypeConversions.h" -#include "EngineGLAttribs.h" static void glDrawArraysInstancedBaseInstance_stub(GLenum mode, GLint first, GLsizei count, GLsizei primcount, GLuint baseinstance) { @@ -48,7 +47,7 @@ static void glDrawElementsInstancedBaseVertexBaseInstance_stub(GLenum mode, GLs namespace Diligent { - GLContext::GLContext(const EngineGLAttribs& InitAttribs, DeviceCaps& DeviceCaps, const struct SwapChainDesc* /*pSCDesc*/) + GLContext::GLContext(const EngineGLCreateInfo& InitAttribs, DeviceCaps& DeviceCaps, const struct SwapChainDesc* /*pSCDesc*/) { if (GetCurrentNativeGLContext() == nullptr) { diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp index 988dbdb8..36acb151 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextWindows.cpp @@ -26,8 +26,6 @@ #include "GLContextWindows.h" #include "DeviceCaps.h" #include "GLTypeConversions.h" -#include "EngineGLAttribs.h" -#include "GraphicsAccessories.h" namespace Diligent { @@ -90,7 +88,7 @@ namespace Diligent LOG_INFO_MESSAGE( MessageSS.str().c_str() ); } - GLContext::GLContext(const EngineGLAttribs& InitAttribs, DeviceCaps& DeviceCaps, const SwapChainDesc* pSCDesc) : + GLContext::GLContext(const EngineGLCreateInfo& InitAttribs, DeviceCaps& DeviceCaps, const SwapChainDesc* pSCDesc) : m_Context(0), m_WindowHandleToDeviceContext(0) { diff --git a/Graphics/GraphicsEngineOpenGL/src/GLProgram.cpp b/Graphics/GraphicsEngineOpenGL/src/GLProgram.cpp index c3108330..a49669ea 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLProgram.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLProgram.cpp @@ -33,67 +33,15 @@ namespace Diligent {} GLProgram::GLProgram( GLProgram&& Program ): - GLObjectWrappers::GLProgramObj(std::move(Program ) ), - m_AllResources (std::move(Program.m_AllResources) ), - m_ConstantResources (std::move(Program.m_ConstantResources)) + GLObjectWrappers::GLProgramObj(std::move(Program ) ), + m_AllResources (std::move(Program.m_AllResources)) {} - void GLProgram::InitResources(RenderDeviceGLImpl* pDeviceGLImpl, - const SHADER_VARIABLE_TYPE DefaultVariableType, - const ShaderVariableDesc *VariableDesc, - Uint32 NumVars, - const StaticSamplerDesc *StaticSamplers, - Uint32 NumStaticSamplers, - IObject &Owner) + void GLProgram::InitResources(RenderDeviceGLImpl* pDeviceGLImpl, + SHADER_TYPE ShaderStage, + IObject& Owner) { GLuint GLProgram = static_cast<GLuint>(*this); - m_AllResources.LoadUniforms(pDeviceGLImpl, GLProgram, DefaultVariableType, VariableDesc, NumVars, StaticSamplers, NumStaticSamplers); - - SHADER_VARIABLE_TYPE VarTypes[] = {SHADER_VARIABLE_TYPE_STATIC}; - m_ConstantResources.Clone(m_AllResources, VarTypes, _countof(VarTypes), Owner); - } - - void GLProgram::BindConstantResources( IResourceMapping *pResourceMapping, Uint32 Flags ) - { - if( !pResourceMapping ) - return; - - m_ConstantResources.BindResources(pResourceMapping, Flags); - } - - -#ifdef VERIFY_RESOURCE_BINDINGS - template<typename TResArrayType> - void GLProgram::dbgVerifyBindingCompletenessHelper(TResArrayType &ResArr, GLProgramResources *pDynamicResources) - { - const auto &ConstVariables = m_ConstantResources.GetVariables(); - for( auto res = ResArr.begin(); res != ResArr.end(); ++res ) - { - auto ConstRes = ConstVariables.find(HashMapStringKey(res->Name.c_str())); - if (ConstRes == ConstVariables.end()) - { - bool bVarFound = false; - if( pDynamicResources) - { - const auto &DynamicVariables = pDynamicResources->GetVariables(); - auto DynRes = DynamicVariables.find(HashMapStringKey(res->Name.c_str())); - bVarFound = (DynRes != DynamicVariables.end()); - } - - if(!bVarFound) - { - LOG_ERROR_MESSAGE( "Incomplete binding: non-static shader variable \"", res->Name, "\" not found" ); - } - } - } - } - - void GLProgram::dbgVerifyBindingCompleteness(GLProgramResources *pDynamicResources, PipelineStateGLImpl *pPSO) - { - dbgVerifyBindingCompletenessHelper(m_AllResources.GetUniformBlocks(), pDynamicResources); - dbgVerifyBindingCompletenessHelper(m_AllResources.GetSamplers(), pDynamicResources); - dbgVerifyBindingCompletenessHelper(m_AllResources.GetImages(), pDynamicResources); - dbgVerifyBindingCompletenessHelper(m_AllResources.GetStorageBlocks(), pDynamicResources); + m_AllResources.LoadUniforms(Owner, pDeviceGLImpl, ShaderStage, GLProgram); } -#endif } diff --git a/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp b/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp index d662207f..21a2ac5d 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp @@ -22,19 +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) @@ -44,16 +62,238 @@ namespace Diligent *OpenBacketPtr = 0; } - void GLProgramResources::LoadUniforms(RenderDeviceGLImpl *pDeviceGLImpl, - GLuint GLProgram, - const SHADER_VARIABLE_TYPE DefaultVariableType, - const ShaderVariableDesc *VariableDesc, - Uint32 NumVars, - const StaticSamplerDesc *StaticSamplers, - Uint32 NumStaticSamplers) + 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; + GLint numActiveUniforms = 0; glGetProgramiv( GLProgram, GL_ACTIVE_UNIFORMS, &numActiveUniforms ); CHECK_GL_ERROR_AND_THROW( "Unable to get number of active uniforms\n" ); @@ -176,18 +416,19 @@ namespace Diligent // The latter is only available in GL 4.4 and GLES 3.1 RemoveArrayBrackets(Name.data()); - auto VarType = GetShaderVariableType(Name.data(), DefaultVariableType, VariableDesc, NumVars); - - RefCntAutoPtr<SamplerGLImpl> pStaticSampler; - for (Uint32 s = 0; s < NumStaticSamplers; ++s) - { - if (strcmp(Name.data(), StaticSamplers[s].SamplerOrTextureName) == 0) - { - pDeviceGLImpl->CreateSampler(StaticSamplers[s].Desc, reinterpret_cast<ISampler**>(static_cast<SamplerGLImpl**>(&pStaticSampler)) ); - break; - } - } - m_Samplers.emplace_back( Name.data(), size, VarType, 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; } @@ -235,8 +476,17 @@ namespace Diligent VERIFY( BindingPoint >= 0, "Incorrect binding point" ); RemoveArrayBrackets(Name.data()); - auto VarType = GetShaderVariableType(Name.data(), DefaultVariableType, VariableDesc, NumVars); - m_Images.emplace_back( Name.data(), size, VarType, 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 @@ -266,35 +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 } } } - - auto VarType = GetShaderVariableType(Name.data(), DefaultVariableType, VariableDesc, NumVars); - m_UniformBlocks.emplace_back( Name.data(), ArraySize, VarType, 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 @@ -320,146 +577,244 @@ 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 } } } - auto VarType = GetShaderVariableType(Name.data(), DefaultVariableType, VariableDesc, NumVars); - m_StorageBlocks.emplace_back( Name.data(), ArraySize, VarType, 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); } - static bool CheckType(SHADER_VARIABLE_TYPE Type, SHADER_VARIABLE_TYPE* AllowedTypes, Uint32 NumAllowedTypes) - { - for(Uint32 i=0; i < NumAllowedTypes; ++i) - if(Type == AllowedTypes[i]) - return true; - - return false; - } - void GLProgramResources::Clone(const GLProgramResources& SrcLayout, - SHADER_VARIABLE_TYPE* VarTypes, - Uint32 NumVarTypes, - IObject& Owner) + void GLProgramResources::Clone(RenderDeviceGLImpl* pDeviceGLImpl, + IObject& Owner, + const GLProgramResources& SrcResources, + const PipelineResourceLayoutDesc& ResourceLayout, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes) { - for (auto& ub : SrcLayout.m_UniformBlocks) + 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 (Uint32 ub=0; ub < SrcResources.GetNumUniformBuffers(); ++ub) { - if(CheckType(ub.VarType, VarTypes, NumVarTypes)) - m_UniformBlocks.emplace_back( ub.Name, ub.pResources.size(), ub.VarType, ub.Index ); + const auto& SrcUB = SrcResources.GetUniformBuffer(ub); + auto VarType = GetShaderVariableType(m_ShaderStages, SrcUB.Name, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) + { + 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 : SrcLayout.m_Samplers) + for (Uint32 sam = 0; sam < SrcResources.GetNumSamplers(); ++sam) { - if(CheckType(sam.VarType, VarTypes, NumVarTypes)) - m_Samplers.emplace_back( sam.Name, sam.pResources.size(), sam.VarType, sam.Location, sam.Type, const_cast<SamplerGLImpl*>(sam.pStaticSampler.RawPtr()) ); + 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(SrcSam.Name, StSam.SamplerOrTextureName) == 0) + { + pDeviceGLImpl->CreateSampler(StSam.Desc, &pStaticSampler); + break; + } + } + 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 : SrcLayout.m_Images) + for (Uint32 img = 0; img < SrcResources.GetNumImages(); ++img) { - if(CheckType(img.VarType, VarTypes, NumVarTypes)) - m_Images.emplace_back( img.Name, img.pResources.size(), img.VarType, img.BindingPoint, img.Type ); + const auto& SrcImg = SrcResources.GetImage(img); + auto VarType = GetShaderVariableType(m_ShaderStages, SrcImg.Name, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) + { + 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 : SrcLayout.m_StorageBlocks) + for (Uint32 sb = 0; sb < SrcResources.GetNumStorageBlocks(); ++sb) { - if(CheckType(sb.VarType, VarTypes, NumVarTypes)) - m_StorageBlocks.emplace_back( sb.Name, sb.pResources.size(), sb.VarType, sb.Binding ); + const auto& SrcSB = SrcResources.GetStorageBlock(sb); + auto VarType = GetShaderVariableType(m_ShaderStages, SrcSB.Name, ResourceLayout); + if (IsAllowedType(VarType, AllowedTypeBits)) + { + 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 - } - IShaderVariable* 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_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; @@ -467,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; } @@ -516,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()); - } + size_t hash = ComputeHash(GetNumUniformBuffers(), GetNumSamplers(), GetNumImages(), GetNumStorageBlocks()); - 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()); - } - - 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 3f0fed9b..8c8a106c 100644 --- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp @@ -53,10 +53,18 @@ void PipelineStateGLImpl::LinkGLProgram(bool bIsProgramPipelineSupported) // Program pipelines are not shared between GL contexts, so we cannot create // it now m_ShaderResourceLayoutHash = 0; + m_StaticResources.resize(m_NumShaders); for (Uint32 Shader = 0; Shader < m_NumShaders; ++Shader) { auto* pShaderGL = GetShader<ShaderGLImpl>(Shader); - HashCombine(m_ShaderResourceLayoutHash, pShaderGL->m_GlProgObj.GetAllResources().GetHash()); + const SHADER_RESOURCE_VARIABLE_TYPE StaticVars[] = {SHADER_RESOURCE_VARIABLE_TYPE_STATIC}; + m_StaticResources[Shader].Clone(GetDevice(), *this, pShaderGL->GetGlProgram().GetResources(), m_Desc.ResourceLayout, StaticVars, _countof(StaticVars)); + + const auto ShaderType = pShaderGL->GetDesc().ShaderType; + const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType); + m_ResourceLayoutIndex[ShaderTypeInd] = static_cast<Int8>(Shader); + + HashCombine(m_ShaderResourceLayoutHash, pShaderGL->m_GlProgObj.GetResources().GetHash()); } } else @@ -99,81 +107,22 @@ void PipelineStateGLImpl::LinkGLProgram(bool bIsProgramPipelineSupported) CHECK_GL_ERROR("glDetachShader() failed"); } - std::vector<ShaderVariableDesc> MergedVarTypesArray; - std::vector<StaticSamplerDesc> MergedStSamArray; - SHADER_VARIABLE_TYPE DefaultVarType = SHADER_VARIABLE_TYPE_STATIC; + SHADER_TYPE ShaderStages = SHADER_TYPE_UNKNOWN; for (Uint32 Shader = 0; Shader < m_NumShaders; ++Shader) { auto* pCurrShader = GetShader<ShaderGLImpl>(Shader); const auto& Desc = pCurrShader->GetDesc(); - if (Shader == 0) - { - DefaultVarType = Desc.DefaultVariableType; - } - else - { - if (DefaultVarType != Desc.DefaultVariableType) - { - LOG_ERROR_MESSAGE("When separate shader programs are not available, all shaders linked into a program " - "must use the same default variable type."); - } - } - - for (Uint32 v = 0; v < Desc.NumVariables; ++v) - { - const auto& NewVar = Desc.VariableDesc[v]; - bool VarExists = false; - for (const auto& Var : MergedVarTypesArray) - { - if (strcmp(Var.Name, NewVar.Name) == 0) - { - VarExists = true; - if (Var.Type != NewVar.Type) - { - LOG_ERROR_MESSAGE("The type of variable '", Var.Name, "' is not consistent between shader stages. " - "When separate shader programs are not available, all shaders must use the same " - "type for identically named shader variables."); - } - break; - } - } - - if (!VarExists) - { - MergedVarTypesArray.push_back(NewVar); - } - } - - for (Uint32 s = 0; s < Desc.NumStaticSamplers; ++s) - { - const auto& NewSampler = Desc.StaticSamplers[s]; - bool SamplerExists = false; - for (const auto& Sampler : MergedStSamArray) - { - if (strcmp(Sampler.SamplerOrTextureName, NewSampler.SamplerOrTextureName) == 0) - { - SamplerExists = true; - if ( !(Sampler.Desc == NewSampler.Desc) ) - { - LOG_ERROR_MESSAGE("Static sampler defined for texture '", NewSampler.SamplerOrTextureName, "' is not consistent between shader stages. " - "When separate shader programs are not available, all shaders must use the same " - "static samplers for identically named shader variables."); - } - break; - } - } - - if (!SamplerExists) - { - MergedStSamArray.push_back(NewSampler); - } - } + ShaderStages |= Desc.ShaderType; } auto pDeviceGL = GetDevice(); - m_GLProgram.InitResources(pDeviceGL, DefaultVarType, MergedVarTypesArray.data(), static_cast<Uint32>(MergedVarTypesArray.size()), MergedStSamArray.data(), static_cast<Uint32>(MergedStSamArray.size()), *this); + m_GLProgram.InitResources(pDeviceGL, ShaderStages, *this); + + m_StaticResources.resize(1); + const SHADER_RESOURCE_VARIABLE_TYPE StaticVars[] = {SHADER_RESOURCE_VARIABLE_TYPE_STATIC}; + m_StaticResources[0].Clone(GetDevice(), *this, m_GLProgram.GetResources(), m_Desc.ResourceLayout, StaticVars, _countof(StaticVars)); - m_ShaderResourceLayoutHash = m_GLProgram.GetAllResources().GetHash(); + m_ShaderResourceLayoutHash = m_GLProgram.GetResources().GetHash(); } } @@ -185,18 +134,6 @@ PipelineStateGLImpl::~PipelineStateGLImpl() IMPLEMENT_QUERY_INTERFACE( PipelineStateGLImpl, IID_PipelineStateGL, TPipelineStateBase ) -void PipelineStateGLImpl::BindShaderResources(IResourceMapping* pResourceMapping, Uint32 Flags) -{ - if (GetDevice()->GetDeviceCaps().bSeparableProgramSupported) - { - TPipelineStateBase::BindShaderResources(pResourceMapping, Flags); - } - else - { - if (m_GLProgram) - m_GLProgram.BindConstantResources(pResourceMapping, Flags); - } -} void PipelineStateGLImpl::CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources) { @@ -219,31 +156,81 @@ bool PipelineStateGLImpl::IsCompatibleWith(const IPipelineState* pPSO)const if (m_ShaderResourceLayoutHash != pPSOGL->m_ShaderResourceLayoutHash) return false; - return m_GLProgram.GetAllResources().IsCompatibleWith(pPSOGL->m_GLProgram.GetAllResources()); + return m_GLProgram.GetResources().IsCompatibleWith(pPSOGL->m_GLProgram.GetResources()); } GLObjectWrappers::GLPipelineObj& PipelineStateGLImpl::GetGLProgramPipeline(GLContext::NativeGLContextType Context) { ThreadingTools::LockHelper Lock(m_ProgPipelineLockFlag); - auto it = m_GLProgPipelines.find(Context); - if (it != m_GLProgPipelines.end()) - return it->second; + for(auto& ctx_pipeline : m_GLProgPipelines) + { + if (ctx_pipeline.first == Context) + return ctx_pipeline.second; + } + + // Create new progam pipeline + m_GLProgPipelines.emplace_back(Context, true); + auto& ctx_pipeline = m_GLProgPipelines.back(); + GLuint Pipeline = ctx_pipeline.second; + for (Uint32 Shader = 0; Shader < m_NumShaders; ++Shader) + { + auto* pCurrShader = GetShader<ShaderGLImpl>(Shader); + auto GLShaderBit = ShaderTypeToGLShaderBit(pCurrShader->GetDesc().ShaderType); + // If the program has an active code for each stage mentioned in set flags, + // then that code will be used by the pipeline. If program is 0, then the given + // stages are cleared from the pipeline. + glUseProgramStages(Pipeline, GLShaderBit, pCurrShader->m_GlProgObj); + CHECK_GL_ERROR("glUseProgramStages() failed"); + } + return ctx_pipeline.second; +} + + +void PipelineStateGLImpl::BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags) +{ + for(auto& StaticRes : m_StaticResources) + { + if ((StaticRes.GetShaderStages() & ShaderFlags)!=0) + StaticRes.BindResources(pResourceMapping, Flags); + } +} + +Uint32 PipelineStateGLImpl::GetStaticVariableCount(SHADER_TYPE ShaderType) const +{ + if (m_GLProgram) + { + return (m_StaticResources[0].GetShaderStages() & ShaderType) != 0 ? m_StaticResources[0].GetVariableCount() : 0; + } else { - // Create new progam pipeline - it = m_GLProgPipelines.emplace(Context, true).first; - GLuint Pipeline = it->second; - for (Uint32 Shader = 0; Shader < m_NumShaders; ++Shader) - { - auto* pCurrShader = GetShader<ShaderGLImpl>(Shader); - auto GLShaderBit = ShaderTypeToGLShaderBit(pCurrShader->GetDesc().ShaderType); - // If the program has an active code for each stage mentioned in set flags, - // then that code will be used by the pipeline. If program is 0, then the given - // stages are cleared from the pipeline. - glUseProgramStages(Pipeline, GLShaderBit, pCurrShader->m_GlProgObj); - CHECK_GL_ERROR("glUseProgramStages() failed"); - } - return it->second; + const auto LayoutInd = m_ResourceLayoutIndex[GetShaderTypeIndex(ShaderType)]; + return LayoutInd >= 0 ? m_StaticResources[LayoutInd].GetVariableCount() : 0; + } +} + +IShaderResourceVariable* PipelineStateGLImpl::GetStaticShaderVariable(SHADER_TYPE ShaderType, const Char* Name) +{ + if (m_GLProgram) + { + return (m_StaticResources[0].GetShaderStages() & ShaderType) != 0 ? m_StaticResources[0].GetVariable(Name) : nullptr; + } + else + { + const auto LayoutInd = m_ResourceLayoutIndex[GetShaderTypeIndex(ShaderType)]; + return LayoutInd >= 0 ? m_StaticResources[LayoutInd].GetVariable(Name) : nullptr; + } +} + +IShaderResourceVariable* PipelineStateGLImpl::GetStaticShaderVariable(SHADER_TYPE ShaderType, Uint32 Index) +{ + if (m_GLProgram) + { + return (m_StaticResources[0].GetShaderStages() & ShaderType) != 0 ? m_StaticResources[0].GetVariable(Index) : nullptr; + } + else + { + const auto LayoutInd = m_ResourceLayoutIndex[GetShaderTypeIndex(ShaderType)]; + return LayoutInd >= 0 ? m_StaticResources[LayoutInd].GetVariable(Index) : nullptr; } } diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp index 9d630130..6e5ba17c 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp @@ -47,10 +47,10 @@ namespace Diligent { -RenderDeviceGLImpl :: RenderDeviceGLImpl(IReferenceCounters* pRefCounters, - IMemoryAllocator& RawMemAllocator, - const EngineGLAttribs& InitAttribs, - const SwapChainDesc* pSCDesc): +RenderDeviceGLImpl :: RenderDeviceGLImpl(IReferenceCounters* pRefCounters, + IMemoryAllocator& RawMemAllocator, + const EngineGLCreateInfo& InitAttribs, + const SwapChainDesc* pSCDesc): TRenderDeviceBase { pRefCounters, @@ -139,13 +139,13 @@ void RenderDeviceGLImpl :: CreateBufferFromGLHandle(Uint32 GLHandle, const Buffe ); } -void RenderDeviceGLImpl :: CreateShader(const ShaderCreationAttribs& ShaderCreationAttribs, IShader** ppShader, bool bIsDeviceInternal) +void RenderDeviceGLImpl :: CreateShader(const ShaderCreateInfo& ShaderCreateInfo, IShader** ppShader, bool bIsDeviceInternal) { - CreateDeviceObject( "shader", ShaderCreationAttribs.Desc, ppShader, + CreateDeviceObject( "shader", ShaderCreateInfo.Desc, ppShader, [&]() { ShaderGLImpl *pShaderOGL(NEW_RC_OBJ(m_ShaderObjAllocator, "ShaderGLImpl instance", ShaderGLImpl) - (this, ShaderCreationAttribs, bIsDeviceInternal)); + (this, ShaderCreateInfo, bIsDeviceInternal)); pShaderOGL->QueryInterface(IID_Shader, reinterpret_cast<IObject**>(ppShader) ); OnCreateDeviceObject( pShaderOGL ); @@ -153,9 +153,9 @@ void RenderDeviceGLImpl :: CreateShader(const ShaderCreationAttribs& ShaderCreat ); } -void RenderDeviceGLImpl :: CreateShader(const ShaderCreationAttribs& ShaderCreationAttribs, IShader **ppShader) +void RenderDeviceGLImpl :: CreateShader(const ShaderCreateInfo& ShaderCreateInfo, IShader **ppShader) { - CreateShader(ShaderCreationAttribs, ppShader, false); + CreateShader(ShaderCreateInfo, ppShader, false); } void RenderDeviceGLImpl :: CreateTexture(const TextureDesc& TexDesc, const TextureData* pData, ITexture **ppTexture, bool bIsDeviceInternal) diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp index 65a797c0..e42ca9ef 100644 --- a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp @@ -33,10 +33,10 @@ using namespace Diligent; namespace Diligent { -ShaderGLImpl::ShaderGLImpl(IReferenceCounters* pRefCounters, - RenderDeviceGLImpl* pDeviceGL, - const ShaderCreationAttribs& CreationAttribs, - bool bIsDeviceInternal) : +ShaderGLImpl::ShaderGLImpl(IReferenceCounters* pRefCounters, + RenderDeviceGLImpl* pDeviceGL, + const ShaderCreateInfo& CreationAttribs, + bool bIsDeviceInternal) : TShaderBase( pRefCounters, pDeviceGL, CreationAttribs.Desc, bIsDeviceInternal ), m_GlProgObj(false), m_GLShaderObj( false, GLObjectWrappers::GLShaderObjCreateReleaseHelper( GetGLShaderType( m_Desc.ShaderType ) ) ) @@ -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.DefaultVariableType, m_Desc.VariableDesc, m_Desc.NumVariables, m_Desc.StaticSamplers, m_Desc.NumStaticSamplers, *this); + m_GlProgObj.InitResources(pDeviceGL, m_Desc.ShaderType, *this); } else { @@ -174,68 +174,33 @@ ShaderGLImpl::~ShaderGLImpl() IMPLEMENT_QUERY_INTERFACE( ShaderGLImpl, IID_ShaderGL, TShaderBase ) -void ShaderGLImpl::BindResources( IResourceMapping* pResourceMapping, Uint32 Flags ) +Uint32 ShaderGLImpl::GetResourceCount()const { - if( static_cast<GLuint>(m_GlProgObj) ) + Uint32 ResCount = 0; + if (m_GlProgObj) { - m_GlProgObj.BindConstantResources( pResourceMapping, Flags ); + return m_GlProgObj.GetResources().GetVariableCount(); } else { - LOG_WARNING_MESSAGE_ONCE( "IShader::BindResources() effectively does nothing when separable programs are not supported by the device." ); + LOG_WARNING_MESSAGE("Shader resource queries are not available when separate shader objects are unsupported"); } + return ResCount; } -IShaderVariable* ShaderGLImpl::GetShaderVariable(const Char* Name) +ShaderResourceDesc ShaderGLImpl::GetResource(Uint32 Index)const { - return GetShaderVariable(Name, true); -} - -IShaderVariable* ShaderGLImpl::GetShaderVariable(const Char* Name, bool CreatePlaceholder) -{ - if( m_GlProgObj ) - return m_GlProgObj.GetConstantResources().GetShaderVariable(Name); - else + ShaderResourceDesc ResourceDesc; + if (m_GlProgObj) { - for (auto& Res : m_StaticResources) - { - if( strcmp(Res->GetName(), Name) == 0) - return Res; - } - - if (CreatePlaceholder) - { - auto* pNewVar = MakeNewRCObj<StaticVarPlaceholder>()(Name, static_cast<Uint32>(m_StaticResources.size())); - m_StaticResources.emplace_back(pNewVar); - return pNewVar; - } - else - { - return nullptr; - } - } -} - -Uint32 ShaderGLImpl::GetVariableCount() const -{ - if( m_GlProgObj ) - return m_GlProgObj.GetConstantResources().GetVariableCount(); - else - { - LOG_WARNING_MESSAGE("When separate shader objects are unavailable, GetVariableCount() returns the number of resources being set so far " - "rather than the total number of static shader resources."); - return static_cast<Uint32>(m_StaticResources.size()); + DEV_CHECK_ERR(Index < GetResourceCount(), "Index is out of range"); + ResourceDesc = m_GlProgObj.GetResources().GetVariable(Index)->GetResourceDesc(); } -} - -IShaderVariable* ShaderGLImpl::GetShaderVariable(Uint32 Index) -{ - if( m_GlProgObj ) - return m_GlProgObj.GetConstantResources().GetShaderVariable(Index); else { - return Index < m_StaticResources.size() ? m_StaticResources[Index].RawPtr() : nullptr; + LOG_WARNING_MESSAGE("Shader resource queries are not available when separate shader objects are unsupported"); } + return ResourceDesc; } } diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp index f58be350..b1099e09 100644 --- a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp @@ -31,31 +31,25 @@ namespace Diligent { ShaderResourceBindingGLImpl::ShaderResourceBindingGLImpl(IReferenceCounters* pRefCounters, PipelineStateGLImpl* pPSO) : - TBase (pRefCounters, pPSO) + TBase (pRefCounters, pPSO), + m_Resources(pPSO->GetGLProgram() == 0 ? pPSO->GetNumShaders() : 1) { + const SHADER_RESOURCE_VARIABLE_TYPE SRBVarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}; if (IsUsingSeparatePrograms()) { - SHADER_VARIABLE_TYPE VarTypes[] = {SHADER_VARIABLE_TYPE_MUTABLE, SHADER_VARIABLE_TYPE_DYNAMIC}; -#define INIT_SHADER(SN)\ - if(auto p##SN = ValidatedCast<ShaderGLImpl>( pPSO->Get##SN() )) \ - { \ - auto &GLProg = p##SN->GetGlProgram(); \ - m_DynamicProgResources[SN##Ind].Clone(GLProg.GetAllResources(), VarTypes, _countof(VarTypes), *this); \ + + for (Uint32 s = 0; s < pPSO->GetNumShaders(); ++s) + { + auto* pShaderGL = pPSO->GetShader<ShaderGLImpl>(s); + m_Resources[s].Clone(pPSO->GetDevice(), *this, pShaderGL->GetGlProgram().GetResources(), pPSO->GetDesc().ResourceLayout, SRBVarTypes, _countof(SRBVarTypes)); + const auto ShaderType = pShaderGL->GetDesc().ShaderType; + const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType); + m_ResourceIndex[ShaderTypeInd] = static_cast<Int8>(s); } - - INIT_SHADER(VS) - INIT_SHADER(PS) - INIT_SHADER(GS) - INIT_SHADER(HS) - INIT_SHADER(DS) - INIT_SHADER(CS) -#undef INIT_SHADER } else { - // Clone all variable types - SHADER_VARIABLE_TYPE VarTypes[] = {SHADER_VARIABLE_TYPE_STATIC, SHADER_VARIABLE_TYPE_MUTABLE, SHADER_VARIABLE_TYPE_DYNAMIC}; - m_DynamicProgResources[0].Clone(pPSO->GetGLProgram().GetAllResources(), VarTypes, _countof(VarTypes), *this); + m_Resources[0].Clone(pPSO->GetDevice(), *this, pPSO->GetGLProgram().GetResources(), pPSO->GetDesc().ResourceLayout, SRBVarTypes, _countof(SRBVarTypes)); } } @@ -72,48 +66,54 @@ bool ShaderResourceBindingGLImpl::IsUsingSeparatePrograms()const void ShaderResourceBindingGLImpl::BindResources(Uint32 ShaderFlags, IResourceMapping* pResMapping, Uint32 Flags) { + for(auto& Resource : m_Resources) + { + if ((Resource.GetShaderStages() & ShaderFlags)!=0) + Resource.BindResources(pResMapping, Flags); + } +} + +IShaderResourceVariable* ShaderResourceBindingGLImpl::GetVariable(SHADER_TYPE ShaderType, const char* Name) +{ if (IsUsingSeparatePrograms()) { - if(ShaderFlags & SHADER_TYPE_VERTEX) - m_DynamicProgResources[VSInd].BindResources(pResMapping, Flags); - if(ShaderFlags & SHADER_TYPE_PIXEL) - m_DynamicProgResources[PSInd].BindResources(pResMapping, Flags); - if(ShaderFlags & SHADER_TYPE_GEOMETRY) - m_DynamicProgResources[GSInd].BindResources(pResMapping, Flags); - if(ShaderFlags & SHADER_TYPE_HULL) - m_DynamicProgResources[HSInd].BindResources(pResMapping, Flags); - if(ShaderFlags & SHADER_TYPE_DOMAIN) - m_DynamicProgResources[DSInd].BindResources(pResMapping, Flags); - if(ShaderFlags & SHADER_TYPE_COMPUTE) - m_DynamicProgResources[CSInd].BindResources(pResMapping, Flags); + auto ShaderInd = m_ResourceIndex[GetShaderTypeIndex(ShaderType)]; + return ShaderInd >= 0 ? m_Resources[ShaderInd].GetVariable(Name) : nullptr; } else { - // Using non-separable program - m_DynamicProgResources[0].BindResources(pResMapping, Flags); + return (m_Resources[0].GetShaderStages() & ShaderType) != 0 ? m_Resources[0].GetVariable(Name) : nullptr; } } -IShaderVariable* ShaderResourceBindingGLImpl::GetVariable(SHADER_TYPE ShaderType, const char* Name) -{ - auto ShaderInd = IsUsingSeparatePrograms() ? GetShaderTypeIndex(ShaderType) : 0; - return m_DynamicProgResources[ShaderInd].GetShaderVariable(Name); -} - Uint32 ShaderResourceBindingGLImpl::GetVariableCount(SHADER_TYPE ShaderType) const { - auto ShaderInd = IsUsingSeparatePrograms() ? GetShaderTypeIndex(ShaderType) : 0; - return m_DynamicProgResources[ShaderInd].GetVariableCount(); + if (IsUsingSeparatePrograms()) + { + auto ShaderInd = m_ResourceIndex[GetShaderTypeIndex(ShaderType)]; + return ShaderInd >= 0 ? m_Resources[ShaderInd].GetVariableCount() : 0; + } + else + { + return (m_Resources[0].GetShaderStages() & ShaderType) != 0 ? m_Resources[0].GetVariableCount() : 0; + } } -IShaderVariable* ShaderResourceBindingGLImpl::GetVariable(SHADER_TYPE ShaderType, Uint32 Index) +IShaderResourceVariable* ShaderResourceBindingGLImpl::GetVariable(SHADER_TYPE ShaderType, Uint32 Index) { - auto ShaderInd = IsUsingSeparatePrograms() ? GetShaderTypeIndex(ShaderType) : 0; - return m_DynamicProgResources[ShaderInd].GetShaderVariable(Index); + if (IsUsingSeparatePrograms()) + { + auto ShaderInd = m_ResourceIndex[GetShaderTypeIndex(ShaderType)]; + return ShaderInd >= 0 ? m_Resources[ShaderInd].GetVariable(Index) : 0; + } + else + { + return (m_Resources[0].GetShaderStages() & ShaderType) != 0 ? m_Resources[0].GetVariable(Index) : nullptr; + } } static GLProgramResources NullProgramResources; -GLProgramResources& ShaderResourceBindingGLImpl::GetProgramResources(SHADER_TYPE ShaderType, PipelineStateGLImpl* pdbgPSO) +GLProgramResources& ShaderResourceBindingGLImpl::GetResources(Uint32 Ind, PipelineStateGLImpl* pdbgPSO) { #ifdef _DEBUG if (pdbgPSO->IsIncompatibleWith(GetPipelineState())) @@ -121,84 +121,12 @@ GLProgramResources& ShaderResourceBindingGLImpl::GetProgramResources(SHADER_TYPE LOG_ERROR("Shader resource binding is incompatible with the currently bound pipeline state."); } #endif - auto ShaderInd = IsUsingSeparatePrograms() ? GetShaderTypeIndex(ShaderType) : 0; - return m_DynamicProgResources[ShaderInd]; + return m_Resources[Ind]; } void ShaderResourceBindingGLImpl::InitializeStaticResources(const IPipelineState* pPipelineState) { - if (!IsUsingSeparatePrograms()) - { - class ResourceMappingProxy final : public IResourceMapping - { - public: - ResourceMappingProxy(const PipelineStateGLImpl& PSO) : - m_PSO(PSO) - { - } - virtual void QueryInterface (const INTERFACE_ID& IID, IObject** ppInterface)override final - { - UNEXPECTED("This method should never be called"); - } - virtual CounterValueType AddRef()override final - { - UNEXPECTED("This method should never be called"); - return 0; - } - virtual CounterValueType Release()override final - { - UNEXPECTED("This method should never be called"); - return 0; - } - virtual IReferenceCounters* GetReferenceCounters()const override final - { - UNEXPECTED("This method should never be called"); - return nullptr; - } - virtual void AddResource (const Char* Name, IDeviceObject* pObject, bool bIsUnique)override final - { - UNEXPECTED("This method should never be called"); - } - virtual void AddResourceArray (const Char* Name, Uint32 StartIndex, IDeviceObject* const* ppObjects, Uint32 NumElements, bool bIsUnique)override final - { - UNEXPECTED("This method should never be called"); - } - virtual void RemoveResourceByName (const Char* Name, Uint32 ArrayIndex = 0) - { - UNEXPECTED("This method should never be called"); - } - virtual void GetResource (const Char* Name, IDeviceObject** ppResource, Uint32 ArrayIndex = 0) - { - auto NumShaders = m_PSO.GetNumShaders(); - for (Uint32 s=0; s < NumShaders; ++s) - { - auto* pShader = m_PSO.GetShader<ShaderGLImpl>(s); - auto* pVar = pShader->GetShaderVariable(Name, false); - if (pVar != nullptr) - { - auto* pStaticVarPlaceholder = ValidatedCast<ShaderGLImpl::StaticVarPlaceholder>(pVar); - *ppResource = pStaticVarPlaceholder->Get(ArrayIndex); - if (*ppResource != nullptr) - (*ppResource)->AddRef(); - } - } - } - virtual size_t GetSize() - { - UNEXPECTED("This method should never be called"); - return 0; - } - private: - const PipelineStateGLImpl& m_PSO; - }; - - if (pPipelineState != nullptr) - { - const auto* PSOGL = ValidatedCast<const PipelineStateGLImpl>(pPipelineState); - ResourceMappingProxy StaticResMapping(*PSOGL); - m_DynamicProgResources[0].BindResources(&StaticResMapping, 0); - } - } + // Do nothing } } diff --git a/Graphics/GraphicsEngineOpenGL/src/SwapChainGLIOS.mm b/Graphics/GraphicsEngineOpenGL/src/SwapChainGLIOS.mm index 679ea021..7e285249 100644 --- a/Graphics/GraphicsEngineOpenGL/src/SwapChainGLIOS.mm +++ b/Graphics/GraphicsEngineOpenGL/src/SwapChainGLIOS.mm @@ -30,15 +30,14 @@ #include "DeviceContextGLImpl.h" #include "RenderDeviceGLImpl.h" #include "SwapChainGLIOS.h" -#include "EngineGLAttribs.h" namespace Diligent { -SwapChainGLIOS::SwapChainGLIOS(IReferenceCounters *pRefCounters, - const EngineGLAttribs &InitAttribs, - const SwapChainDesc& SCDesc, - RenderDeviceGLImpl* pRenderDeviceGL, - DeviceContextGLImpl* pImmediateContextGL) : +SwapChainGLIOS::SwapChainGLIOS(IReferenceCounters* pRefCounters, + const EngineGLCreateInfo& InitAttribs, + const SwapChainDesc& SCDesc, + RenderDeviceGLImpl* pRenderDeviceGL, + DeviceContextGLImpl* pImmediateContextGL) : TSwapChainBase( pRefCounters, pRenderDeviceGL, pImmediateContextGL, SCDesc), m_ColorRenderBuffer(false), m_DepthRenderBuffer(false), diff --git a/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp index bf1e706c..01f1e5ec 100644 --- a/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp @@ -28,11 +28,11 @@ namespace Diligent { -SwapChainGLImpl::SwapChainGLImpl(IReferenceCounters *pRefCounters, - const EngineGLAttribs &InitAttribs, - const SwapChainDesc& SCDesc, - RenderDeviceGLImpl* pRenderDeviceGL, - DeviceContextGLImpl* pImmediateContextGL) : +SwapChainGLImpl::SwapChainGLImpl(IReferenceCounters* pRefCounters, + const EngineGLCreateInfo& InitAttribs, + const SwapChainDesc& SCDesc, + RenderDeviceGLImpl* pRenderDeviceGL, + DeviceContextGLImpl* pImmediateContextGL) : TSwapChainBase( pRefCounters, pRenderDeviceGL, pImmediateContextGL, SCDesc) { #if PLATFORM_WIN32 diff --git a/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp b/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp index 312889e7..abd5c9f2 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TexRegionRender.cpp @@ -58,10 +58,9 @@ namespace Diligent TexRegionRender::TexRegionRender( class RenderDeviceGLImpl *pDeviceGL ) { - ShaderCreationAttribs ShaderAttrs; + ShaderCreateInfo ShaderAttrs; ShaderAttrs.Desc.Name = "TexRegionRender : Vertex shader"; ShaderAttrs.Desc.ShaderType = SHADER_TYPE_VERTEX; - ShaderAttrs.Desc.DefaultVariableType = SHADER_VARIABLE_TYPE_DYNAMIC; ShaderAttrs.Source = VertexShaderSource; constexpr bool IsInternalDeviceObject = true; pDeviceGL->CreateShader(ShaderAttrs, &m_pVertexShader, IsInternalDeviceObject); @@ -117,12 +116,6 @@ namespace Diligent Name.append(SamplerDim); ShaderAttrs.Desc.Name = Name.c_str(); ShaderAttrs.Desc.ShaderType = SHADER_TYPE_PIXEL; - ShaderVariableDesc Vars[] = - { - {"cbConstants", SHADER_VARIABLE_TYPE_MUTABLE} - }; - ShaderAttrs.Desc.NumVariables = _countof(Vars); - ShaderAttrs.Desc.VariableDesc = Vars; std::stringstream SourceSS; SourceSS << "uniform " << Prefix << SamplerDim << " gSourceTex;\n" @@ -141,6 +134,15 @@ namespace Diligent auto &FragmetShader = m_pFragmentShaders[Dim*3 + Fmt]; pDeviceGL->CreateShader(ShaderAttrs, &FragmetShader, IsInternalDeviceObject); GraphicsPipeline.pPS = FragmetShader; + + PSODesc.ResourceLayout.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC; + ShaderResourceVariableDesc Vars[] = + { + {SHADER_TYPE_PIXEL, "cbConstants", SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE} + }; + PSODesc.ResourceLayout.NumVariables = _countof(Vars); + PSODesc.ResourceLayout.Variables = Vars; + pDeviceGL->CreatePipelineState(PSODesc, &m_pPSO[Dim*3 + Fmt], IsInternalDeviceObject); } m_pPSO[RESOURCE_DIM_TEX_2D*3]->CreateShaderResourceBinding(&m_pSRB); |
