diff --git a/renderdoc/driver/gl/wrappers/gl_debug_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_debug_funcs.cpp index 7bc3745f1..174ab3723 100644 --- a/renderdoc/driver/gl/wrappers/gl_debug_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_debug_funcs.cpp @@ -27,69 +27,52 @@ #include "common/common.h" #include "strings/string_utils.h" -bool WrappedOpenGL::Serialise_glObjectLabel(GLenum identifier, GLuint name, GLsizei length, - const GLchar *label) +template +bool WrappedOpenGL::Serialise_glObjectLabel(SerialiserType &ser, GLenum identifier, GLuint name, + GLsizei length, const GLchar *label) { - ResourceId liveid; + GLResource Resource; + std::string Label; - bool extvariant = false; - - string Label; - if(m_State >= WRITING) + if(ser.IsWriting()) { - if(length == 0) + if(length == 0 || label == NULL) Label = ""; else - Label = string(label, label + (length > 0 ? length : strlen(label))); + Label = std::string(label, label + (length > 0 ? length : strlen(label))); switch(identifier) { - case eGL_TEXTURE: liveid = GetResourceManager()->GetID(TextureRes(GetCtx(), name)); break; + case eGL_TEXTURE: Resource = TextureRes(GetCtx(), name); break; case eGL_BUFFER_OBJECT_EXT: - extvariant = true; // intentional fallthrough - case eGL_BUFFER: liveid = GetResourceManager()->GetID(BufferRes(GetCtx(), name)); break; + case eGL_BUFFER: Resource = BufferRes(GetCtx(), name); break; case eGL_PROGRAM_OBJECT_EXT: - extvariant = true; // intentional fallthrough - case eGL_PROGRAM: liveid = GetResourceManager()->GetID(ProgramRes(GetCtx(), name)); break; + case eGL_PROGRAM: Resource = ProgramRes(GetCtx(), name); break; case eGL_PROGRAM_PIPELINE_OBJECT_EXT: - extvariant = true; // intentional fallthrough - case eGL_PROGRAM_PIPELINE: - liveid = GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), name)); - break; + case eGL_PROGRAM_PIPELINE: Resource = ProgramPipeRes(GetCtx(), name); break; case eGL_VERTEX_ARRAY_OBJECT_EXT: - extvariant = true; // intentional fallthrough - case eGL_VERTEX_ARRAY: - liveid = GetResourceManager()->GetID(VertexArrayRes(GetCtx(), name)); - break; + case eGL_VERTEX_ARRAY: Resource = VertexArrayRes(GetCtx(), name); break; case eGL_SHADER_OBJECT_EXT: - extvariant = true; // intentional fallthrough - case eGL_SHADER: liveid = GetResourceManager()->GetID(ShaderRes(GetCtx(), name)); break; + case eGL_SHADER: Resource = ShaderRes(GetCtx(), name); break; case eGL_QUERY_OBJECT_EXT: - extvariant = true; // intentional fallthrough - case eGL_QUERY: liveid = GetResourceManager()->GetID(QueryRes(GetCtx(), name)); break; - case eGL_TRANSFORM_FEEDBACK: - liveid = GetResourceManager()->GetID(FeedbackRes(GetCtx(), name)); - break; - case eGL_SAMPLER: liveid = GetResourceManager()->GetID(SamplerRes(GetCtx(), name)); break; - case eGL_RENDERBUFFER: - liveid = GetResourceManager()->GetID(RenderbufferRes(GetCtx(), name)); - break; - case eGL_FRAMEBUFFER: - liveid = GetResourceManager()->GetID(FramebufferRes(GetCtx(), name)); - break; + case eGL_QUERY: Resource = QueryRes(GetCtx(), name); break; + case eGL_TRANSFORM_FEEDBACK: Resource = FeedbackRes(GetCtx(), name); break; + case eGL_SAMPLER: Resource = SamplerRes(GetCtx(), name); break; + case eGL_RENDERBUFFER: Resource = RenderbufferRes(GetCtx(), name); break; + case eGL_FRAMEBUFFER: Resource = FramebufferRes(GetCtx(), name); break; default: RDCERR("Unhandled namespace in glObjectLabel"); } } - SERIALISE_ELEMENT(GLenum, Identifier, identifier); - SERIALISE_ELEMENT(ResourceId, id, liveid); - SERIALISE_ELEMENT(uint32_t, Length, length); - SERIALISE_ELEMENT(bool, HasLabel, label != NULL); + SERIALISE_ELEMENT(Resource); + SERIALISE_ELEMENT(length); + SERIALISE_ELEMENT(Label); - m_pSerialiser->SerialiseString("label", Label); - - if(m_State == READING && GetResourceManager()->HasLiveResource(id)) - GetResourceManager()->SetName(id, HasLabel ? Label : ""); + if(IsReplayingAndReading() && Resource.name) + { + GetResourceManager()->SetName( + GetResourceManager()->GetOriginalID(GetResourceManager()->GetID(Resource)), Label); + } return true; } @@ -99,10 +82,11 @@ void WrappedOpenGL::glLabelObjectEXT(GLenum identifier, GLuint name, GLsizei len { m_Real.glLabelObjectEXT(identifier, name, length, label); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { - SCOPED_SERIALISE_CONTEXT(OBJECT_LABEL); - Serialise_glObjectLabel(identifier, name, length, label); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glObjectLabel(ser, identifier, name, length, label); m_DeviceRecord->AddChunk(scope.Get()); } @@ -112,10 +96,11 @@ void WrappedOpenGL::glObjectLabel(GLenum identifier, GLuint name, GLsizei length { m_Real.glObjectLabel(identifier, name, length, label); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { - SCOPED_SERIALISE_CONTEXT(OBJECT_LABEL); - Serialise_glObjectLabel(identifier, name, length, label); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glObjectLabel(ser, identifier, name, length, label); m_DeviceRecord->AddChunk(scope.Get()); } @@ -125,11 +110,12 @@ void WrappedOpenGL::glObjectPtrLabel(const void *ptr, GLsizei length, const GLch { m_Real.glObjectPtrLabel(ptr, length, label); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { - SCOPED_SERIALISE_CONTEXT(OBJECT_LABEL); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); ResourceId id = GetResourceManager()->GetSyncID((GLsync)ptr); - Serialise_glObjectLabel(eGL_SYNC_FENCE, GetResourceManager()->GetCurrentResource(id).name, + Serialise_glObjectLabel(ser, eGL_SYNC_FENCE, GetResourceManager()->GetCurrentResource(id).name, length, label); m_DeviceRecord->AddChunk(scope.Get()); @@ -151,24 +137,32 @@ void WrappedOpenGL::glDebugMessageControl(GLenum source, GLenum type, GLenum sev m_Real.glDebugMessageControl(source, type, severity, count, ids, enabled); } -bool WrappedOpenGL::Serialise_glDebugMessageInsert(GLenum source, GLenum type, GLuint id, - GLenum severity, GLsizei length, const GLchar *buf) +template +bool WrappedOpenGL::Serialise_glDebugMessageInsert(SerialiserType &ser, GLenum source, GLenum type, + GLuint id, GLenum severity, GLsizei length, + const GLchar *buf) { - string name = buf ? string(buf, buf + (length > 0 ? length : strlen(buf))) : ""; + std::string name = buf ? std::string(buf, buf + (length > 0 ? length : strlen(buf))) : ""; - m_pSerialiser->Serialise("Name", name); + // unused, just for the user's benefit + SERIALISE_ELEMENT(source); + SERIALISE_ELEMENT(type); + SERIALISE_ELEMENT(id); + SERIALISE_ELEMENT(severity); + SERIALISE_ELEMENT(name); - if(m_State == EXECUTING) + if(IsReplayingAndReading()) { GLMarkerRegion::Set(name); - } - else if(m_State == READING) - { - DrawcallDescription draw; - draw.name = name; - draw.flags |= DrawFlags::SetMarker; - AddDrawcall(draw, false); + if(IsLoading(m_State)) + { + DrawcallDescription draw; + draw.name = name; + draw.flags |= DrawFlags::SetMarker; + + AddDrawcall(draw, false); + } } return true; @@ -177,10 +171,12 @@ bool WrappedOpenGL::Serialise_glDebugMessageInsert(GLenum source, GLenum type, G void WrappedOpenGL::glDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf) { - if(m_State == WRITING_CAPFRAME && type == eGL_DEBUG_TYPE_MARKER) + if(IsActiveCapturing(m_State) && type == eGL_DEBUG_TYPE_MARKER) { - SCOPED_SERIALISE_CONTEXT(SET_MARKER); - Serialise_glDebugMessageInsert(source, type, id, severity, length, buf); + USE_SCRATCH_SERIALISER(); + ser.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glDebugMessageInsert(ser, source, type, id, severity, length, buf); m_ContextRecord->AddChunk(scope.Get()); } @@ -190,10 +186,11 @@ void WrappedOpenGL::glDebugMessageInsert(GLenum source, GLenum type, GLuint id, void WrappedOpenGL::glPushGroupMarkerEXT(GLsizei length, const GLchar *marker) { - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(BEGIN_EVENT); - Serialise_glPushDebugGroup(eGL_NONE, 0, length, marker); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glPushDebugGroup(ser, eGL_DEBUG_SOURCE_APPLICATION, 0, length, marker); m_ContextRecord->AddChunk(scope.Get()); } @@ -201,21 +198,50 @@ void WrappedOpenGL::glPushGroupMarkerEXT(GLsizei length, const GLchar *marker) void WrappedOpenGL::glPopGroupMarkerEXT() { - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(END_EVENT); - Serialise_glPopDebugGroup(); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glPopDebugGroup(ser); m_ContextRecord->AddChunk(scope.Get()); } } +template +bool WrappedOpenGL::Serialise_glInsertEventMarkerEXT(SerialiserType &ser, GLsizei length, + const GLchar *marker_) +{ + std::string marker = + marker_ ? std::string(marker_, marker_ + (length > 0 ? length : strlen(marker_))) : ""; + + SERIALISE_ELEMENT(marker); + + if(IsReplayingAndReading()) + { + GLMarkerRegion::Set(marker); + + if(IsLoading(m_State)) + { + DrawcallDescription draw; + draw.name = marker; + draw.flags |= DrawFlags::SetMarker; + + AddDrawcall(draw, false); + } + } + + return true; +} + void WrappedOpenGL::glInsertEventMarkerEXT(GLsizei length, const GLchar *marker) { - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_MARKER); - Serialise_glDebugMessageInsert(eGL_NONE, eGL_NONE, 0, eGL_NONE, length, marker); + USE_SCRATCH_SERIALISER(); + ser.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glInsertEventMarkerEXT(ser, length, marker); m_ContextRecord->AddChunk(scope.Get()); } @@ -228,34 +254,41 @@ void WrappedOpenGL::glFrameTerminatorGREMEDY() void WrappedOpenGL::glStringMarkerGREMEDY(GLsizei len, const void *string) { - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(SET_MARKER); - Serialise_glDebugMessageInsert(eGL_NONE, eGL_NONE, 0, eGL_NONE, len, (const GLchar *)string); + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glInsertEventMarkerEXT(ser, len, (const GLchar *)string); m_ContextRecord->AddChunk(scope.Get()); } } -bool WrappedOpenGL::Serialise_glPushDebugGroup(GLenum source, GLuint id, GLsizei length, - const GLchar *message) +template +bool WrappedOpenGL::Serialise_glPushDebugGroup(SerialiserType &ser, GLenum source, GLuint id, + GLsizei length, const GLchar *message) { - string name = message ? string(message, message + (length > 0 ? length : strlen(message))) : ""; + std::string name = + message ? std::string(message, message + (length > 0 ? length : strlen(message))) : ""; - m_pSerialiser->Serialise("Name", name); + // unused, just for the user's benefit + SERIALISE_ELEMENT(source); + SERIALISE_ELEMENT(id); + SERIALISE_ELEMENT(name); - if(m_State == EXECUTING) + if(IsReplayingAndReading()) { - GLMarkerRegion::Begin(name); + GLMarkerRegion::Begin(name, source, id); m_ReplayEventCount++; - } - else if(m_State == READING) - { - DrawcallDescription draw; - draw.name = name; - draw.flags |= DrawFlags::PushMarker; - AddDrawcall(draw, false); + if(IsLoading(m_State)) + { + DrawcallDescription draw; + draw.name = name; + draw.flags |= DrawFlags::PushMarker; + + AddDrawcall(draw, false); + } } return true; @@ -263,10 +296,12 @@ bool WrappedOpenGL::Serialise_glPushDebugGroup(GLenum source, GLuint id, GLsizei void WrappedOpenGL::glPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message) { - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(BEGIN_EVENT); - Serialise_glPushDebugGroup(source, id, length, message); + USE_SCRATCH_SERIALISER(); + ser.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glPushDebugGroup(ser, source, id, length, message); m_ContextRecord->AddChunk(scope.Get()); } @@ -274,33 +309,46 @@ void WrappedOpenGL::glPushDebugGroup(GLenum source, GLuint id, GLsizei length, c m_Real.glPushDebugGroup(source, id, length, message); } -bool WrappedOpenGL::Serialise_glPopDebugGroup() +template +bool WrappedOpenGL::Serialise_glPopDebugGroup(SerialiserType &ser) { - if(m_State == EXECUTING) + if(IsReplayingAndReading()) { GLMarkerRegion::End(); m_ReplayEventCount = RDCMAX(0, m_ReplayEventCount - 1); - } - else if(m_State == READING && !m_CurEvents.empty()) - { - DrawcallDescription draw; - draw.name = "API Calls"; - draw.flags |= DrawFlags::SetMarker | DrawFlags::APICalls; - AddDrawcall(draw, true); + if(IsLoading(m_State) && !m_CurEvents.empty()) + { + DrawcallDescription draw; + draw.name = "API Calls"; + draw.flags |= DrawFlags::SetMarker | DrawFlags::APICalls; + + AddDrawcall(draw, true); + } } return true; } void WrappedOpenGL::glPopDebugGroup() { - if(m_State == WRITING_CAPFRAME) + if(IsActiveCapturing(m_State)) { - SCOPED_SERIALISE_CONTEXT(END_EVENT); - Serialise_glPopDebugGroup(); + USE_SCRATCH_SERIALISER(); + ser.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glPopDebugGroup(ser); m_ContextRecord->AddChunk(scope.Get()); } m_Real.glPopDebugGroup(); } + +INSTANTIATE_FUNCTION_SERIALISED(void, glObjectLabel, GLenum identifier, GLuint name, GLsizei length, + const GLchar *label); +INSTANTIATE_FUNCTION_SERIALISED(void, glDebugMessageInsert, GLenum source, GLenum type, GLuint id, + GLenum severity, GLsizei length, const GLchar *buf); +INSTANTIATE_FUNCTION_SERIALISED(void, glInsertEventMarkerEXT, GLsizei length, const GLchar *marker); +INSTANTIATE_FUNCTION_SERIALISED(void, glPushDebugGroup, GLenum source, GLuint id, GLsizei length, + const GLchar *message); +INSTANTIATE_FUNCTION_SERIALISED(void, glPopDebugGroup);