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.
This commit is contained in:
baldurk
2017-06-07 23:04:15 +01:00
parent 4c64a3e42d
commit ccf3b17731
5 changed files with 29 additions and 23 deletions
+16
View File
@@ -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)
+1
View File
@@ -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);
+1
View File
@@ -242,6 +242,7 @@ private:
{
GLResource resource;
GLenum curType;
BufferCategory creationFlags;
uint64_t size;
};
+1 -23
View File
@@ -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
@@ -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
{