Hook Vertex Buffer binding functions and save as initial state

* Vertex attrib state is a property of the VAO so should be saved as
  initial resource contents.
This commit is contained in:
baldurk
2014-08-15 14:26:13 +01:00
parent 437cc374c2
commit 56430387db
8 changed files with 121 additions and 2 deletions
+2
View File
@@ -173,6 +173,8 @@ enum GLChunkType
SCISSOR,
SCISSOR_ARRAY,
BINDVERTEXARRAY,
BINDVERTEXBUFFER,
VERTEXDIVISOR,
UNIFORM_MATRIX,
UNIFORM_VECTOR,
DRAWARRAYS,
+8
View File
@@ -130,6 +130,8 @@ const char *GLChunkNames[] =
"glScissor",
"glScissorArrayv",
"glBindVertexArray",
"glBindVertexBuffer",
"glVertexBindingDivisor",
"glUniformMatrix*",
"glUniformVector*",
"glDrawArrays",
@@ -1196,6 +1198,12 @@ void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context)
case BINDVERTEXARRAY:
Serialise_glBindVertexArray(0);
break;
case BINDVERTEXBUFFER:
Serialise_glBindVertexBuffer(0, 0, 0, 0);
break;
case VERTEXDIVISOR:
Serialise_glVertexBindingDivisor(0, 0);
break;
case UNIFORM_MATRIX:
Serialise_glUniformMatrix(0, 0, 0, NULL, UNIFORM_UNKNOWN);
break;
+2
View File
@@ -490,6 +490,8 @@ class WrappedOpenGL
IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexAttribPointerv(GLuint index, GLenum pname, void **pointer));
IMPLEMENT_FUNCTION_SERIALISED(void, glGenVertexArrays(GLsizei n, GLuint *arrays));
IMPLEMENT_FUNCTION_SERIALISED(void, glBindVertexArray(GLuint array));
IMPLEMENT_FUNCTION_SERIALISED(void, glBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride));
IMPLEMENT_FUNCTION_SERIALISED(void, glVertexBindingDivisor(GLuint bindingindex, GLuint divisor));
IMPLEMENT_FUNCTION_SERIALISED(GLint, glGetUniformLocation(GLuint program, const GLchar *name));
IMPLEMENT_FUNCTION_SERIALISED(void, glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices));
IMPLEMENT_FUNCTION_SERIALISED(GLuint, glGetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName));
+2
View File
@@ -212,6 +212,8 @@ struct GLHookSet
PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
PFNGLGETVERTEXATTRIBIVPROC glGetVertexAttribiv;
PFNGLGETVERTEXATTRIBPOINTERVPROC glGetVertexAttribPointerv;
PFNGLBINDVERTEXBUFFERPROC glBindVertexBuffer;
PFNGLVERTEXBINDINGDIVISORPROC glVertexBindingDivisor;
PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
PFNGLGENSAMPLERSPROC glGenSamplers;
PFNGLBINDSAMPLERPROC glBindSampler;
+4
View File
@@ -226,6 +226,8 @@
HookExtension(PFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray); \
HookExtension(PFNGLGETVERTEXATTRIBIVPROC, glGetVertexAttribiv); \
HookExtension(PFNGLGETVERTEXATTRIBPOINTERVPROC, glGetVertexAttribPointerv); \
HookExtension(PFNGLBINDVERTEXBUFFERPROC, glBindVertexBuffer); \
HookExtension(PFNGLVERTEXBINDINGDIVISORPROC, glVertexBindingDivisor); \
HookExtension(PFNGLGETCOMPRESSEDTEXIMAGEPROC, glGetCompressedTexImage); \
HookExtension(PFNGLGENSAMPLERSPROC, glGenSamplers); \
HookExtension(PFNGLBINDSAMPLERPROC, glBindSampler); \
@@ -570,6 +572,8 @@
HookWrapper1(void, glDisableVertexAttribArray, GLuint, index); \
HookWrapper3(void, glGetVertexAttribiv, GLuint, index, GLenum, pname, GLint *, params); \
HookWrapper3(void, glGetVertexAttribPointerv, GLuint, index, GLenum, pname, void **, pointer); \
HookWrapper4(void, glBindVertexBuffer, GLuint, bindingindex, GLuint, buffer, GLintptr, offset, GLsizei, stride); \
HookWrapper2(void, glVertexBindingDivisor, GLuint, bindingindex, GLuint, divisor); \
HookWrapper3(void, glGetCompressedTexImage, GLenum, target, GLint, level, void *, img); \
HookWrapper2(void, glGenSamplers, GLsizei, count, GLuint *, samplers); \
HookWrapper2(void, glBindSampler, GLuint, unit, GLuint, sampler); \
+38 -1
View File
@@ -90,6 +90,16 @@ void GLRenderState::FetchState()
m_Real->glActiveTexture(ActiveTexture);
m_Real->glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&VAO);
for(GLuint i=0; i < (GLuint)ARRAY_COUNT(VertexBuffers); i++)
{
m_Real->glGetIntegeri_v(eGL_VERTEX_BINDING_BUFFER, i, (GLint *)&VertexBuffers[i].Buffer);
m_Real->glGetIntegeri_v(eGL_VERTEX_BINDING_STRIDE, i, (GLint *)&VertexBuffers[i].Stride);
m_Real->glGetIntegeri_v(eGL_VERTEX_BINDING_OFFSET, i, (GLint *)&VertexBuffers[i].Offset);
m_Real->glGetIntegeri_v(eGL_VERTEX_BINDING_DIVISOR, i, (GLint *)&VertexBuffers[i].Divisor);
}
m_Real->glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint *)&Program);
m_Real->glGetIntegerv(eGL_PROGRAM_PIPELINE_BINDING, (GLint *)&Pipeline);
@@ -254,7 +264,7 @@ void GLRenderState::ApplyState()
if(Enabled[i]) m_Real->glEnable(pnames[i]); else m_Real->glDisable(pnames[i]);
}
for(size_t i=0; i < ARRAY_COUNT(Tex2D); i++)
for(GLuint i=0; i < (GLuint)ARRAY_COUNT(Tex2D); i++)
{
m_Real->glActiveTexture(GLenum(eGL_TEXTURE0 + i));
m_Real->glBindTexture(eGL_TEXTURE_2D, Tex2D[i]);
@@ -263,6 +273,13 @@ void GLRenderState::ApplyState()
m_Real->glActiveTexture(ActiveTexture);
m_Real->glBindVertexArray(VAO);
for(GLuint i=0; i < (GLuint)ARRAY_COUNT(VertexBuffers); i++)
{
m_Real->glBindVertexBuffer(i, VertexBuffers[i].Buffer, (GLintptr)VertexBuffers[i].Offset, (GLsizei)VertexBuffers[i].Stride);
m_Real->glVertexBindingDivisor(i, VertexBuffers[i].Divisor);
}
m_Real->glUseProgram(Program);
m_Real->glBindProgramPipeline(Pipeline);
@@ -397,6 +414,9 @@ void GLRenderState::Clear()
RDCEraseEl(Tex2D);
RDCEraseEl(Samplers);
RDCEraseEl(ActiveTexture);
RDCEraseEl(VAO);
RDCEraseEl(VertexBuffers);
RDCEraseEl(Program);
RDCEraseEl(Pipeline);
@@ -459,6 +479,23 @@ void GLRenderState::Serialise(LogState state, void *ctx, GLResourceManager *rm)
m_pSerialiser->Serialise("GL_ACTIVE_TEXTURE", ActiveTexture);
{
ResourceId ID = ResourceId();
if(state >= WRITING) ID = rm->GetID(VertexArrayRes(ctx, VAO));
m_pSerialiser->Serialise("GL_VERTEX_ARRAY_BINDING", ID);
if(state < WRITING && ID != ResourceId()) VAO = rm->GetLiveResource(ID).name;
}
for(size_t i=0; i < ARRAY_COUNT(VertexBuffers); i++)
{
ResourceId ID = ResourceId();
if(state >= WRITING) ID = rm->GetID(BufferRes(ctx, VertexBuffers[i].Buffer));
m_pSerialiser->Serialise("GL_VERTEX_BINDING_BUFFER", ID);
m_pSerialiser->Serialise("GL_VERTEX_BINDING_DIVISOR", VertexBuffers[i].Divisor);
m_pSerialiser->Serialise("GL_VERTEX_BINDING_OFFSET", VertexBuffers[i].Offset);
m_pSerialiser->Serialise("GL_VERTEX_BINDING_STRIDE", VertexBuffers[i].Stride);
if(state < WRITING && ID != ResourceId()) VertexBuffers[i].Buffer = rm->GetLiveResource(ID).name;
}
for(size_t i=0; i < ARRAY_COUNT(BufferBindings); i++)
{
ResourceId ID = ResourceId();
+9 -1
View File
@@ -96,6 +96,15 @@ struct GLRenderState
eBufIdx_Query,
eBufIdx_Texture,
};
struct VertexBuffer
{
GLuint Buffer;
uint64_t Stride;
uint64_t Offset;
uint32_t Divisor;
} VertexBuffers[16];
GLuint VAO;
uint32_t BufferBindings[10];
struct IdxRangeBuffer
@@ -128,7 +137,6 @@ struct GLRenderState
GLenum DrawBuffers[8];
// TODO:
// Vertex Attribs/Buffers/Pointers etc
// Image state (GL_IMAGE_BINDING_NAME)
// multisampling
// provoking vertex
@@ -1376,6 +1376,62 @@ void WrappedOpenGL::glBindVertexArray(GLuint array)
}
}
bool WrappedOpenGL::Serialise_glBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride)
{
SERIALISE_ELEMENT(uint32_t, idx, bindingindex);
SERIALISE_ELEMENT(ResourceId, id, (buffer ? GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)) : ResourceId()));
SERIALISE_ELEMENT(uint64_t, offs, offset);
SERIALISE_ELEMENT(uint64_t, str, stride);
if(m_State <= EXECUTING)
{
GLuint live = 0;
if(id != ResourceId())
live = GetResourceManager()->GetLiveResource(id).name;
m_Real.glBindVertexBuffer(idx, live, (GLintptr)offs, (GLsizei)str);
}
return true;
}
void WrappedOpenGL::glBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride)
{
m_Real.glBindVertexBuffer(bindingindex, buffer, offset, stride);
if(m_State == WRITING_CAPFRAME)
{
SCOPED_SERIALISE_CONTEXT(BINDVERTEXBUFFER);
Serialise_glBindVertexBuffer(bindingindex, buffer, offset, stride);
m_ContextRecord->AddChunk(scope.Get());
}
}
bool WrappedOpenGL::Serialise_glVertexBindingDivisor(GLuint bindingindex, GLuint divisor)
{
SERIALISE_ELEMENT(uint32_t, idx, bindingindex);
SERIALISE_ELEMENT(uint32_t, d, divisor);
if(m_State <= EXECUTING)
m_Real.glVertexBindingDivisor(idx, d);
return true;
}
void WrappedOpenGL::glVertexBindingDivisor(GLuint bindingindex, GLuint divisor)
{
m_Real.glVertexBindingDivisor(bindingindex, divisor);
if(m_State == WRITING_CAPFRAME)
{
SCOPED_SERIALISE_CONTEXT(VERTEXDIVISOR);
Serialise_glVertexBindingDivisor(bindingindex, divisor);
m_ContextRecord->AddChunk(scope.Get());
}
}
void WrappedOpenGL::glDeleteBuffers(GLsizei n, const GLuint *buffers)
{
m_Real.glDeleteBuffers(n, buffers);