From cbc4c4cc435969a58db491da465a4e759c6e3b83 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 25 Nov 2014 21:43:42 +0000 Subject: [PATCH] Implement missing glMultiDraw functions --- renderdoc/driver/gl/gl_common.h | 3 + renderdoc/driver/gl/gl_driver.cpp | 12 ++ renderdoc/driver/gl/gl_driver.h | 3 + renderdoc/driver/gl/gl_hookset.h | 3 + renderdoc/driver/gl/gl_hookset_defs.h | 6 + .../driver/gl/wrappers/gl_draw_funcs.cpp | 201 ++++++++++++++++++ 6 files changed, 228 insertions(+) diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index fc75f8ae4..17929e51c 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -254,6 +254,9 @@ enum GLChunkType DRAWELEMENTS_INSTANCEDBASEVERTEXBASEINSTANCE, MULTI_DRAWARRAYS, MULTI_DRAWELEMENTS, + MULTI_DRAWELEMENTSBASEVERTEX, + MULTI_DRAWARRAYS_INDIRECT, + MULTI_DRAWELEMENTS_INDIRECT, GEN_FRAMEBUFFERS, FRAMEBUFFER_TEX, diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index d936ab36b..f07694b85 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -199,6 +199,9 @@ const char *GLChunkNames[] = "glDrawElementsInstancedBaseVertexBaseInstance", "glMultiDrawArrays", "glMultiDrawElements", + "glMultiDrawElementsBaseVertex", + "glMultiDrawArraysIndirect", + "glMultiDrawElementsIndirect", "glGenFramebuffers", "glFramebufferTexture", @@ -2026,6 +2029,15 @@ void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context) case MULTI_DRAWELEMENTS: Serialise_glMultiDrawElements(eGL_NONE, NULL, eGL_NONE, NULL, 0); break; + case MULTI_DRAWELEMENTSBASEVERTEX: + Serialise_glMultiDrawElementsBaseVertex(eGL_NONE, NULL, eGL_NONE, NULL, 0, NULL); + break; + case MULTI_DRAWARRAYS_INDIRECT: + Serialise_glMultiDrawArraysIndirect(eGL_NONE, NULL, 0, 0); + break; + case MULTI_DRAWELEMENTS_INDIRECT: + Serialise_glMultiDrawElementsIndirect(eGL_NONE, eGL_NONE, NULL, 0, 0); + break; case GEN_FRAMEBUFFERS: Serialise_glGenFramebuffers(0, NULL); diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index b29b98f5d..f7fa95f30 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -981,6 +981,9 @@ class WrappedOpenGL IMPLEMENT_FUNCTION_SERIALISED(void, glDrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance)); IMPLEMENT_FUNCTION_SERIALISED(void, glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount)); IMPLEMENT_FUNCTION_SERIALISED(void, glMultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount)); + IMPLEMENT_FUNCTION_SERIALISED(void, glMultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex)); + IMPLEMENT_FUNCTION_SERIALISED(void, glMultiDrawArraysIndirect(GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride)); + IMPLEMENT_FUNCTION_SERIALISED(void, glMultiDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride)); IMPLEMENT_FUNCTION_SERIALISED(void, glDrawArraysIndirect(GLenum mode, const void *indirect)); IMPLEMENT_FUNCTION_SERIALISED(void, glDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect)); IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteBuffers(GLsizei n, const GLuint *buffers)); diff --git a/renderdoc/driver/gl/gl_hookset.h b/renderdoc/driver/gl/gl_hookset.h index 17177c04e..dd0793b49 100644 --- a/renderdoc/driver/gl/gl_hookset.h +++ b/renderdoc/driver/gl/gl_hookset.h @@ -587,6 +587,9 @@ struct GLHookSet PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glDrawElementsInstancedBaseVertexBaseInstance; PFNGLMULTIDRAWARRAYSPROC glMultiDrawArrays; PFNGLMULTIDRAWELEMENTSPROC glMultiDrawElements; + PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glMultiDrawElementsBaseVertex; + PFNGLMULTIDRAWARRAYSINDIRECTPROC glMultiDrawArraysIndirect; + PFNGLMULTIDRAWELEMENTSINDIRECTPROC glMultiDrawElementsIndirect; PFNGLDRAWARRAYSINDIRECTPROC glDrawArraysIndirect; PFNGLDRAWELEMENTSINDIRECTPROC glDrawElementsIndirect; PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; diff --git a/renderdoc/driver/gl/gl_hookset_defs.h b/renderdoc/driver/gl/gl_hookset_defs.h index 43bd1abe8..45e30eb0d 100644 --- a/renderdoc/driver/gl/gl_hookset_defs.h +++ b/renderdoc/driver/gl/gl_hookset_defs.h @@ -619,6 +619,9 @@ HookExtension(PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC, glDrawElementsInstancedBaseVertexBaseInstance); \ HookExtension(PFNGLMULTIDRAWARRAYSPROC, glMultiDrawArrays); \ HookExtension(PFNGLMULTIDRAWELEMENTSPROC, glMultiDrawElements); \ + HookExtension(PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC, glMultiDrawElementsBaseVertex); \ + HookExtension(PFNGLMULTIDRAWARRAYSINDIRECTPROC, glMultiDrawArraysIndirect); \ + HookExtension(PFNGLMULTIDRAWELEMENTSINDIRECTPROC, glMultiDrawElementsIndirect); \ HookExtension(PFNGLDRAWARRAYSINDIRECTPROC, glDrawArraysIndirect); \ HookExtension(PFNGLDRAWELEMENTSINDIRECTPROC, glDrawElementsIndirect); \ HookExtension(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer); \ @@ -1294,6 +1297,9 @@ HookWrapper7(void, glDrawElementsInstancedBaseVertexBaseInstance, GLenum, mode, GLsizei, count, GLenum, type, const void *, indices, GLsizei, instancecount, GLint, basevertex, GLuint, baseinstance); \ HookWrapper4(void, glMultiDrawArrays, GLenum, mode, const GLint *, first, const GLsizei *, count, GLsizei, drawcount); \ HookWrapper5(void, glMultiDrawElements, GLenum, mode, const GLsizei *, count, GLenum, type, const void *const*, indices, GLsizei, drawcount); \ + HookWrapper6(void, glMultiDrawElementsBaseVertex, GLenum, mode, const GLsizei *, count, GLenum, type, const void *const*, indices, GLsizei, drawcount, const GLint *, basevertex); \ + HookWrapper4(void, glMultiDrawArraysIndirect, GLenum, mode, const void *, indirect, GLsizei, drawcount, GLsizei, stride); \ + HookWrapper5(void, glMultiDrawElementsIndirect, GLenum, mode, GLenum, type, const void *, indirect, GLsizei, drawcount, GLsizei, stride); \ HookWrapper2(void, glDrawArraysIndirect, GLenum, mode, const void *, indirect); \ HookWrapper3(void, glDrawElementsIndirect, GLenum, mode, GLenum, type, const void *, indirect); \ HookWrapper10(void, glBlitFramebuffer, GLint, srcX0, GLint, srcY0, GLint, srcX1, GLint, srcY1, GLint, dstX0, GLint, dstY0, GLint, dstX1, GLint, dstY1, GLbitfield, mask, GLenum, filter); \ diff --git a/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp index 6d5592c31..7bad96b95 100644 --- a/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp @@ -1133,6 +1133,207 @@ void WrappedOpenGL::glMultiDrawElements(GLenum mode, const GLsizei *count, GLenu } } +bool WrappedOpenGL::Serialise_glMultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex) +{ + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint32_t, Count, drawcount); + + SERIALISE_ELEMENT_ARR(int32_t, countArray, count, Count); + SERIALISE_ELEMENT_ARR(int32_t, baseArray, basevertex, Count); + + void **idxOffsArray = new void*[Count]; + size_t len = Count; + + // serialise pointer array as uint64s + if(m_State >= WRITING) + { + for(uint32_t i=0; i < Count; i++) + { + uint64_t ptr = (uint64_t)indices[i]; + m_pSerialiser->Serialise("idxOffsArray", ptr); + } + } + else + { + for(uint32_t i=0; i < Count; i++) + { + uint64_t ptr = 0; + m_pSerialiser->Serialise("idxOffsArray", ptr); + idxOffsArray[i] = (void *)ptr; + } + } + + if(m_State <= EXECUTING) + { + m_Real.glMultiDrawElementsBaseVertex(Mode, countArray, Type, idxOffsArray, Count, baseArray); + } + + const string desc = m_pSerialiser->GetDebugStr(); + + vector debugMessages = Serialise_DebugMessages(); + + if(m_State == READING) + { + AddEvent(MULTI_DRAWARRAYS, desc); + string name = "glMultiDrawElementsBaseVertex(" + + ToStr::Get(Mode) + ", " + + ToStr::Get(Count) + ")"; + + RDCUNIMPLEMENTED("Not processing multi-draw data for glMultiDrawElements() display"); + + FetchDrawcall draw; + draw.name = name; + draw.numIndices = 1; + draw.numInstances = 1; + draw.indexOffset = 0; + draw.vertexOffset = 0; + draw.instanceOffset = 0; + + draw.flags |= eDraw_Drawcall; + + draw.debugMessages = debugMessages; + + m_LastDrawMode = Mode; + + AddDrawcall(draw, true); + } + + SAFE_DELETE_ARRAY(countArray); + SAFE_DELETE_ARRAY(baseArray); + SAFE_DELETE_ARRAY(idxOffsArray); + + return true; +} + +void WrappedOpenGL::glMultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex) +{ + m_Real.glMultiDrawElementsBaseVertex(mode, count, type, indices, drawcount, basevertex); + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(MULTI_DRAWELEMENTSBASEVERTEX); + Serialise_glMultiDrawElementsBaseVertex(mode, count, type, indices, drawcount, basevertex); + + m_ContextRecord->AddChunk(scope.Get()); + } +} + +bool WrappedOpenGL::Serialise_glMultiDrawArraysIndirect(GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride) +{ + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)indirect); + SERIALISE_ELEMENT(uint32_t, Count, drawcount); + SERIALISE_ELEMENT(uint32_t, Stride, stride); + + if(m_State <= EXECUTING) + { + m_Real.glMultiDrawArraysIndirect(Mode, (const void *)Offset, Count, Stride); + } + + const string desc = m_pSerialiser->GetDebugStr(); + + vector debugMessages = Serialise_DebugMessages(); + + if(m_State == READING) + { + AddEvent(DRAWARRAYS_INDIRECT, desc); + string name = "glMultiDrawArraysIndirect(" + + ToStr::Get(Mode) + ")"; + + RDCUNIMPLEMENTED("Not fetching indirect data for glMultiDrawArraysIndirect() display"); + + FetchDrawcall draw; + draw.name = name; + draw.numIndices = 1; + draw.numInstances = 1; + draw.indexOffset = 0; + draw.vertexOffset = 0; + draw.instanceOffset = 0; + + draw.flags |= eDraw_Drawcall; + + draw.debugMessages = debugMessages; + + m_LastDrawMode = Mode; + + AddDrawcall(draw, true); + } + + return true; +} + +void WrappedOpenGL::glMultiDrawArraysIndirect(GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride) +{ + m_Real.glMultiDrawArraysIndirect(mode, indirect, drawcount, stride); + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(MULTI_DRAWELEMENTS_INDIRECT); + Serialise_glMultiDrawArraysIndirect(mode, indirect, drawcount, stride); + + m_ContextRecord->AddChunk(scope.Get()); + } +} + +bool WrappedOpenGL::Serialise_glMultiDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride) +{ + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)indirect); + SERIALISE_ELEMENT(uint32_t, Count, drawcount); + SERIALISE_ELEMENT(uint32_t, Stride, stride); + + if(m_State <= EXECUTING) + { + m_Real.glMultiDrawElementsIndirect(Mode, Type, (const void *)Offset, Count, Stride); + } + + const string desc = m_pSerialiser->GetDebugStr(); + + vector debugMessages = Serialise_DebugMessages(); + + if(m_State == READING) + { + AddEvent(DRAWARRAYS_INDIRECT, desc); + string name = "glMultiDrawElementsIndirect(" + + ToStr::Get(Mode) + ")"; + + RDCUNIMPLEMENTED("Not fetching indirect data for glMultiDrawElementsIndirect() display"); + + FetchDrawcall draw; + draw.name = name; + draw.numIndices = 1; + draw.numInstances = 1; + draw.indexOffset = 0; + draw.vertexOffset = 0; + draw.instanceOffset = 0; + + draw.flags |= eDraw_Drawcall; + + draw.debugMessages = debugMessages; + + m_LastDrawMode = Mode; + + AddDrawcall(draw, true); + } + + return true; +} + +void WrappedOpenGL::glMultiDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride) +{ + m_Real.glMultiDrawElementsIndirect(mode, type, indirect, drawcount, stride); + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(MULTI_DRAWELEMENTS_INDIRECT); + Serialise_glMultiDrawElementsIndirect(mode, type, indirect, drawcount, stride); + + m_ContextRecord->AddChunk(scope.Get()); + } +} + bool WrappedOpenGL::Serialise_glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) { SERIALISE_ELEMENT(GLenum, buf, buffer);