From 785a72c96e86244a978838b979bee8fa7525903f Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sat, 12 Oct 2019 17:13:38 -0700 Subject: OpenGL backend: improved buffer binding --- .../GraphicsEngineOpenGL/include/BufferGLImpl.h | 10 +- .../include/DeviceContextGLImpl.h | 3 - .../GraphicsEngineOpenGL/include/GLContextState.h | 136 +++++++++++++-------- .../GraphicsEngineOpenGL/include/GLObjectWrapper.h | 7 +- .../include/GLTypeConversions.h | 9 +- Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp | 81 ++++++------ .../src/DeviceContextGLImpl.cpp | 43 +++---- .../GraphicsEngineOpenGL/src/GLContextState.cpp | 83 +++++++++++-- .../src/GLProgramResources.cpp | 2 +- .../src/PipelineStateGLImpl.cpp | 2 +- .../src/RenderDeviceGLImpl.cpp | 4 +- .../src/Texture1DArray_OGL.cpp | 4 +- .../GraphicsEngineOpenGL/src/Texture1D_OGL.cpp | 4 +- .../src/Texture2DArray_OGL.cpp | 4 +- .../GraphicsEngineOpenGL/src/Texture2D_OGL.cpp | 4 +- .../GraphicsEngineOpenGL/src/Texture3D_OGL.cpp | 4 +- .../GraphicsEngineOpenGL/src/TextureBaseGL.cpp | 4 +- .../src/TextureCubeArray_OGL.cpp | 4 +- .../GraphicsEngineOpenGL/src/TextureCube_OGL.cpp | 4 +- Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp | 14 ++- 20 files changed, 253 insertions(+), 173 deletions(-) (limited to 'Graphics/GraphicsEngineOpenGL') diff --git a/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.h index 96de1119..2a2186e1 100644 --- a/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.h @@ -46,14 +46,14 @@ public: BufferGLImpl(IReferenceCounters* pRefCounters, FixedBlockMemoryAllocator& BuffViewObjMemAllocator, RenderDeviceGLImpl* pDeviceGL, - DeviceContextGLImpl* pCtxGL, + GLContextState& CtxState, const BufferDesc& BuffDesc, const BufferData* pBuffData, bool bIsDeviceInternal); BufferGLImpl(IReferenceCounters* pRefCounters, FixedBlockMemoryAllocator& BuffViewObjMemAllocator, class RenderDeviceGLImpl* pDeviceGL, - DeviceContextGLImpl* pCtxGL, + GLContextState& CtxState, const BufferDesc& BuffDesc, GLuint GLHandle, bool bIsDeviceInternal); @@ -62,10 +62,10 @@ public: /// Queries the specific interface, see IObject::QueryInterface() for details virtual void QueryInterface( const INTERFACE_ID& IID, IObject** ppInterface )override; - void UpdateData(DeviceContextGLImpl* pCtxGL, Uint32 Offset, Uint32 Size, const PVoid pData); + void UpdateData(GLContextState& CtxState, Uint32 Offset, Uint32 Size, const PVoid pData); void CopyData(GLContextState& CtxState, BufferGLImpl& SrcBufferGL, Uint32 SrcOffset, Uint32 DstOffset, Uint32 Size); void Map(GLContextState& CtxState, MAP_TYPE MapType, Uint32 MapFlags, PVoid& pMappedData ); - void Unmap(); + void Unmap(GLContextState& CtxState); void BufferMemoryBarrier( Uint32 RequiredBarriers, class GLContextState &GLContextState ); @@ -81,7 +81,7 @@ private: friend class VAOCache; GLObjectWrappers::GLBufferObj m_GlBuffer; - Uint32 m_uiMapTarget; + const Uint32 m_BindTarget; const GLenum m_GLUsageHint; const Bool m_bUseMapWriteDiscardBugWA; }; diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h index 6f1aea88..917df61a 100644 --- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h @@ -162,8 +162,6 @@ public: void CommitRenderTargets(); - void ResetVAO(); - protected: friend class BufferGLImpl; friend class TextureBaseGL; @@ -177,7 +175,6 @@ private: std::vector m_BoundWritableTextures; std::vector m_BoundWritableBuffers; - bool m_bVAOIsUpToDate = false; GLObjectWrappers::GLFrameBufferObj m_DefaultFBO; }; diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextState.h b/Graphics/GraphicsEngineOpenGL/include/GLContextState.h index 050bc44f..9d1d5af6 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextState.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextState.h @@ -36,53 +36,60 @@ class GLContextState public: GLContextState(class RenderDeviceGLImpl *pDeviceGL); - void SetProgram( const GLObjectWrappers::GLProgramObj &GLProgram ); - void SetPipeline( const GLObjectWrappers::GLPipelineObj &GLPipeline ); - void BindVAO( const GLObjectWrappers::GLVertexArrayObj &VAO ); - void BindFBO( const GLObjectWrappers::GLFrameBufferObj &FBO ); - void SetActiveTexture( Int32 Index ); - void BindTexture( Int32 Index, GLenum BindTarget, const GLObjectWrappers::GLTextureObj &Tex); - void BindSampler( Uint32 Index, const GLObjectWrappers::GLSamplerObj &GLSampler); - void BindImage( Uint32 Index, class TextureViewGLImpl *pTexView, GLint MipLevel, GLboolean IsLayered, GLint Layer, GLenum Access, GLenum Format ); - void BindImage( Uint32 Index, class BufferViewGLImpl *pBuffView, GLenum Access, GLenum Format ); + void SetProgram (const GLObjectWrappers::GLProgramObj& GLProgram); + void SetPipeline (const GLObjectWrappers::GLPipelineObj& GLPipeline); + void BindVAO (const GLObjectWrappers::GLVertexArrayObj& VAO); + void BindFBO (const GLObjectWrappers::GLFrameBufferObj& FBO); + void SetActiveTexture (Int32 Index); + void BindTexture (Int32 Index, GLenum BindTarget, const GLObjectWrappers::GLTextureObj& Tex); + void BindUniformBuffer (Int32 Index, const GLObjectWrappers::GLBufferObj& Buff); + void BindBuffer (GLenum BindTarget, const GLObjectWrappers::GLBufferObj& Buff, bool ResetVAO); + void BindSampler (Uint32 Index, const GLObjectWrappers::GLSamplerObj& GLSampler); + void BindImage (Uint32 Index, class TextureViewGLImpl* pTexView, GLint MipLevel, GLboolean IsLayered, GLint Layer, GLenum Access, GLenum Format); + void BindImage (Uint32 Index, class BufferViewGLImpl* pBuffView, GLenum Access, GLenum Format); + void BindStorageBlock (Int32 Index, const GLObjectWrappers::GLBufferObj& Buff, GLintptr Offset, GLsizeiptr Size); + void EnsureMemoryBarrier(Uint32 RequiredBarriers, class AsyncWritableResource *pRes = nullptr); - void SetPendingMemoryBarriers( Uint32 PendingBarriers ); + void SetPendingMemoryBarriers(Uint32 PendingBarriers); - void EnableDepthTest( Bool bEnable ); - void EnableDepthWrites( Bool bEnable ); - void SetDepthFunc(COMPARISON_FUNCTION CmpFunc); - void EnableStencilTest( Bool bEnable ); - void SetStencilWriteMask( Uint8 StencilWriteMask ); - void SetStencilRef( GLenum Face, Int32 Ref ); - void SetStencilFunc( GLenum Face, COMPARISON_FUNCTION Func, Int32 Ref, Uint32 Mask ); - void SetStencilOp( GLenum Face, STENCIL_OP StencilFailOp, STENCIL_OP StencilDepthFailOp, STENCIL_OP StencilPassOp ); - - void SetFillMode( FILL_MODE FillMode ); - void SetCullMode( CULL_MODE CullMode ); - void SetFrontFace( Bool FrontCounterClockwise ); - void SetDepthBias( float DepthBias, float fSlopeScaledDepthBias ); - void SetDepthClamp( Bool bEnableDepthClamp ); - void EnableScissorTest( Bool bEnableScissorTest ); - - void SetBlendFactors(const float *BlendFactors); - void SetBlendState(const BlendStateDesc &BSDsc, Uint32 SampleMask); + void EnableDepthTest (bool bEnable); + void EnableDepthWrites (bool bEnable); + void SetDepthFunc (COMPARISON_FUNCTION CmpFunc); + void EnableStencilTest (bool bEnable); + void SetStencilWriteMask (Uint8 StencilWriteMask); + void SetStencilRef (GLenum Face, Int32 Ref); + void SetStencilFunc (GLenum Face, COMPARISON_FUNCTION Func, Int32 Ref, Uint32 Mask); + void SetStencilOp (GLenum Face, STENCIL_OP StencilFailOp, STENCIL_OP StencilDepthFailOp, STENCIL_OP StencilPassOp); + void SetFillMode (FILL_MODE FillMode); + void SetCullMode (CULL_MODE CullMode); + void SetFrontFace (bool FrontCounterClockwise); + void SetDepthBias (float DepthBias, float fSlopeScaledDepthBias); + void SetDepthClamp (bool bEnableDepthClamp); + void EnableScissorTest (bool bEnableScissorTest); + + void SetBlendFactors(const float* BlendFactors); + void SetBlendState(const BlendStateDesc& BSDsc, Uint32 SampleMask); Bool GetDepthWritesEnabled(){ return m_DSState.m_DepthWritesEnableState; } Bool GetScissorTestEnabled(){ return m_RSState.ScissorTestEnable; } - void GetColorWriteMask( Uint32 RTIndex, Uint32 &WriteMask, Bool &bIsIndependent ); - void SetColorWriteMask( Uint32 RTIndex, Uint32 WriteMask, Bool bIsIndependent ); + void GetColorWriteMask(Uint32 RTIndex, Uint32& WriteMask, Bool& bIsIndependent); + void SetColorWriteMask(Uint32 RTIndex, Uint32 WriteMask, Bool bIsIndependent); void SetNumPatchVertices( Int32 NumVertices); void Invalidate(); + void InvalidateVAO(){m_VAOId = -1;} + bool IsValidVAOBound()const {return m_VAOId > 0;} + void SetCurrentGLContext(GLContext::NativeGLContextType Context) { m_CurrentGLContext = Context; } GLContext::NativeGLContextType GetCurrentGLContext()const { return m_CurrentGLContext; } struct ContextCaps { - bool bFillModeSelectionSupported = True; - GLint m_iMaxCombinedTexUnits = 0; - GLint m_iMaxDrawBuffers = 0; + bool bFillModeSelectionSupported = true; + GLint m_iMaxCombinedTexUnits = 0; + GLint m_iMaxDrawBuffers = 0; + GLint m_iMaxUniformBufferBindings = 0; }; const ContextCaps& GetContextCaps(){return m_Caps;} @@ -94,35 +101,37 @@ private: // the system can reuse the same address // The safest way is to keep global unique ID for all objects - Diligent::UniqueIdentifier m_GLProgId = -1; - Diligent::UniqueIdentifier m_GLPipelineId = -1; - Diligent::UniqueIdentifier m_VAOId = -1; - Diligent::UniqueIdentifier m_FBOId = -1; - std::vector< Diligent::UniqueIdentifier > m_BoundTextures; - std::vector< Diligent::UniqueIdentifier > m_BoundSamplers; + UniqueIdentifier m_GLProgId = -1; + UniqueIdentifier m_GLPipelineId = -1; + UniqueIdentifier m_VAOId = -1; + UniqueIdentifier m_FBOId = -1; + std::vector< UniqueIdentifier > m_BoundTextures; + std::vector< UniqueIdentifier > m_BoundSamplers; + std::vector< UniqueIdentifier > m_BoundUniformBuffers; + struct BoundImageInfo { - Diligent::UniqueIdentifier InterfaceID = -1; - GLint MipLevel = 0; - GLboolean IsLayered = 0; - GLint Layer = 0; - GLenum Access = 0; - GLenum Format = 0; + UniqueIdentifier InterfaceID = -1; + GLint MipLevel = 0; + GLboolean IsLayered = 0; + GLint Layer = 0; + GLenum Access = 0; + GLenum Format = 0; BoundImageInfo() {}; - BoundImageInfo( Diligent::UniqueIdentifier _UniqueID, + BoundImageInfo( UniqueIdentifier _UniqueID, GLint _MipLevel, GLboolean _IsLayered, GLint _Layer, GLenum _Access, GLenum _Format) : - InterfaceID (_UniqueID ), - MipLevel (_MipLevel ), - IsLayered (_IsLayered), - Layer (_Layer ), - Access (_Access ), - Format (_Format ) + InterfaceID {_UniqueID }, + MipLevel {_MipLevel }, + IsLayered {_IsLayered}, + Layer {_Layer }, + Access {_Access }, + Format {_Format } {} bool operator==(const BoundImageInfo &rhs)const @@ -137,6 +146,29 @@ private: }; std::vector< BoundImageInfo > m_BoundImages; + struct BoundSSBOInfo + { + BoundSSBOInfo(){} + BoundSSBOInfo(UniqueIdentifier _BufferID, + GLintptr _Offset , + GLsizeiptr _Size) : + BufferID{_BufferID}, + Offset {_Offset }, + Size {_Size } + {} + UniqueIdentifier BufferID = -1; + GLintptr Offset = 0; + GLsizeiptr Size = 0; + + bool operator==(const BoundSSBOInfo &rhs)const + { + return BufferID == rhs.BufferID && + Offset == rhs.Offset && + Size == rhs.Size; + } + }; + std::vector< BoundSSBOInfo > m_BoundStorageBlocks; + Uint32 m_PendingMemoryBarriers = 0; class EnableStateHelper diff --git a/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h b/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h index f1a894f8..3b481aa1 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h @@ -32,7 +32,7 @@ template class GLObjWrapper { public: - GLObjWrapper(bool CreateObject, CreateReleaseHelperType CreateReleaseHelper = CreateReleaseHelperType()) : + explicit GLObjWrapper(bool CreateObject, CreateReleaseHelperType CreateReleaseHelper = CreateReleaseHelperType()) : m_uiHandle {0 }, m_CreateReleaseHelper{CreateReleaseHelper} { @@ -103,6 +103,11 @@ public: operator GLuint()const{return m_uiHandle;} + static GLObjWrapper Null() + { + return GLObjWrapper{false}; + } + private: GLuint m_uiHandle; CreateReleaseHelperType m_CreateReleaseHelper; diff --git a/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.h b/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.h index 7f3c7ba1..e3ba9ea5 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.h @@ -89,11 +89,16 @@ inline GLenum TypeToGLType(VALUE_TYPE Value) inline GLenum UsageToGLUsage(USAGE Usage) { // http://www.informit.com/articles/article.aspx?p=2033340&seqNum=2 + // https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glBufferData.xml switch(Usage) { + // STATIC: The data store contents will be modified once and used many times. + // STREAM: The data store contents will be modified once and used at MOST a few times. + // DYNAMIC: The data store contents will be modified repeatedly and used many times. + case USAGE_STATIC: return GL_STATIC_DRAW; - case USAGE_DEFAULT: return GL_DYNAMIC_DRAW; - case USAGE_DYNAMIC: return GL_STREAM_DRAW; + case USAGE_DEFAULT: return GL_STATIC_DRAW; + case USAGE_DYNAMIC: return GL_DYNAMIC_DRAW; case USAGE_STAGING: return GL_DYNAMIC_READ; default: UNEXPECTED( "Unknow usage" ); return 0; } diff --git a/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp index f0123b11..c2be0396 100644 --- a/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp @@ -70,7 +70,7 @@ static GLenum GetBufferBindTarget(const BufferDesc& Desc) BufferGLImpl::BufferGLImpl(IReferenceCounters* pRefCounters, FixedBlockMemoryAllocator& BuffViewObjMemAllocator, RenderDeviceGLImpl* pDeviceGL, - DeviceContextGLImpl* pCtxGL, + GLContextState& GLState, const BufferDesc& BuffDesc, const BufferData* pBuffData /*= nullptr*/, bool bIsDeviceInternal) : @@ -83,24 +83,19 @@ BufferGLImpl::BufferGLImpl(IReferenceCounters* pRefCounters, bIsDeviceInternal }, m_GlBuffer {true }, // Create buffer immediately - m_uiMapTarget {0 }, + m_BindTarget {GetBufferBindTarget(BuffDesc) }, m_GLUsageHint {UsageToGLUsage(BuffDesc.Usage) }, m_bUseMapWriteDiscardBugWA{GetUseMapWriteDiscardBugWA(pDeviceGL)} { if( BuffDesc.Usage == USAGE_STATIC && (pBuffData == nullptr || pBuffData->pData == nullptr) ) LOG_ERROR_AND_THROW("Static buffer must be initialized with data at creation time"); - auto Target = GetBufferBindTarget(BuffDesc); - - if (Target == GL_ARRAY_BUFFER || Target == GL_ELEMENT_ARRAY_BUFFER) - { - // We must unbind VAO because otherwise we will break the bindings - pCtxGL->ResetVAO(); - } - // TODO: find out if it affects performance if the buffer is originally bound to one target // and then bound to another (such as first to GL_ARRAY_BUFFER and then to GL_UNIFORM_BUFFER) - glBindBuffer(Target, m_GlBuffer); + + // We must unbind VAO because otherwise we will break the bindings + constexpr bool ResetVAO = true; + GLState.BindBuffer(m_BindTarget, m_GlBuffer, ResetVAO); VERIFY(pBuffData == nullptr || pBuffData->pData == nullptr || pBuffData->DataSize >= BuffDesc.uiSizeInBytes, "Data pointer is null or data size is not consistent with buffer size" ); GLsizeiptr DataSize = BuffDesc.uiSizeInBytes; const GLvoid *pData = nullptr; @@ -148,23 +143,22 @@ BufferGLImpl::BufferGLImpl(IReferenceCounters* pRefCounters, // All buffer bind targets (GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER etc.) relate to the same // kind of objects. As a result they are all equivalent from a transfer point of view. - glBufferData(Target, DataSize, pData, m_GLUsageHint); + glBufferData(m_BindTarget, DataSize, pData, m_GLUsageHint); CHECK_GL_ERROR_AND_THROW("glBufferData() failed"); - glBindBuffer(Target, 0); + GLState.BindBuffer(m_BindTarget, GLObjectWrappers::GLBufferObj::Null(), ResetVAO); } -static BufferDesc GetBufferDescFromGLHandle(DeviceContextGLImpl* pCtxGL, BufferDesc BuffDesc, GLuint BufferHandle) +static BufferDesc GetBufferDescFromGLHandle(GLContextState& GLState, BufferDesc BuffDesc, GLuint BufferHandle) { // NOTE: the operations in this function are merely for debug purposes. // If binding a buffer to a target does not work, these operations can be skipped GLenum BindTarget = GetBufferBindTarget(BuffDesc); - if (BindTarget == GL_ARRAY_BUFFER || BindTarget == GL_ELEMENT_ARRAY_BUFFER) - { - // We must unbind VAO because otherwise we will break the bindings - pCtxGL->ResetVAO(); - } + // We must unbind VAO because otherwise we will break the bindings + constexpr bool ResetVAO = true; + GLState.BindBuffer(BindTarget, GLObjectWrappers::GLBufferObj::Null(), ResetVAO); + // Note that any glBindBufferBase, glBindBufferRange etc. also bind the buffer to the generic buffer binding point. glBindBuffer(BindTarget, BufferHandle); CHECK_GL_ERROR("Failed to bind GL buffer to ", BindTarget, " target"); @@ -186,7 +180,7 @@ static BufferDesc GetBufferDescFromGLHandle(DeviceContextGLImpl* pCtxGL, BufferD BufferGLImpl::BufferGLImpl(IReferenceCounters* pRefCounters, FixedBlockMemoryAllocator& BuffViewObjMemAllocator, RenderDeviceGLImpl* pDeviceGL, - DeviceContextGLImpl* pCtxGL, + GLContextState& CtxState, const BufferDesc& BuffDesc, GLuint GLHandle, bool bIsDeviceInternal) : @@ -195,12 +189,12 @@ BufferGLImpl::BufferGLImpl(IReferenceCounters* pRefCounters, pRefCounters, BuffViewObjMemAllocator, pDeviceGL, - GetBufferDescFromGLHandle(pCtxGL, BuffDesc, GLHandle), + GetBufferDescFromGLHandle(CtxState, BuffDesc, GLHandle), bIsDeviceInternal }, // Attach to external buffer handle m_GlBuffer {true, GLObjectWrappers::GLBufferObjCreateReleaseHelper(GLHandle)}, - m_uiMapTarget {0 }, + m_BindTarget {GetBufferBindTarget(m_Desc) }, m_GLUsageHint {UsageToGLUsage(BuffDesc.Usage) }, m_bUseMapWriteDiscardBugWA{GetUseMapWriteDiscardBugWA(pDeviceGL)} { @@ -213,24 +207,23 @@ BufferGLImpl::~BufferGLImpl() IMPLEMENT_QUERY_INTERFACE(BufferGLImpl, IID_BufferGL, TBufferBase) -void BufferGLImpl :: UpdateData(DeviceContextGLImpl* pCtxGL, Uint32 Offset, Uint32 Size, const PVoid pData) +void BufferGLImpl :: UpdateData(GLContextState& CtxState, Uint32 Offset, Uint32 Size, const PVoid pData) { - // We must unbind VAO because otherwise we will break the bindings - pCtxGL->ResetVAO(); - BufferMemoryBarrier( GL_BUFFER_UPDATE_BARRIER_BIT,// Reads or writes to buffer objects via any OpenGL API functions that allow // modifying their contents will reflect data written by shaders prior to the barrier. // Additionally, writes via these commands issued after the barrier will wait on // the completion of any shader writes to the same memory initiated prior to the barrier. - pCtxGL->GetContextState()); + CtxState); - glBindBuffer(GL_ARRAY_BUFFER, m_GlBuffer); + // We must unbind VAO because otherwise we will break the bindings + constexpr bool ResetVAO = true; + CtxState.BindBuffer(GL_ARRAY_BUFFER, m_GlBuffer, ResetVAO); // All buffer bind targets (GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER etc.) relate to the same // kind of objects. As a result they are all equivalent from a transfer point of view. glBufferSubData(GL_ARRAY_BUFFER, Offset, Size, pData); CHECK_GL_ERROR("glBufferSubData() failed"); - glBindBuffer(GL_ARRAY_BUFFER, 0); + CtxState.BindBuffer(GL_ARRAY_BUFFER, GLObjectWrappers::GLBufferObj::Null(), ResetVAO); } @@ -251,26 +244,26 @@ void BufferGLImpl :: CopyData(GLContextState& CtxState, BufferGLImpl& SrcBufferG // Neither target is used for anything else by OpenGL, and so you can safely bind buffers to them for // the purposes of copying or staging data without disturbing OpenGL state or needing to keep track of // what was bound to the target before your copy. - glBindBuffer(GL_COPY_WRITE_BUFFER, m_GlBuffer); - glBindBuffer(GL_COPY_READ_BUFFER, SrcBufferGL.m_GlBuffer); + constexpr bool ResetVAO = false; // No need to reset VAO for READ/WRITE targets + CtxState.BindBuffer(GL_COPY_WRITE_BUFFER, m_GlBuffer, ResetVAO); + CtxState.BindBuffer(GL_COPY_READ_BUFFER, SrcBufferGL.m_GlBuffer, ResetVAO); glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, SrcOffset, DstOffset, Size); CHECK_GL_ERROR("glCopyBufferSubData() failed"); - glBindBuffer(GL_COPY_READ_BUFFER, 0); - glBindBuffer(GL_COPY_WRITE_BUFFER, 0); + CtxState.BindBuffer(GL_COPY_READ_BUFFER, GLObjectWrappers::GLBufferObj::Null(), ResetVAO); + CtxState.BindBuffer(GL_COPY_WRITE_BUFFER, GLObjectWrappers::GLBufferObj::Null(), ResetVAO); } void BufferGLImpl :: Map(GLContextState& CtxState, MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData) { - VERIFY( m_uiMapTarget == 0, "Buffer is already mapped"); - BufferMemoryBarrier( GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT,// Access by the client to persistent mapped regions of buffer // objects will reflect data written by shaders prior to the barrier. // Note that this may cause additional synchronization operations. CtxState); - m_uiMapTarget = ( MapType == MAP_READ ) ? GL_COPY_READ_BUFFER : GL_COPY_WRITE_BUFFER; - glBindBuffer(m_uiMapTarget, m_GlBuffer); + // We must unbind VAO because otherwise we will break the bindings + constexpr bool ResetVAO = true; + CtxState.BindBuffer(m_BindTarget, m_GlBuffer, ResetVAO); // !!!WARNING!!! GL_MAP_UNSYNCHRONIZED_BIT is not the same thing as MAP_FLAG_DO_NOT_WAIT. // If GL_MAP_UNSYNCHRONIZED_BIT flag is set, OpenGL will not attempt to synchronize operations @@ -299,7 +292,7 @@ void BufferGLImpl :: Map(GLContextState& CtxState, MAP_TYPE MapType, Uint32 MapF // implementation to simply reallocate storage for that buffer object under-the-hood. // Since NULL is passed, if there wasn't a need for synchronization to begin with, // this can be reduced to a no-op. - glBufferData(m_uiMapTarget, m_Desc.uiSizeInBytes, nullptr, m_GLUsageHint); + glBufferData(m_BindTarget, m_Desc.uiSizeInBytes, nullptr, m_GLUsageHint); CHECK_GL_ERROR("glBufferData() failed"); Access |= GL_MAP_WRITE_BIT; } @@ -334,16 +327,16 @@ void BufferGLImpl :: Map(GLContextState& CtxState, MAP_TYPE MapType, Uint32 MapF default: UNEXPECTED( "Unknown map type" ); } - pMappedData = glMapBufferRange(m_uiMapTarget, 0, m_Desc.uiSizeInBytes, Access); + pMappedData = glMapBufferRange(m_BindTarget, 0, m_Desc.uiSizeInBytes, Access); CHECK_GL_ERROR("glMapBufferRange() failed"); VERIFY( pMappedData, "Map failed" ); - glBindBuffer(m_uiMapTarget, 0); } -void BufferGLImpl::Unmap() +void BufferGLImpl::Unmap(GLContextState& CtxState) { - glBindBuffer(m_uiMapTarget, m_GlBuffer); - auto Result = glUnmapBuffer(m_uiMapTarget); + constexpr bool ResetVAO = true; + CtxState.BindBuffer(m_BindTarget, m_GlBuffer, ResetVAO); + auto Result = glUnmapBuffer(m_BindTarget); // glUnmapBuffer() returns TRUE unless data values in the buffer's data store have // become corrupted during the period that the buffer was mapped. Such corruption // can be the result of a screen resolution change or other window system - dependent @@ -353,8 +346,6 @@ void BufferGLImpl::Unmap() // has occurred, glUnmapBuffer() returns FALSE, and the contents of the buffer's // data store become undefined. VERIFY( Result != GL_FALSE, "Failed to unmap buffer. The data may have been corrupted" ); (void)Result; - glBindBuffer(m_uiMapTarget, 0); - m_uiMapTarget = 0; } void BufferGLImpl::BufferMemoryBarrier( Uint32 RequiredBarriers, GLContextState &GLContextState ) diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index 1d606ff7..aacf29cb 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -134,7 +134,7 @@ namespace Diligent m_ContextState.SetStencilOp( GL_BACK, BackFace.StencilFailOp, BackFace.StencilDepthFailOp, BackFace.StencilPassOp ); } } - m_bVAOIsUpToDate = false; + m_ContextState.InvalidateVAO(); } } @@ -182,7 +182,7 @@ namespace Diligent SET_VERTEX_BUFFERS_FLAGS Flags) { TDeviceContextBase::SetVertexBuffers(StartSlot, NumBuffersSet, ppBuffers, pOffsets, StateTransitionMode, Flags); - m_bVAOIsUpToDate = false; + m_ContextState.InvalidateVAO(); } void DeviceContextGLImpl::InvalidateState() @@ -192,13 +192,12 @@ namespace Diligent m_ContextState.Invalidate(); m_BoundWritableTextures.clear(); m_BoundWritableBuffers.clear(); - m_bVAOIsUpToDate = false; } void DeviceContextGLImpl::SetIndexBuffer(IBuffer* pIndexBuffer, Uint32 ByteOffset, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) { TDeviceContextBase::SetIndexBuffer(pIndexBuffer, ByteOffset, StateTransitionMode); - m_bVAOIsUpToDate = false; + m_ContextState.InvalidateVAO(); } void DeviceContextGLImpl::SetViewports(Uint32 NumViewports, const Viewport* pViewports, Uint32 RTWidth, Uint32 RTHeight) @@ -388,8 +387,7 @@ namespace Diligent // will reflect data written by shaders prior to the barrier m_ContextState); - glBindBufferBase(GL_UNIFORM_BUFFER, ub, pBufferGL->m_GlBuffer); - DEV_CHECK_GL_ERROR("Failed to bind uniform buffer to slot ", ub); + m_ContextState.BindUniformBuffer(ub, pBufferGL->m_GlBuffer); //glBindBufferRange(GL_UNIFORM_BUFFER, it->Index, pBufferGL->m_GlBuffer, 0, pBufferGL->GetDesc().uiSizeInBytes); } @@ -479,7 +477,7 @@ namespace Diligent glGetTexParameteriv( pTexViewGL->GetBindTarget(), GL_TEXTURE_IMMUTABLE_FORMAT, &IsImmutable ); CHECK_GL_ERROR( "glGetTexParameteriv() failed" ); VERIFY( IsImmutable, "Only immutable textures can be bound to pipeline using glBindImageTexture()" ); - m_ContextState.BindTexture( -1, pTexViewGL->GetBindTarget(), GLObjectWrappers::GLTextureObj(false) ); + m_ContextState.BindTexture( -1, pTexViewGL->GetBindTarget(), GLObjectWrappers::GLTextureObj::Null() ); } #endif auto GlTexFormat = TexFormatToGLInternalTexFormat( ViewDesc.Format ); @@ -541,11 +539,10 @@ namespace Diligent auto* pBufferGL = pBufferViewGL->GetBuffer(); pBufferGL->BufferMemoryBarrier( GL_SHADER_STORAGE_BARRIER_BIT,// Accesses to shader storage blocks after the barrier - // will reflect writes prior to the barrier + // will reflect writes prior to the barrier m_ContextState); - glBindBufferRange(GL_SHADER_STORAGE_BUFFER, ssbo, pBufferGL->m_GlBuffer, ViewDesc.ByteOffset, ViewDesc.ByteWidth); - DEV_CHECK_GL_ERROR("Failed to bind shader storage buffer"); + m_ContextState.BindStorageBlock(ssbo, pBufferGL->m_GlBuffer, ViewDesc.ByteOffset, ViewDesc.ByteWidth); if (ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS) m_BoundWritableBuffers.push_back(pBufferGL); @@ -621,7 +618,7 @@ namespace Diligent auto* pRenderDeviceGL = m_pDevice.RawPtr(); auto CurrNativeGLContext = pRenderDeviceGL->m_GLContext.GetCurrentNativeGLContext(); const auto& PipelineDesc = m_pPipelineState->GetDesc().GraphicsPipeline; - if (!m_bVAOIsUpToDate) + if (!m_ContextState.IsValidVAOBound()) { auto& VAOCache = pRenderDeviceGL->GetVAOCache(CurrNativeGLContext); IBuffer* pIndexBuffer = drawAttribs.IsIndexed ? m_pIndexBuffer.RawPtr() : nullptr; @@ -638,7 +635,6 @@ namespace Diligent const auto& VAO = VAOCache.GetEmptyVAO(); m_ContextState.BindVAO( VAO ); } - m_bVAOIsUpToDate = true; } GLenum GlTopology; @@ -688,8 +684,8 @@ namespace Diligent // objects affected by this bit are derived from the DRAW_INDIRECT_BUFFER // and DISPATCH_INDIRECT_BUFFER bindings. m_ContextState); - - glBindBuffer( GL_DRAW_INDIRECT_BUFFER, pIndirectDrawAttribsGL->m_GlBuffer ); + constexpr bool ResetVAO = false; // GL_DRAW_INDIRECT_BUFFER does not affect VAO + m_ContextState.BindBuffer( GL_DRAW_INDIRECT_BUFFER, pIndirectDrawAttribsGL->m_GlBuffer, ResetVAO); if (drawAttribs.IsIndexed) { @@ -717,7 +713,7 @@ namespace Diligent DEV_CHECK_GL_ERROR( "glDrawArraysIndirect() failed" ); } - glBindBuffer( GL_DRAW_INDIRECT_BUFFER, 0 ); + m_ContextState.BindBuffer( GL_DRAW_INDIRECT_BUFFER, GLObjectWrappers::GLBufferObj::Null(), ResetVAO ); #else LOG_ERROR_MESSAGE("Indirect rendering is not supported"); #endif @@ -796,13 +792,14 @@ namespace Diligent // and DISPATCH_INDIRECT_BUFFER bindings. m_ContextState); - glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, pBufferGL->m_GlBuffer); + constexpr bool ResetVAO = false; // GL_DISPATCH_INDIRECT_BUFFER does not affect VAO + m_ContextState.BindBuffer(GL_DISPATCH_INDIRECT_BUFFER, pBufferGL->m_GlBuffer, ResetVAO); CHECK_GL_ERROR( "Failed to bind a buffer for dispatch indirect command" ); glDispatchComputeIndirect(DispatchAttrs.DispatchArgsByteOffset); CHECK_GL_ERROR("glDispatchComputeIndirect() failed"); - glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0); + m_ContextState.BindBuffer(GL_DISPATCH_INDIRECT_BUFFER, GLObjectWrappers::GLBufferObj::Null(), ResetVAO); } else { @@ -994,7 +991,7 @@ namespace Diligent TDeviceContextBase::UpdateBuffer(pBuffer, Offset, Size, pData, StateTransitionMode); auto* pBufferGL = ValidatedCast(pBuffer); - pBufferGL->UpdateData(this, Offset, Size, pData); + pBufferGL->UpdateData(m_ContextState, Offset, Size, pData); } void DeviceContextGLImpl::CopyBuffer(IBuffer* pSrcBuffer, @@ -1023,7 +1020,7 @@ namespace Diligent { TDeviceContextBase::UnmapBuffer(pBuffer, MapType); auto* pBufferGL = ValidatedCast(pBuffer); - pBufferGL->Unmap(); + pBufferGL->Unmap(m_ContextState); } void DeviceContextGLImpl::UpdateTexture(ITexture* pTexture, @@ -1076,17 +1073,11 @@ namespace Diligent m_ContextState.BindTexture( -1, BindTarget, pTexViewGL->GetHandle() ); glGenerateMipmap( BindTarget ); CHECK_GL_ERROR( "Failed to generate mip maps" ); - m_ContextState.BindTexture( -1, BindTarget, GLObjectWrappers::GLTextureObj(false) ); + m_ContextState.BindTexture( -1, BindTarget, GLObjectWrappers::GLTextureObj::Null() ); } void DeviceContextGLImpl::TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers) { } - - void DeviceContextGLImpl::ResetVAO() - { - m_bVAOIsUpToDate = false; - m_ContextState.BindVAO(GLObjectWrappers::GLVertexArrayObj{false}); - } } diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp index d28175d6..ee125649 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp @@ -51,11 +51,17 @@ namespace Diligent glGetIntegerv( GL_MAX_DRAW_BUFFERS, &m_Caps.m_iMaxDrawBuffers ); CHECK_GL_ERROR( "Failed to get max draw buffers count" ); VERIFY_EXPR(m_Caps.m_iMaxDrawBuffers > 0); + + glGetIntegerv( GL_MAX_UNIFORM_BUFFER_BINDINGS, &m_Caps.m_iMaxUniformBufferBindings ); + CHECK_GL_ERROR( "Failed to get uniform buffers count" ); + VERIFY_EXPR(m_Caps.m_iMaxUniformBufferBindings > 0); } m_BoundTextures.reserve( m_Caps.m_iMaxCombinedTexUnits ); m_BoundSamplers.reserve( 32 ); m_BoundImages.reserve( 32 ); + m_BoundUniformBuffers.reserve( m_Caps.m_iMaxUniformBufferBindings ); + m_BoundStorageBlocks.reserve(16); Invalidate(); @@ -82,14 +88,16 @@ namespace Diligent glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 ); DEV_CHECK_GL_ERROR( "Failed to reset GL context state" ); - m_GLProgId = -1; + m_GLProgId = -1; m_GLPipelineId = -1; - m_VAOId = -1; - m_FBOId = -1; + m_VAOId = -1; + m_FBOId = -1; m_BoundTextures.clear(); m_BoundSamplers.clear(); m_BoundImages.clear(); + m_BoundUniformBuffers.clear(); + m_BoundStorageBlocks.clear(); m_DSState = DepthStencilGLState(); m_RSState = RasterizerGLState(); @@ -107,13 +115,9 @@ namespace Diligent bool UpdateBoundObject( UniqueIdentifier &CurrentObjectID, const ObjectType &NewObject, GLuint &NewGLHandle ) { NewGLHandle = static_cast(NewObject); - UniqueIdentifier NewObjectID = 0; - if( NewGLHandle != 0 ) - { - // Only ask for the ID if the object handle is non-zero - // to avoid ID generation for null objects - NewObjectID = NewObject.GetUniqueID(); - } + // Only ask for the ID if the object handle is non-zero + // to avoid ID generation for null objects + UniqueIdentifier NewObjectID = (NewGLHandle != 0) ? NewObject.GetUniqueID() : 0; // It is unsafe to use GL handle to keep track of bound textures // When a texture is released, GL is free to reuse its handle for @@ -285,6 +289,59 @@ namespace Diligent #endif } + void GLContextState::BindUniformBuffer( Int32 Index, const GLObjectWrappers::GLBufferObj &Buff) + { + VERIFY( 0 <= Index && Index < m_Caps.m_iMaxUniformBufferBindings, "Uniform buffer index is out of range" ); + + GLuint GLBufferHandle = Buff; + if( UpdateBoundObjectsArr( m_BoundUniformBuffers, Index, Buff, GLBufferHandle ) ) + { + // In addition to binding buffer to the indexed buffer binding target, glBindBufferBase also binds + // buffer to the generic buffer binding point specified by target. + glBindBufferBase(GL_UNIFORM_BUFFER, Index, GLBufferHandle); + DEV_CHECK_GL_ERROR("Failed to bind uniform buffer to slot ", Index); + } + } + + void GLContextState::BindStorageBlock( Int32 Index, const GLObjectWrappers::GLBufferObj& Buff, GLintptr Offset, GLsizeiptr Size) + { +#if GL_ARB_shader_storage_buffer_object + BoundSSBOInfo NewSSBOInfo {Buff.GetUniqueID(), Offset, Size}; + if (Index >= m_BoundStorageBlocks.size()) + m_BoundStorageBlocks.resize(Index + 1); + + if( !(m_BoundStorageBlocks[Index] == NewSSBOInfo) ) + { + m_BoundStorageBlocks[Index] = NewSSBOInfo; + GLuint GLBufferHandle = Buff; + // In addition to binding buffer to the indexed buffer binding target, glBindBufferRange also binds + // buffer to the generic buffer binding point specified by target. + glBindBufferRange(GL_SHADER_STORAGE_BUFFER, Index, GLBufferHandle, Offset, Size); + DEV_CHECK_GL_ERROR("Failed to bind shader storage block to slot ", Index); + } +#else + UNSUPPORTED("GL_ARB_shader_image_load_store is not supported"); +#endif + } + + void GLContextState::BindBuffer(GLenum BindTarget, const GLObjectWrappers::GLBufferObj& Buff, bool ResetVAO) + { + // Binding ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER affects currently bound VAO + if (ResetVAO && (BindTarget == GL_ARRAY_BUFFER || BindTarget == GL_ELEMENT_ARRAY_BUFFER)) + { + BindVAO(GLVertexArrayObj::Null()); + } + + // Note that glBindBufferBase, glBindBufferRange etc. also bind the + // buffer to the generic buffer binding point specified by target. + + // GL_UNIFORM_BUFFER, GL_ATOMIC_COUNTER_BUFFER and GL_SHADER_STORAGE_BUFFER buffer binding points do not directly affect + // uniform buffer, atomic counter buffer or shader storage buffer state, respectively. glBindBufferBase or glBindBufferRange + // must be used to bind a buffer to an indexed uniform buffer, atomic counter buffer or shader storage buffer binding point. + glBindBuffer(BindTarget, Buff); + DEV_CHECK_GL_ERROR("Failed to bind buffer ", static_cast(Buff), " to target ", BindTarget); + } + void GLContextState::EnsureMemoryBarrier( Uint32 RequiredBarriers, AsyncWritableResource *pRes/* = nullptr */ ) { #if GL_ARB_shader_image_load_store @@ -500,7 +557,7 @@ namespace Diligent } } - void GLContextState::SetFrontFace( Bool FrontCounterClockwise ) + void GLContextState::SetFrontFace( bool FrontCounterClockwise ) { if( m_RSState.FrontCounterClockwise != FrontCounterClockwise ) { @@ -535,7 +592,7 @@ namespace Diligent } } - void GLContextState::SetDepthClamp( Bool bEnableDepthClamp ) + void GLContextState::SetDepthClamp( bool bEnableDepthClamp ) { if( m_RSState.DepthClampEnable != bEnableDepthClamp ) { @@ -570,7 +627,7 @@ namespace Diligent } } - void GLContextState::EnableScissorTest( Bool bEnableScissorTest ) + void GLContextState::EnableScissorTest( bool bEnableScissorTest ) { if( m_RSState.ScissorTestEnable != bEnableScissorTest ) { diff --git a/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp b/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp index d885aa77..52862588 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp @@ -583,7 +583,7 @@ void GLProgramResources::LoadUniforms(SHADER_TYPE Shad } #endif - State.SetProgram(GLObjectWrappers::GLProgramObj{false}); + State.SetProgram(GLObjectWrappers::GLProgramObj::Null()); AllocateResources(UniformBlocks, Samplers, Images, StorageBlocks); } diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp index 83b199f4..07e46e76 100644 --- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp @@ -183,7 +183,7 @@ void PipelineStateGLImpl::CommitProgram(GLContextState& State) // WARNING: glUseProgram() overrides glBindProgramPipeline(). That is, if you have a program in use and // a program pipeline bound, all rendering will use the program that is in use, not the pipeline programs! // So make sure that glUseProgram(0) has been called if pipeline is in use - State.SetProgram(GLObjectWrappers::GLProgramObj{false}); + State.SetProgram(GLObjectWrappers::GLProgramObj::Null()); auto& Pipeline = GetGLProgramPipeline(State.GetCurrentGLContext()); VERIFY(Pipeline != 0, "Program pipeline must not be null"); State.SetPipeline( Pipeline ); diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp index 8ec263c2..b8b28665 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp @@ -124,7 +124,7 @@ void RenderDeviceGLImpl :: CreateBuffer(const BufferDesc& BuffDesc, const Buffer auto* pDeviceContextGL = spDeviceContext.RawPtr(); BufferGLImpl *pBufferOGL( NEW_RC_OBJ(m_BufObjAllocator, "BufferGLImpl instance", BufferGLImpl) - (m_BuffViewObjAllocator, this, pDeviceContextGL, BuffDesc, pBuffData, bIsDeviceInternal ) ); + (m_BuffViewObjAllocator, this, pDeviceContextGL->GetContextState(), BuffDesc, pBuffData, bIsDeviceInternal ) ); pBufferOGL->QueryInterface( IID_Buffer, reinterpret_cast(ppBuffer) ); pBufferOGL->CreateDefaultViews(); OnCreateDeviceObject( pBufferOGL ); @@ -148,7 +148,7 @@ void RenderDeviceGLImpl :: CreateBufferFromGLHandle(Uint32 GLHandle, const Buffe auto* pDeviceContextGL = spDeviceContext.RawPtr(); BufferGLImpl *pBufferOGL( NEW_RC_OBJ(m_BufObjAllocator, "BufferGLImpl instance", BufferGLImpl) - (m_BuffViewObjAllocator, this, pDeviceContextGL, BuffDesc, GLHandle, false ) ); + (m_BuffViewObjAllocator, this, pDeviceContextGL->GetContextState(), BuffDesc, GLHandle, false ) ); pBufferOGL->QueryInterface( IID_Buffer, reinterpret_cast(ppBuffer) ); pBufferOGL->CreateDefaultViews(); OnCreateDeviceObject( pBufferOGL ); diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp index a92f32a7..265e54a5 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp @@ -88,7 +88,7 @@ Texture1DArray_OGL::Texture1DArray_OGL(IReferenceCounters* pRefCounters, } } - GLState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj( false ) ); + GLState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); } Texture1DArray_OGL::Texture1DArray_OGL(IReferenceCounters* pRefCounters, @@ -152,7 +152,7 @@ void Texture1DArray_OGL::UpdateData( GLContextState& ContextState, if(UnpackBuffer != 0) glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); } void Texture1DArray_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp index 97d60345..b93a5dc0 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp @@ -85,7 +85,7 @@ Texture1D_OGL::Texture1D_OGL(IReferenceCounters* pRefCounters, } } - GLState.BindTexture(-1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); + GLState.BindTexture(-1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); } Texture1D_OGL::Texture1D_OGL( IReferenceCounters* pRefCounters, @@ -146,7 +146,7 @@ void Texture1D_OGL::UpdateData( GLContextState& ContextState, if(UnpackBuffer != 0) glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); } void Texture1D_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp index 7a5ce82e..17ba7fe0 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp @@ -109,7 +109,7 @@ Texture2DArray_OGL::Texture2DArray_OGL(IReferenceCounters* pRefCounters, } } - GLState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); + GLState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); } Texture2DArray_OGL::Texture2DArray_OGL( IReferenceCounters* pRefCounters, @@ -225,7 +225,7 @@ void Texture2DArray_OGL::UpdateData(GLContextState& ContextState, if(UnpackBuffer != 0) glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); } void Texture2DArray_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp index 5f9acdeb..ff8ff138 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp @@ -112,7 +112,7 @@ Texture2D_OGL::Texture2D_OGL( IReferenceCounters* pRefCounters, } } - GLState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); + GLState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); } Texture2D_OGL::Texture2D_OGL( IReferenceCounters* pRefCounters, @@ -225,7 +225,7 @@ void Texture2D_OGL::UpdateData( GLContextState& ContextState, if(UnpackBuffer != 0) glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); } void Texture2D_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp index 46b79d6f..1eb7deb0 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp @@ -89,7 +89,7 @@ Texture3D_OGL::Texture3D_OGL(IReferenceCounters* pRefCounters, } } - GLState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); + GLState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); } Texture3D_OGL::Texture3D_OGL( IReferenceCounters* pRefCounters, @@ -164,7 +164,7 @@ void Texture3D_OGL::UpdateData( GLContextState& ContextState, if(UnpackBuffer != 0) glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); } void Texture3D_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp index 6ca11e69..d7b0abe2 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp @@ -80,7 +80,7 @@ static GLenum GetTextureInternalFormat(GLContextState& GLState, GLenum BindTarge else UNSUPPORTED("Texture format cannot be queried and must be provided by the texture description"); #endif - GLState.BindTexture(-1, BindTarget, GLObjectWrappers::GLTextureObj(false) ); + GLState.BindTexture(-1, BindTarget, GLObjectWrappers::GLTextureObj::Null() ); return GlFormat; } @@ -166,7 +166,7 @@ static TextureDesc GetTextureDescFromGLHandle(GLContextState& GLState, TextureDe VERIFY(TexDesc.MipLevels != 0, "Unable to query the number of mip levels, so it must be specified by the texture description."); } - GLState.BindTexture(-1, BindTarget, GLObjectWrappers::GLTextureObj(false) ); + GLState.BindTexture(-1, BindTarget, GLObjectWrappers::GLTextureObj::Null() ); return TexDesc; } diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp index 0a16f4e6..db2b9bb1 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp @@ -97,7 +97,7 @@ TextureCubeArray_OGL::TextureCubeArray_OGL(IReferenceCounters* pRefCount } } - GLState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); + GLState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); } TextureCubeArray_OGL::TextureCubeArray_OGL( IReferenceCounters* pRefCounters, @@ -223,7 +223,7 @@ void TextureCubeArray_OGL::UpdateData( GLContextState& ContextState, if(UnpackBuffer != 0) glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); } void TextureCubeArray_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp index ec09b6bf..8223a91f 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp @@ -95,7 +95,7 @@ TextureCube_OGL::TextureCube_OGL(IReferenceCounters* pRefCounters, } } - GLState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); + GLState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); } TextureCube_OGL::TextureCube_OGL( IReferenceCounters* pRefCounters, @@ -228,7 +228,7 @@ void TextureCube_OGL::UpdateData( GLContextState& ContextState, if(UnpackBuffer != 0) glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj(false) ); + ContextState.BindTexture( -1, m_BindTarget, GLObjectWrappers::GLTextureObj::Null() ); } void TextureCube_OGL::AttachToFramebuffer( const TextureViewDesc& ViewDesc, GLenum AttachmentPoint ) diff --git a/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp b/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp index 1fa06748..3fce4c33 100644 --- a/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp @@ -75,7 +75,7 @@ const GLObjectWrappers::GLVertexArrayObj& VAOCache::GetVAO(IPipelineState* IBuffer* pIndexBuffer, VertexStreamInfo VertexStreams[], Uint32 NumVertexStreams, - GLContextState& GLContextState) + GLContextState& GLState) { // Lock the cache ThreadingTools::LockHelper CacheLock{m_CacheLockFlag}; @@ -127,7 +127,7 @@ const GLObjectWrappers::GLVertexArrayObj& VAOCache::GetVAO(IPipelineState* // will reflect data written by shaders prior to the barrier. // The set of buffer objects affected by this bit is derived // from the GL_VERTEX_ARRAY_BUFFER_BINDING bindings - GLContextState); + GLState); CurrStreamKey.BufferUId = pCurrBuf ? pCurrBuf->GetUniqueID() : 0; CurrStreamKey.Stride = Stride; @@ -149,7 +149,7 @@ const GLObjectWrappers::GLVertexArrayObj& VAOCache::GetVAO(IPipelineState* // will reflect data written by shaders prior to the barrier. // The buffer objects affected by this bit are derived from the // ELEMENT_ARRAY_BUFFER binding. - GLContextState); + GLState); } // Try to find VAO in the map @@ -164,7 +164,7 @@ const GLObjectWrappers::GLVertexArrayObj& VAOCache::GetVAO(IPipelineState* GLObjectWrappers::GLVertexArrayObj NewVAO(true); // Initialize VAO - GLContextState.BindVAO( NewVAO ); + GLState.BindVAO( NewVAO ); auto LayoutIt = LayoutElems; for( size_t Elem = 0; Elem < NumElems; ++Elem, ++LayoutIt ) { @@ -182,7 +182,8 @@ const GLObjectWrappers::GLVertexArrayObj& VAOCache::GetVAO(IPipelineState* VERIFY( pBuff != nullptr, "Vertex buffer is null" ); const BufferGLImpl *pBufferOGL = static_cast( pBuff ); - glBindBuffer(GL_ARRAY_BUFFER, pBufferOGL->m_GlBuffer); + constexpr bool ResetVAO = false; + GLState.BindBuffer(GL_ARRAY_BUFFER, pBufferOGL->m_GlBuffer, ResetVAO); GLvoid* DataStartOffset = reinterpret_cast( static_cast( CurrStream.Offset + LayoutIt->RelativeOffset ) ); auto GlType = TypeToGLType(LayoutIt->ValueType); if( !LayoutIt->IsNormalized && @@ -208,7 +209,8 @@ const GLObjectWrappers::GLVertexArrayObj& VAOCache::GetVAO(IPipelineState* if( pIndexBuffer ) { const BufferGLImpl *pIndBufferOGL = static_cast( pIndexBuffer ); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pIndBufferOGL->m_GlBuffer); + constexpr bool ResetVAO = false; + GLState.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, pIndBufferOGL->m_GlBuffer, ResetVAO); } auto NewElems = m_Cache.emplace( std::make_pair(Key, std::move(NewVAO)) ); -- cgit v1.2.3