summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineOpenGL
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2019-10-13 00:13:38 +0000
committerEgor Yusov <egor.yusov@gmail.com>2019-10-13 00:13:38 +0000
commit785a72c96e86244a978838b979bee8fa7525903f (patch)
tree2b873deb8c2c7dda6604775b69351e993143143c /Graphics/GraphicsEngineOpenGL
parentUpdated 3rd party submodules (diff)
downloadDiligentCore-785a72c96e86244a978838b979bee8fa7525903f.tar.gz
DiligentCore-785a72c96e86244a978838b979bee8fa7525903f.zip
OpenGL backend: improved buffer binding
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/BufferGLImpl.h10
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h3
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/GLContextState.h136
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/GLObjectWrapper.h7
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/GLTypeConversions.h9
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp81
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp43
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp83
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp2
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp2
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp4
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/Texture1DArray_OGL.cpp4
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/Texture1D_OGL.cpp4
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/Texture2DArray_OGL.cpp4
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp4
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/Texture3D_OGL.cpp4
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp4
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/TextureCubeArray_OGL.cpp4
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/TextureCube_OGL.cpp4
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/VAOCache.cpp14
20 files changed, 253 insertions, 173 deletions
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<class TextureBaseGL*> m_BoundWritableTextures;
std::vector<class BufferGLImpl*> 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 CreateReleaseHelperType>
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<BufferGLImpl>();
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<RenderDeviceGLImpl>();
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<BufferGLImpl>(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<BufferGLImpl>(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<GLuint>(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<GLint>(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<DeviceContextGLImpl>();
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<IObject**>(ppBuffer) );
pBufferOGL->CreateDefaultViews();
OnCreateDeviceObject( pBufferOGL );
@@ -148,7 +148,7 @@ void RenderDeviceGLImpl :: CreateBufferFromGLHandle(Uint32 GLHandle, const Buffe
auto* pDeviceContextGL = spDeviceContext.RawPtr<DeviceContextGLImpl>();
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<IObject**>(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<BufferGLImpl> 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<const BufferGLImpl*>( 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<GLvoid*>( static_cast<size_t>( 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<const BufferGLImpl*>( 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)) );