From f13f07ee4eede9f4f8e35179c1b4cdc11e1c562a Mon Sep 17 00:00:00 2001 From: baldurk Date: Sat, 8 Nov 2014 22:55:32 +0000 Subject: [PATCH] Implement remaining functions that UE4 uses * glBindFragDataLocation * glMultiDraw* (non indirect) * glDraw*Indirect * glDispatchComputeIndirect --- renderdoc/driver/gl/gl_common.h | 6 + renderdoc/driver/gl/gl_driver.cpp | 24 ++ renderdoc/driver/gl/gl_driver.h | 6 + renderdoc/driver/gl/gl_hookset.h | 6 + renderdoc/driver/gl/gl_hookset_defs.h | 12 + .../driver/gl/wrappers/gl_draw_funcs.cpp | 308 ++++++++++++++++++ .../driver/gl/wrappers/gl_shader_funcs.cpp | 33 ++ 7 files changed, 395 insertions(+) diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index 5518edf14..f77227f1a 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -134,6 +134,7 @@ enum GLChunkType USEPROGRAM, PROGRAMPARAMETER, BINDATTRIB_LOCATION, + BINDFRAGDATA_LOCATION, UNIFORM_BLOCKBIND, PROGRAMUNIFORM_VECTOR, PROGRAMUNIFORM_MATRIX, @@ -209,17 +210,22 @@ enum GLChunkType BINDVERTEXBUFFER, VERTEXBINDINGDIVISOR, DISPATCH_COMPUTE, + DISPATCH_COMPUTE_INDIRECT, MEMORY_BARRIER, DRAWARRAYS, + DRAWARRAYS_INDIRECT, DRAWARRAYS_INSTANCED, DRAWARRAYS_INSTANCEDBASEINSTANCE, DRAWELEMENTS, + DRAWELEMENTS_INDIRECT, DRAWRANGEELEMENTS, DRAWELEMENTS_INSTANCED, DRAWELEMENTS_INSTANCEDBASEINSTANCE, DRAWELEMENTS_BASEVERTEX, DRAWELEMENTS_INSTANCEDBASEVERTEX, DRAWELEMENTS_INSTANCEDBASEVERTEXBASEINSTANCE, + MULTI_DRAWARRAYS, + MULTI_DRAWELEMENTS, GEN_FRAMEBUFFERS, FRAMEBUFFER_TEX, diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 0c2e72f5b..0558ec2a6 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -87,6 +87,7 @@ const char *GLChunkNames[] = "glUseProgram", "glProgramParameter", "glBindAttribLocation", + "glBindFragDataLocation", "glUniformBlockBinding", "glProgramUniformMatrix*", "glProgramUniformVector*", @@ -162,17 +163,22 @@ const char *GLChunkNames[] = "glBindVertexBuffer", "glVertexBindingDivisor", "glDispatchCompute", + "glDispatchComputeIndirect", "glMemoryBarrier", "glDrawArrays", + "glDrawArraysIndirect", "glDrawArraysInstanced", "glDrawArraysInstancedBaseInstance", "glDrawElements", + "glDrawElementsIndirect", "glDrawRangeElements", "glDrawElementsInstanced", "glDrawElementsInstancedBaseInstance", "glDrawElementsBaseVertex", "glDrawElementsInstancedBaseVertex", "glDrawElementsInstancedBaseVertexBaseInstance", + "glMultiDrawArrays", + "glMultiDrawElements", "glGenFramebuffers", "glFramebufferTexture", @@ -1565,6 +1571,9 @@ void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context) case BINDATTRIB_LOCATION: Serialise_glBindAttribLocation(0, 0, NULL); break; + case BINDFRAGDATA_LOCATION: + Serialise_glBindFragDataLocation(0, 0, NULL); + break; case UNIFORM_BLOCKBIND: Serialise_glUniformBlockBinding(0, 0, 0); break; @@ -1784,12 +1793,18 @@ void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context) case DISPATCH_COMPUTE: Serialise_glDispatchCompute(0, 0, 0); break; + case DISPATCH_COMPUTE_INDIRECT: + Serialise_glDispatchComputeIndirect(0); + break; case MEMORY_BARRIER: Serialise_glMemoryBarrier(0); break; case DRAWARRAYS: Serialise_glDrawArrays(eGL_NONE, 0, 0); break; + case DRAWARRAYS_INDIRECT: + Serialise_glDrawArraysIndirect(eGL_NONE, 0); + break; case DRAWARRAYS_INSTANCED: Serialise_glDrawArraysInstanced(eGL_NONE, 0, 0, 0); break; @@ -1799,6 +1814,9 @@ void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context) case DRAWELEMENTS: Serialise_glDrawElements(eGL_NONE, 0, eGL_NONE, NULL); break; + case DRAWELEMENTS_INDIRECT: + Serialise_glDrawElementsIndirect(eGL_NONE, eGL_NONE, 0); + break; case DRAWRANGEELEMENTS: Serialise_glDrawRangeElements(eGL_NONE, 0, 0, 0, eGL_NONE, NULL); break; @@ -1817,6 +1835,12 @@ void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context) case DRAWELEMENTS_INSTANCEDBASEVERTEXBASEINSTANCE: Serialise_glDrawElementsInstancedBaseVertexBaseInstance(eGL_NONE, 0, eGL_NONE, NULL, 0, 0, 0); break; + case MULTI_DRAWARRAYS: + Serialise_glMultiDrawArrays(eGL_NONE, NULL, NULL, 0); + break; + case MULTI_DRAWELEMENTS: + Serialise_glMultiDrawElements(eGL_NONE, NULL, eGL_NONE, NULL, 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 ed83a48dc..46189c82d 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -491,6 +491,7 @@ class WrappedOpenGL IMPLEMENT_FUNCTION_SERIALISED(void, glProgramParameteri(GLuint program, GLenum pname, GLint value)); IMPLEMENT_FUNCTION_SERIALISED(void, glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)); IMPLEMENT_FUNCTION_SERIALISED(void, glBindAttribLocation(GLuint program, GLuint index, const GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBindFragDataLocation(GLuint program, GLuint color, const GLchar *name)); IMPLEMENT_FUNCTION_SERIALISED(void, glUseProgram(GLuint program)); IMPLEMENT_FUNCTION_SERIALISED(void, glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)); IMPLEMENT_FUNCTION_SERIALISED(void, glValidateProgram(GLuint program)); @@ -512,6 +513,7 @@ class WrappedOpenGL IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glUnmapBuffer(GLenum target)); IMPLEMENT_FUNCTION_SERIALISED(void, glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDispatchComputeIndirect(GLintptr indirect)); IMPLEMENT_FUNCTION_SERIALISED(void, glMemoryBarrier(GLbitfield barriers)); IMPLEMENT_FUNCTION_SERIALISED(void, glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)); IMPLEMENT_FUNCTION_SERIALISED(void, glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)); @@ -935,6 +937,10 @@ class WrappedOpenGL IMPLEMENT_FUNCTION_SERIALISED(void, glDrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance)); IMPLEMENT_FUNCTION_SERIALISED(void, glDrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex)); 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, 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)); IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteVertexArrays(GLsizei n, const GLuint *arrays)); diff --git a/renderdoc/driver/gl/gl_hookset.h b/renderdoc/driver/gl/gl_hookset.h index afbe87b18..9410a5816 100644 --- a/renderdoc/driver/gl/gl_hookset.h +++ b/renderdoc/driver/gl/gl_hookset.h @@ -402,6 +402,7 @@ struct GLHookSet PFNGLVERTEXATTRIBLFORMATPROC glVertexAttribLFormat; PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor; PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation; + PFNGLBINDFRAGDATALOCATIONPROC glBindFragDataLocation; PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; PFNGLBINDVERTEXBUFFERPROC glBindVertexBuffer; @@ -423,6 +424,7 @@ struct GLHookSet PFNGLPOINTPARAMETERIPROC glPointParameteri; PFNGLPOINTPARAMETERIVPROC glPointParameteriv; PFNGLDISPATCHCOMPUTEPROC glDispatchCompute; + PFNGLDISPATCHCOMPUTEINDIRECTPROC glDispatchComputeIndirect; PFNGLMEMORYBARRIERPROC glMemoryBarrier; PFNGLCLEARBUFFERFVPROC glClearBufferfv; PFNGLCLEARBUFFERIVPROC glClearBufferiv; @@ -545,6 +547,10 @@ struct GLHookSet PFNGLDRAWELEMENTSBASEVERTEXPROC glDrawElementsBaseVertex; PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glDrawElementsInstancedBaseVertex; PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glDrawElementsInstancedBaseVertexBaseInstance; + PFNGLMULTIDRAWARRAYSPROC glMultiDrawArrays; + PFNGLMULTIDRAWELEMENTSPROC glMultiDrawElements; + PFNGLDRAWARRAYSINDIRECTPROC glDrawArraysIndirect; + PFNGLDRAWELEMENTSINDIRECTPROC glDrawElementsIndirect; PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC glCheckNamedFramebufferStatusEXT; PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC glCompressedTextureImage1DEXT; diff --git a/renderdoc/driver/gl/gl_hookset_defs.h b/renderdoc/driver/gl/gl_hookset_defs.h index 530a1e713..b12bbbbfd 100644 --- a/renderdoc/driver/gl/gl_hookset_defs.h +++ b/renderdoc/driver/gl/gl_hookset_defs.h @@ -421,6 +421,7 @@ HookExtension(PFNGLVERTEXATTRIBLFORMATPROC, glVertexAttribLFormat); \ HookExtension(PFNGLVERTEXATTRIBDIVISORPROC, glVertexAttribDivisor); \ HookExtension(PFNGLBINDATTRIBLOCATIONPROC, glBindAttribLocation); \ + HookExtension(PFNGLBINDFRAGDATALOCATIONPROC, glBindFragDataLocation); \ HookExtension(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray); \ HookExtension(PFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray); \ HookExtension(PFNGLBINDVERTEXBUFFERPROC, glBindVertexBuffer); \ @@ -442,6 +443,7 @@ HookExtension(PFNGLPOINTPARAMETERIPROC, glPointParameteri); \ HookExtension(PFNGLPOINTPARAMETERIVPROC, glPointParameteriv); \ HookExtension(PFNGLDISPATCHCOMPUTEPROC, glDispatchCompute); \ + HookExtension(PFNGLDISPATCHCOMPUTEINDIRECTPROC, glDispatchComputeIndirect); \ HookExtension(PFNGLMEMORYBARRIERPROC, glMemoryBarrier); \ HookExtension(PFNGLCLEARBUFFERFVPROC, glClearBufferfv); \ HookExtension(PFNGLCLEARBUFFERIVPROC, glClearBufferiv); \ @@ -564,6 +566,10 @@ HookExtension(PFNGLDRAWELEMENTSBASEVERTEXPROC, glDrawElementsBaseVertex); \ HookExtension(PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC, glDrawElementsInstancedBaseVertex); \ HookExtension(PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC, glDrawElementsInstancedBaseVertexBaseInstance); \ + HookExtension(PFNGLMULTIDRAWARRAYSPROC, glMultiDrawArrays); \ + HookExtension(PFNGLMULTIDRAWELEMENTSPROC, glMultiDrawElements); \ + HookExtension(PFNGLDRAWARRAYSINDIRECTPROC, glDrawArraysIndirect); \ + HookExtension(PFNGLDRAWELEMENTSINDIRECTPROC, glDrawElementsIndirect); \ HookExtension(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer); \ HookExtension(PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC, glCheckNamedFramebufferStatusEXT); \ HookExtension(PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC, glCompressedTextureImage1DEXT); \ @@ -1042,6 +1048,7 @@ HookWrapper4(void, glVertexAttribLFormat, GLuint, attribindex, GLint, size, GLenum, type, GLuint, relativeoffset); \ HookWrapper2(void, glVertexAttribDivisor, GLuint, index, GLuint, divisor); \ HookWrapper3(void, glBindAttribLocation, GLuint, program, GLuint, index, const GLchar *, name); \ + HookWrapper3(void, glBindFragDataLocation, GLuint, program, GLuint, color, const GLchar *, name); \ HookWrapper1(void, glEnableVertexAttribArray, GLuint, index); \ HookWrapper1(void, glDisableVertexAttribArray, GLuint, index); \ HookWrapper4(void, glBindVertexBuffer, GLuint, bindingindex, GLuint, buffer, GLintptr, offset, GLsizei, stride); \ @@ -1063,6 +1070,7 @@ HookWrapper2(void, glPointParameteri, GLenum, pname, GLint, param); \ HookWrapper2(void, glPointParameteriv, GLenum, pname, const GLint *, params); \ HookWrapper3(void, glDispatchCompute, GLuint, num_groups_x, GLuint, num_groups_y, GLuint, num_groups_z); \ + HookWrapper1(void, glDispatchComputeIndirect, GLintptr, indirect); \ HookWrapper1(void, glMemoryBarrier, GLbitfield, barriers); \ HookWrapper3(void, glClearBufferfv, GLenum, buffer, GLint, drawbuffer, const GLfloat *, value); \ HookWrapper3(void, glClearBufferiv, GLenum, buffer, GLint, drawbuffer, const GLint *, value); \ @@ -1185,6 +1193,10 @@ HookWrapper5(void, glDrawElementsBaseVertex, GLenum, mode, GLsizei, count, GLenum, type, const void *, indices, GLint, basevertex); \ HookWrapper6(void, glDrawElementsInstancedBaseVertex, GLenum, mode, GLsizei, count, GLenum, type, const void *, indices, GLsizei, instancecount, GLint, basevertex); \ 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); \ + 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); \ HookWrapper2(GLenum, glCheckNamedFramebufferStatusEXT, GLuint, framebuffer, GLenum, target); \ HookWrapper8(void, glCompressedTextureImage1DEXT, GLuint, texture, GLenum, target, GLint, level, GLenum, internalformat, GLsizei, width, GLint, border, GLsizei, imageSize, const void *, bits); \ diff --git a/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp index 31ba7c40e..f6644a87d 100644 --- a/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp @@ -74,6 +74,54 @@ void WrappedOpenGL::glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, } } +bool WrappedOpenGL::Serialise_glDispatchComputeIndirect(GLintptr indirect) +{ + SERIALISE_ELEMENT(uint64_t, offs, indirect); + + if(m_State <= EXECUTING) + { + m_Real.glDispatchComputeIndirect((GLintptr)offs); + } + + const string desc = m_pSerialiser->GetDebugStr(); + + vector debugMessages = Serialise_DebugMessages(); + + if(m_State == READING) + { + AddEvent(DISPATCH_COMPUTE_INDIRECT, desc); + string name = "glDispatchComputeIndirect(" + + ToStr::Get(0) + ", " + + ToStr::Get(0) + ", " + + ToStr::Get(0) + ")"; + + RDCUNIMPLEMENTED("Not fetching indirect data for glDispatchComputeIndirect() display"); + + FetchDrawcall draw; + draw.name = widen(name); + draw.flags |= eDraw_Dispatch; + + draw.debugMessages = debugMessages; + + AddDrawcall(draw, true); + } + + return true; +} + +void WrappedOpenGL::glDispatchComputeIndirect(GLintptr indirect) +{ + m_Real.glDispatchComputeIndirect(indirect); + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DISPATCH_COMPUTE_INDIRECT); + Serialise_glDispatchComputeIndirect(indirect); + + m_ContextRecord->AddChunk(scope.Get()); + } +} + bool WrappedOpenGL::Serialise_glMemoryBarrier(GLbitfield barriers) { SERIALISE_ELEMENT(uint32_t, Barriers, barriers); @@ -155,6 +203,61 @@ void WrappedOpenGL::glDrawArrays(GLenum mode, GLint first, GLsizei count) } } +bool WrappedOpenGL::Serialise_glDrawArraysIndirect(GLenum mode, const void *indirect) +{ + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)indirect); + + if(m_State <= EXECUTING) + { + m_Real.glDrawArraysIndirect(Mode, (const void *)Offset); + } + + const string desc = m_pSerialiser->GetDebugStr(); + + vector debugMessages = Serialise_DebugMessages(); + + if(m_State == READING) + { + AddEvent(DRAWARRAYS_INDIRECT, desc); + string name = "glDrawArraysIndirect(" + + ToStr::Get(Mode) + ")"; + + RDCUNIMPLEMENTED("Not fetching indirect data for glDrawArraysIndirect() display"); + + FetchDrawcall draw; + draw.name = widen(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::glDrawArraysIndirect(GLenum mode, const void *indirect) +{ + m_Real.glDrawArraysIndirect(mode, indirect); + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAWARRAYS_INDIRECT); + Serialise_glDrawArraysIndirect(mode, indirect); + + m_ContextRecord->AddChunk(scope.Get()); + } +} + bool WrappedOpenGL::Serialise_glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) { SERIALISE_ELEMENT(GLenum, Mode, mode); @@ -333,6 +436,65 @@ void WrappedOpenGL::glDrawElements(GLenum mode, GLsizei count, GLenum type, cons } } +bool WrappedOpenGL::Serialise_glDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect) +{ + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)indirect); + + if(m_State <= EXECUTING) + { + m_Real.glDrawElementsIndirect(Mode, Type, (const void *)Offset); + } + + const string desc = m_pSerialiser->GetDebugStr(); + + vector debugMessages = Serialise_DebugMessages(); + + if(m_State == READING) + { + AddEvent(DRAWELEMENTS_INDIRECT, desc); + string name = "glDrawElementsIndirect(" + + ToStr::Get(Mode) + ", " + + ToStr::Get(Type) + ")"; + + RDCUNIMPLEMENTED("Not fetching indirect data for glDrawElementsIndirect() display"); + + FetchDrawcall draw; + draw.name = widen(name); + draw.numIndices = 1; + draw.numInstances = 1; + draw.indexOffset = 0; + draw.vertexOffset = 0; + draw.instanceOffset = 0; + + draw.flags |= eDraw_Drawcall|eDraw_UseIBuffer; + + draw.debugMessages = debugMessages; + + m_LastDrawMode = Mode; + m_LastIndexSize = Type; + m_LastIndexOffset = 0; + + AddDrawcall(draw, true); + } + + return true; +} + +void WrappedOpenGL::glDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect) +{ + m_Real.glDrawElementsIndirect(mode, type, indirect); + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAWELEMENTS_INDIRECT); + Serialise_glDrawElementsIndirect(mode, type, indirect); + + m_ContextRecord->AddChunk(scope.Get()); + } +} + bool WrappedOpenGL::Serialise_glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices) { SERIALISE_ELEMENT(GLenum, Mode, mode); @@ -713,6 +875,152 @@ void WrappedOpenGL::glDrawElementsInstancedBaseVertexBaseInstance(GLenum mode, G } } +bool WrappedOpenGL::Serialise_glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount) +{ + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(uint32_t, Count, drawcount); + + SERIALISE_ELEMENT_ARR(int32_t, firstArray, first, Count); + SERIALISE_ELEMENT_ARR(int32_t, countArray, count, Count); + + if(m_State <= EXECUTING) + { + m_Real.glMultiDrawArrays(Mode, firstArray, countArray, Count); + } + + const string desc = m_pSerialiser->GetDebugStr(); + + vector debugMessages = Serialise_DebugMessages(); + + if(m_State == READING) + { + AddEvent(MULTI_DRAWARRAYS, desc); + string name = "glMultiDrawArrays(" + + ToStr::Get(Mode) + ", " + + ToStr::Get(Count) + ")"; + + RDCUNIMPLEMENTED("Not processing multi-draw data for glMultiDrawArrays() display"); + + FetchDrawcall draw; + draw.name = widen(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(firstArray); + SAFE_DELETE_ARRAY(countArray); + + return true; +} + +void WrappedOpenGL::glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount) +{ + m_Real.glMultiDrawArrays(mode, first, count, drawcount); + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(MULTI_DRAWARRAYS); + Serialise_glMultiDrawArrays(mode, first, count, drawcount); + + m_ContextRecord->AddChunk(scope.Get()); + } +} + +bool WrappedOpenGL::Serialise_glMultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount) +{ + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint32_t, Count, drawcount); + + SERIALISE_ELEMENT_ARR(int32_t, countArray, count, 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.glMultiDrawElements(Mode, countArray, Type, idxOffsArray, Count); + } + + const string desc = m_pSerialiser->GetDebugStr(); + + vector debugMessages = Serialise_DebugMessages(); + + if(m_State == READING) + { + AddEvent(MULTI_DRAWARRAYS, desc); + string name = "glMultiDrawElements(" + + ToStr::Get(Mode) + ", " + + ToStr::Get(Count) + ")"; + + RDCUNIMPLEMENTED("Not processing multi-draw data for glMultiDrawElements() display"); + + FetchDrawcall draw; + draw.name = widen(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(idxOffsArray); + + return true; +} + +void WrappedOpenGL::glMultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount) +{ + m_Real.glMultiDrawElements(mode, count, type, indices, drawcount); + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(MULTI_DRAWELEMENTS); + Serialise_glMultiDrawElements(mode, count, type, indices, drawcount); + + m_ContextRecord->AddChunk(scope.Get()); + } +} + bool WrappedOpenGL::Serialise_glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) { SERIALISE_ELEMENT(GLenum, buf, buffer); diff --git a/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp index 11e8aa550..98a5d673e 100644 --- a/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp @@ -539,6 +539,39 @@ void WrappedOpenGL::glBindAttribLocation(GLuint program, GLuint index, const GLc } } +bool WrappedOpenGL::Serialise_glBindFragDataLocation(GLuint program, GLuint color, const GLchar *name_) +{ + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); + SERIALISE_ELEMENT(uint32_t, col, color); + + string name = name_ ? name_ : ""; + m_pSerialiser->Serialise("Name", name); + + if(m_State == READING) + { + m_Real.glBindFragDataLocation(GetResourceManager()->GetLiveResource(id).name, col, name.c_str()); + } + + return true; +} + +void WrappedOpenGL::glBindFragDataLocation(GLuint program, GLuint color, const GLchar *name) +{ + m_Real.glBindFragDataLocation(program, color, name); + + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); + RDCASSERT(record); + { + SCOPED_SERIALISE_CONTEXT(BINDFRAGDATA_LOCATION); + Serialise_glBindFragDataLocation(program, color, name); + + record->AddChunk(scope.Get()); + } + } +} + bool WrappedOpenGL::Serialise_glProgramParameteri(GLuint program, GLenum pname, GLint value) { SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program)));