diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index 83b887008..88e52010d 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -173,6 +173,8 @@ enum GLChunkType SCISSOR, SCISSOR_ARRAY, BINDVERTEXARRAY, + BINDVERTEXBUFFER, + VERTEXDIVISOR, UNIFORM_MATRIX, UNIFORM_VECTOR, DRAWARRAYS, diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 1cc313c6b..c6da2a1d6 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -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; diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 33302dc81..b98c4efdb 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -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)); diff --git a/renderdoc/driver/gl/gl_hookset.h b/renderdoc/driver/gl/gl_hookset.h index 66eaacee9..e7ed2b605 100644 --- a/renderdoc/driver/gl/gl_hookset.h +++ b/renderdoc/driver/gl/gl_hookset.h @@ -212,6 +212,8 @@ struct GLHookSet PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; PFNGLGETVERTEXATTRIBIVPROC glGetVertexAttribiv; PFNGLGETVERTEXATTRIBPOINTERVPROC glGetVertexAttribPointerv; + PFNGLBINDVERTEXBUFFERPROC glBindVertexBuffer; + PFNGLVERTEXBINDINGDIVISORPROC glVertexBindingDivisor; PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage; PFNGLGENSAMPLERSPROC glGenSamplers; PFNGLBINDSAMPLERPROC glBindSampler; diff --git a/renderdoc/driver/gl/gl_hookset_defs.h b/renderdoc/driver/gl/gl_hookset_defs.h index 36d2963d8..66e83e33e 100644 --- a/renderdoc/driver/gl/gl_hookset_defs.h +++ b/renderdoc/driver/gl/gl_hookset_defs.h @@ -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); \ diff --git a/renderdoc/driver/gl/gl_renderstate.cpp b/renderdoc/driver/gl/gl_renderstate.cpp index 938f94226..3fd752252 100644 --- a/renderdoc/driver/gl/gl_renderstate.cpp +++ b/renderdoc/driver/gl/gl_renderstate.cpp @@ -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(); diff --git a/renderdoc/driver/gl/gl_renderstate.h b/renderdoc/driver/gl/gl_renderstate.h index 5b7263544..07e8f5d90 100644 --- a/renderdoc/driver/gl/gl_renderstate.h +++ b/renderdoc/driver/gl/gl_renderstate.h @@ -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 diff --git a/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp index d5458e331..af2d1b5ba 100644 --- a/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp @@ -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);