From ccf3b17731fd1b098d90616fbb7d74cb64f8b58e Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 7 Jun 2017 23:04:15 +0100 Subject: [PATCH] Track buffer category in GL as the union of all bound states * This fixes a bug with replay proxies where looking at the last bound buffer type lead to buffers being created with insufficient flags on the local replay. * It will also handle the case where a buffer is used as e.g. both vertex and index and needs to have the flags for both specified. --- renderdoc/driver/gl/gl_common.cpp | 16 +++++++++++++ renderdoc/driver/gl/gl_common.h | 1 + renderdoc/driver/gl/gl_driver.h | 1 + renderdoc/driver/gl/gl_replay.cpp | 24 +------------------ .../driver/gl/wrappers/gl_buffer_funcs.cpp | 10 ++++++++ 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/renderdoc/driver/gl/gl_common.cpp b/renderdoc/driver/gl/gl_common.cpp index f17a3d249..439f19fcb 100644 --- a/renderdoc/driver/gl/gl_common.cpp +++ b/renderdoc/driver/gl/gl_common.cpp @@ -961,6 +961,22 @@ GLuint GetBoundVertexBuffer(const GLHookSet &gl, GLuint i) return buffer; } +BufferCategory MakeBufferCategory(GLenum bufferTarget) +{ + switch(bufferTarget) + { + case eGL_ARRAY_BUFFER: return BufferCategory::Vertex; break; + case eGL_ELEMENT_ARRAY_BUFFER: return BufferCategory::Index; break; + case eGL_UNIFORM_BUFFER: return BufferCategory::Constants; break; + case eGL_SHADER_STORAGE_BUFFER: return BufferCategory::ReadWrite; break; + case eGL_DRAW_INDIRECT_BUFFER: + case eGL_DISPATCH_INDIRECT_BUFFER: + case eGL_PARAMETER_BUFFER_ARB: return BufferCategory::Indirect; break; + default: break; + } + return BufferCategory::NoFlags; +} + AddressMode MakeAddressMode(GLenum addr) { switch(addr) diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index 8d4b7206c..bb54b4e89 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -269,6 +269,7 @@ ResourceFormat MakeResourceFormat(const GLHookSet &gl, GLenum target, GLenum fmt GLenum MakeGLFormat(WrappedOpenGL &gl, ResourceFormat fmt); Topology MakePrimitiveTopology(const GLHookSet &gl, GLenum Topo); GLenum MakeGLPrimitiveTopology(Topology Topo); +BufferCategory MakeBufferCategory(GLenum bufferTarget); AddressMode MakeAddressMode(GLenum addr); TextureFilter MakeFilter(GLenum minf, GLenum magf, bool shadowSampler, float maxAniso); CompareFunc MakeCompareFunc(GLenum func); diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 147d8496d..0dfdde833 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -242,6 +242,7 @@ private: { GLResource resource; GLenum curType; + BufferCategory creationFlags; uint64_t size; }; diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index a98be75cb..35c075035 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -774,29 +774,7 @@ BufferDescription GLReplay::GetBuffer(ResourceId id) gl.glBindBuffer(res.curType, res.resource.name); } - ret.creationFlags = BufferCategory::NoFlags; - switch(res.curType) - { - case eGL_ARRAY_BUFFER: ret.creationFlags = BufferCategory::Vertex; break; - case eGL_ELEMENT_ARRAY_BUFFER: ret.creationFlags = BufferCategory::Index; break; - case eGL_UNIFORM_BUFFER: ret.creationFlags = BufferCategory::Constants; break; - case eGL_SHADER_STORAGE_BUFFER: ret.creationFlags = BufferCategory::ReadWrite; break; - case eGL_DRAW_INDIRECT_BUFFER: - case eGL_DISPATCH_INDIRECT_BUFFER: - case eGL_PARAMETER_BUFFER_ARB: ret.creationFlags = BufferCategory::Indirect; break; - case eGL_PIXEL_PACK_BUFFER: - case eGL_PIXEL_UNPACK_BUFFER: - case eGL_COPY_WRITE_BUFFER: - case eGL_COPY_READ_BUFFER: - case eGL_QUERY_BUFFER: - case eGL_TEXTURE_BUFFER: - case eGL_TRANSFORM_FEEDBACK_BUFFER: - case eGL_ATOMIC_COUNTER_BUFFER: break; - case eGL_NONE: - break; // could be from a 'create' DSA call which didn't ever bind the buffer to an - // explicit type - default: RDCERR("Unexpected buffer type %s", ToStr::Get(res.curType).c_str()); break; - } + ret.creationFlags = res.creationFlags; GLint size = 0; // if the type is NONE it's probably a DSA created buffer diff --git a/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp index 99ad38455..3d26fd3e0 100644 --- a/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp @@ -46,6 +46,7 @@ bool WrappedOpenGL::Serialise_glGenBuffers(GLsizei n, GLuint *buffers) m_Buffers[live].resource = res; m_Buffers[live].curType = eGL_NONE; + m_Buffers[live].creationFlags = BufferCategory::NoFlags; } return true; @@ -81,6 +82,7 @@ void WrappedOpenGL::glGenBuffers(GLsizei n, GLuint *buffers) GetResourceManager()->AddLiveResource(id, res); m_Buffers[id].resource = res; m_Buffers[id].curType = eGL_NONE; + m_Buffers[id].creationFlags = BufferCategory::NoFlags; } } } @@ -101,6 +103,7 @@ bool WrappedOpenGL::Serialise_glCreateBuffers(GLsizei n, GLuint *buffers) m_Buffers[live].resource = res; m_Buffers[live].curType = eGL_NONE; + m_Buffers[live].creationFlags = BufferCategory::NoFlags; } return true; @@ -136,6 +139,7 @@ void WrappedOpenGL::glCreateBuffers(GLsizei n, GLuint *buffers) GetResourceManager()->AddLiveResource(id, res); m_Buffers[id].resource = res; m_Buffers[id].curType = eGL_NONE; + m_Buffers[id].creationFlags = BufferCategory::NoFlags; } } } @@ -173,6 +177,7 @@ bool WrappedOpenGL::Serialise_glBindBuffer(GLenum target, GLuint buffer) m_Real.glBindBuffer(Target, res.name); m_Buffers[GetResourceManager()->GetLiveID(Id)].curType = Target; + m_Buffers[GetResourceManager()->GetLiveID(Id)].creationFlags |= MakeBufferCategory(Target); if(m_State == READING && m_CurEventID == 0 && Target != eGL_NONE) m_Real.glBindBuffer(Target, prevbuf); @@ -316,6 +321,8 @@ void WrappedOpenGL::glBindBuffer(GLenum target, GLuint buffer) else { m_Buffers[GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))].curType = target; + m_Buffers[GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))].creationFlags |= + MakeBufferCategory(target); } } @@ -4002,6 +4009,7 @@ bool WrappedOpenGL::Serialise_glVertexArrayElementBuffer(GLuint vaobj, GLuint bu buffer = GetResourceManager()->GetLiveResource(bid).name; m_Buffers[GetResourceManager()->GetLiveID(bid)].curType = eGL_ELEMENT_ARRAY_BUFFER; + m_Buffers[GetResourceManager()->GetLiveID(bid)].creationFlags |= BufferCategory::Index; } // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If @@ -4070,6 +4078,7 @@ bool WrappedOpenGL::Serialise_glVertexArrayBindVertexBufferEXT(GLuint vaobj, GLu { live = GetResourceManager()->GetLiveResource(id).name; m_Buffers[GetResourceManager()->GetLiveID(id)].curType = eGL_ARRAY_BUFFER; + m_Buffers[GetResourceManager()->GetLiveID(id)].creationFlags |= BufferCategory::Vertex; } m_Real.glVertexArrayBindVertexBufferEXT(vaobj, idx, live, (GLintptr)offs, (GLsizei)str); @@ -4181,6 +4190,7 @@ bool WrappedOpenGL::Serialise_glVertexArrayVertexBuffers(GLuint vaobj, GLuint fi { bufs[i] = GetResourceManager()->GetLiveResource(id).name; m_Buffers[GetResourceManager()->GetLiveID(id)].curType = eGL_ARRAY_BUFFER; + m_Buffers[GetResourceManager()->GetLiveID(id)].creationFlags |= BufferCategory::Vertex; } else {