diff --git a/renderdoc/driver/gl/gl_counters.cpp b/renderdoc/driver/gl/gl_counters.cpp index b37b08aa8..40bdc3896 100644 --- a/renderdoc/driver/gl/gl_counters.cpp +++ b/renderdoc/driver/gl/gl_counters.cpp @@ -63,8 +63,10 @@ vector GLReplay::EnumerateCounters() return ret; } -void GLReplay::DescribeCounter(GPUCounter counterID, CounterDescription &desc) +CounterDescription GLReplay::DescribeCounter(GPUCounter counterID) { + CounterDescription desc = {}; + desc.counterID = counterID; // FFBA5548-FBF8-405D-BA18-F0329DA370A0 desc.uuid.bytes[0] = 0xFFBA5548; @@ -174,6 +176,8 @@ void GLReplay::DescribeCounter(GPUCounter counterID, CounterDescription &desc) desc.unit = CounterUnit::Absolute; break; } + + return desc; } struct GPUQueries diff --git a/renderdoc/driver/gl/gl_debug.cpp b/renderdoc/driver/gl/gl_debug.cpp index dcf1d035b..3d43661d7 100644 --- a/renderdoc/driver/gl/gl_debug.cpp +++ b/renderdoc/driver/gl/gl_debug.cpp @@ -1636,8 +1636,8 @@ void GLReplay::CopyTex2DMSToArray(GLuint destArray, GLuint srcMS, GLint width, G return; } - GLRenderState rs(&gl.GetHookset(), NULL, READING); - rs.FetchState(m_pDriver->GetCtx(), m_pDriver); + GLRenderState rs(&gl.GetHookset()); + rs.FetchState(m_pDriver); GLenum viewClass; gl.glGetInternalformativ(eGL_TEXTURE_2D_ARRAY, intFormat, eGL_VIEW_COMPATIBILITY_CLASS, @@ -1686,7 +1686,7 @@ void GLReplay::CopyTex2DMSToArray(GLuint destArray, GLuint srcMS, GLint width, G gl.glDeleteTextures(2, texs); - rs.ApplyState(m_pDriver->GetCtx(), m_pDriver); + rs.ApplyState(m_pDriver); } bool GLReplay::RenderTexture(TextureDisplay cfg) @@ -2201,8 +2201,8 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOve void *ctx = m_ReplayCtx.ctx; - GLRenderState rs(&gl.GetHookset(), NULL, READING); - rs.FetchState(ctx, &gl); + GLRenderState rs(&gl.GetHookset()); + rs.FetchState(&gl); // use our overlay pipeline that we'll fill up with all the right // shaders, then replace the fragment shader with our own. @@ -2212,7 +2212,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOve // we bind the separable program created for each shader, and copy // uniforms and attrib bindings from the 'real' programs, wherever // they are. - SetupOverlayPipeline(rs.Program, rs.Pipeline, DebugData.fixedcolFSProg); + SetupOverlayPipeline(rs.Program.name, rs.Pipeline.name, DebugData.fixedcolFSProg); auto &texDetails = m_pDriver->m_Textures[texid]; @@ -2396,9 +2396,10 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOve GLuint curDepth = 0, curStencil = 0; - gl.glGetNamedFramebufferAttachmentParameterivEXT( - rs.DrawFBO, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&curDepth); - gl.glGetNamedFramebufferAttachmentParameterivEXT(rs.DrawFBO, eGL_STENCIL_ATTACHMENT, + gl.glGetNamedFramebufferAttachmentParameterivEXT(rs.DrawFBO.name, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&curDepth); + gl.glGetNamedFramebufferAttachmentParameterivEXT(rs.DrawFBO.name, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&curStencil); @@ -2415,7 +2416,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOve { GLint type = 0; gl.glGetNamedFramebufferAttachmentParameterivEXT( - rs.DrawFBO, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type); + rs.DrawFBO.name, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type); GLenum fmt; @@ -2427,14 +2428,14 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOve fmt = details.internalFormat; gl.glGetNamedFramebufferAttachmentParameterivEXT( - rs.DrawFBO, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &mip); + rs.DrawFBO.name, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &mip); if(details.curType == eGL_TEXTURE_CUBE_MAP) { GLenum face; gl.glGetNamedFramebufferAttachmentParameterivEXT( - rs.DrawFBO, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, - (GLint *)&face); + rs.DrawFBO.name, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, (GLint *)&face); layer = CubeTargetIndex(face); } @@ -2484,7 +2485,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOve { GLint type = 0; gl.glGetNamedFramebufferAttachmentParameterivEXT( - rs.DrawFBO, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type); + rs.DrawFBO.name, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type); GLenum fmt; @@ -2499,8 +2500,8 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOve { GLenum face; gl.glGetNamedFramebufferAttachmentParameterivEXT( - rs.DrawFBO, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, - (GLint *)&face); + rs.DrawFBO.name, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, (GLint *)&face); layer = CubeTargetIndex(face); } @@ -2566,7 +2567,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOve } // bind the 'real' fbo to the read framebuffer, so we can blit from it - gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, rs.DrawFBO); + gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, rs.DrawFBO.name); float green[] = {0.0f, 1.0f, 0.0f, 1.0f}; gl.glProgramUniform4fv(DebugData.fixedcolFSProg, colLoc, 1, green); @@ -2659,7 +2660,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOve else { // if we don't replay the real state, restore what we've changed - rs.ApplyState(ctx, &gl); + rs.ApplyState(&gl); } float black[] = {0.0f, 0.0f, 0.0f, 0.0f}; @@ -2719,7 +2720,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOve if(overlay == DebugOverlay::TriangleSizePass) ReplayLog(events[0], eReplay_WithoutDraw); else - rs.ApplyState(m_pDriver->GetCtx(), m_pDriver); + rs.ApplyState(m_pDriver); // this all happens on the replay context so we need a temp FBO/VAO GLuint overlayFBO = 0, tempVAO = 0; @@ -3107,14 +3108,14 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOve // TODO handle non-2D depth/stencil attachments and fetch slice or cubemap face GLint mip = 0; - gl.glGetNamedFramebufferAttachmentParameterivEXT(rs.DrawFBO, eGL_DEPTH_ATTACHMENT, + gl.glGetNamedFramebufferAttachmentParameterivEXT(rs.DrawFBO.name, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&curDepth); - gl.glGetNamedFramebufferAttachmentParameterivEXT(rs.DrawFBO, eGL_DEPTH_ATTACHMENT, + gl.glGetNamedFramebufferAttachmentParameterivEXT(rs.DrawFBO.name, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&depthType); gl.glGetNamedFramebufferAttachmentParameterivEXT( - rs.DrawFBO, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &mip); + rs.DrawFBO.name, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &mip); GLenum fmt = eGL_DEPTH32F_STENCIL8; @@ -3148,7 +3149,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOve if(overlay == DebugOverlay::QuadOverdrawPass) ReplayLog(events[0], eReplay_WithoutDraw); else - rs.ApplyState(m_pDriver->GetCtx(), m_pDriver); + rs.ApplyState(m_pDriver); for(size_t i = 0; i < events.size(); i++) { @@ -3295,7 +3296,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOve "types"); } - rs.ApplyState(m_pDriver->GetCtx(), m_pDriver); + rs.ApplyState(m_pDriver); return m_pDriver->GetResourceManager()->GetID(TextureRes(ctx, DebugData.overlayTex)); } @@ -3307,18 +3308,16 @@ void GLReplay::InitPostVSBuffers(uint32_t eventID) MakeCurrentReplayContext(&m_ReplayCtx); - void *ctx = m_ReplayCtx.ctx; - WrappedOpenGL &gl = *m_pDriver; if(gl.m_ActiveFeedback) gl.glEndTransformFeedback(); GLResourceManager *rm = m_pDriver->GetResourceManager(); - GLRenderState rs(&gl.GetHookset(), NULL, READING); - rs.FetchState(ctx, &gl); + GLRenderState rs(&gl.GetHookset()); + rs.FetchState(&gl); GLuint elArrayBuffer = 0; - if(rs.VAO) + if(rs.VAO.name) gl.glGetIntegerv(eGL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint *)&elArrayBuffer); // reflection structures @@ -3341,15 +3340,15 @@ void GLReplay::InitPostVSBuffers(uint32_t eventID) GLuint tesProgSrc = 0; GLuint gsProgSrc = 0; - if(rs.Program == 0) + if(rs.Program.name == 0) { - if(rs.Pipeline == 0) + if(rs.Pipeline.name == 0) { return; } else { - ResourceId id = rm->GetID(ProgramPipeRes(ctx, rs.Pipeline)); + ResourceId id = rm->GetID(rs.Pipeline); auto &pipeDetails = m_pDriver->m_Pipelines[id]; if(pipeDetails.stageShaders[0] != ResourceId()) @@ -3379,7 +3378,7 @@ void GLReplay::InitPostVSBuffers(uint32_t eventID) } else { - auto &progDetails = m_pDriver->m_Programs[rm->GetID(ProgramRes(ctx, rs.Program))]; + auto &progDetails = m_pDriver->m_Programs[rm->GetID(rs.Program)]; if(progDetails.stageShaders[0] != ResourceId()) { @@ -3401,7 +3400,7 @@ void GLReplay::InitPostVSBuffers(uint32_t eventID) gsProg = m_pDriver->m_Shaders[progDetails.stageShaders[3]].prog; } - vsProgSrc = tcsProgSrc = tesProgSrc = gsProgSrc = rs.Program; + vsProgSrc = tcsProgSrc = tesProgSrc = gsProgSrc = rs.Program.name; } if(vsRefl == NULL) @@ -3878,13 +3877,13 @@ void GLReplay::InitPostVSBuffers(uint32_t eventID) gl.glDeleteProgramPipelines(1, &vsFeedbackPipe); // restore replay state we trashed - gl.glUseProgram(rs.Program); - gl.glBindProgramPipeline(rs.Pipeline); + gl.glUseProgram(rs.Program.name); + gl.glBindProgramPipeline(rs.Pipeline.name); - gl.glBindBuffer(eGL_ARRAY_BUFFER, rs.BufferBindings[GLRenderState::eBufIdx_Array]); + gl.glBindBuffer(eGL_ARRAY_BUFFER, rs.BufferBindings[GLRenderState::eBufIdx_Array].name); gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, elArrayBuffer); - gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, rs.FeedbackObj); + gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, rs.FeedbackObj.name); if(!rs.Enabled[GLRenderState::eEnabled_RasterizerDiscard]) gl.glDisable(eGL_RASTERIZER_DISCARD); @@ -4486,13 +4485,13 @@ void GLReplay::InitPostVSBuffers(uint32_t eventID) gl.glDeleteProgramPipelines(1, &lastFeedbackPipe); // restore replay state we trashed - gl.glUseProgram(rs.Program); - gl.glBindProgramPipeline(rs.Pipeline); + gl.glUseProgram(rs.Program.name); + gl.glBindProgramPipeline(rs.Pipeline.name); - gl.glBindBuffer(eGL_ARRAY_BUFFER, rs.BufferBindings[GLRenderState::eBufIdx_Array]); + gl.glBindBuffer(eGL_ARRAY_BUFFER, rs.BufferBindings[GLRenderState::eBufIdx_Array].name); gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, elArrayBuffer); - gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, rs.FeedbackObj); + gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, rs.FeedbackObj.name); if(!rs.Enabled[GLRenderState::eEnabled_RasterizerDiscard]) gl.glDisable(eGL_RASTERIZER_DISCARD); @@ -4627,13 +4626,13 @@ void GLReplay::InitPostVSBuffers(uint32_t eventID) gl.glDeleteProgramPipelines(1, &lastFeedbackPipe); // restore replay state we trashed - gl.glUseProgram(rs.Program); - gl.glBindProgramPipeline(rs.Pipeline); + gl.glUseProgram(rs.Program.name); + gl.glBindProgramPipeline(rs.Pipeline.name); - gl.glBindBuffer(eGL_ARRAY_BUFFER, rs.BufferBindings[GLRenderState::eBufIdx_Array]); + gl.glBindBuffer(eGL_ARRAY_BUFFER, rs.BufferBindings[GLRenderState::eBufIdx_Array].name); gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, elArrayBuffer); - gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, rs.FeedbackObj); + gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, rs.FeedbackObj.name); if(!rs.Enabled[GLRenderState::eEnabled_RasterizerDiscard]) gl.glDisable(eGL_RASTERIZER_DISCARD); diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 025f7e924..7040f05aa 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -26,6 +26,7 @@ #include "gl_replay.h" #include "driver/ihv/amd/amd_isa.h" #include "maths/matrix.h" +#include "serialise/rdcfile.h" #include "strings/string_utils.h" #include "gl_driver.h" #include "gl_resources.h" @@ -72,12 +73,10 @@ void GLReplay::Shutdown() GLReplay::PostContextShutdownCounters(); } -#pragma region Implemented - -void GLReplay::ReadLogInitialisation() +void GLReplay::ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers) { MakeCurrentReplayContext(&m_ReplayCtx); - m_pDriver->ReadLogInitialisation(); + m_pDriver->ReadLogInitialisation(rdc, storeStructuredBuffers); } void GLReplay::ReplayLog(uint32_t endEventID, ReplayLogType replayType) @@ -86,6 +85,11 @@ void GLReplay::ReplayLog(uint32_t endEventID, ReplayLogType replayType) m_pDriver->ReplayLog(0, endEventID, replayType); } +const SDFile &GLReplay::GetStructuredFile() +{ + return m_pDriver->GetStructuredFile(); +} + vector GLReplay::GetPassEvents(uint32_t eventID) { vector passEvents; @@ -190,21 +194,6 @@ void GLReplay::SetReplayData(GLWindowingData data) PostContextInitCounters(); } -void GLReplay::InitCallstackResolver() -{ - m_pDriver->GetSerialiser()->InitCallstackResolver(); -} - -bool GLReplay::HasCallstacks() -{ - return m_pDriver->GetSerialiser()->HasCallstacks(); -} - -Callstack::StackResolver *GLReplay::GetCallstackResolver() -{ - return m_pDriver->GetSerialiser()->GetCallstackResolver(); -} - void GLReplay::CreateOutputWindowBackbuffer(OutputWindow &outwin, bool depth) { if(m_pDriver == NULL) @@ -880,8 +869,8 @@ void GLReplay::SavePipelineState() MakeCurrentReplayContext(&m_ReplayCtx); - GLRenderState rs(&gl.GetHookset(), NULL, READING); - rs.FetchState(m_ReplayCtx.ctx, &gl); + GLRenderState rs(&gl.GetHookset()); + rs.FetchState(&gl); // Index buffer @@ -1488,15 +1477,14 @@ void GLReplay::SavePipelineState() pipe.UniformBuffers.resize(ARRAY_COUNT(rs.UniformBinding)); for(size_t b = 0; b < pipe.UniformBuffers.size(); b++) { - if(rs.UniformBinding[b].name == 0) + if(rs.UniformBinding[b].res.name == 0) { pipe.UniformBuffers[b].Resource = ResourceId(); pipe.UniformBuffers[b].Offset = pipe.UniformBuffers[b].Size = 0; } else { - pipe.UniformBuffers[b].Resource = - rm->GetOriginalID(rm->GetID(BufferRes(ctx, rs.UniformBinding[b].name))); + pipe.UniformBuffers[b].Resource = rm->GetOriginalID(rm->GetID(rs.UniformBinding[b].res)); pipe.UniformBuffers[b].Offset = rs.UniformBinding[b].start; pipe.UniformBuffers[b].Size = rs.UniformBinding[b].size; } @@ -1505,15 +1493,14 @@ void GLReplay::SavePipelineState() pipe.AtomicBuffers.resize(ARRAY_COUNT(rs.AtomicCounter)); for(size_t b = 0; b < pipe.AtomicBuffers.size(); b++) { - if(rs.AtomicCounter[b].name == 0) + if(rs.AtomicCounter[b].res.name == 0) { pipe.AtomicBuffers[b].Resource = ResourceId(); pipe.AtomicBuffers[b].Offset = pipe.AtomicBuffers[b].Size = 0; } else { - pipe.AtomicBuffers[b].Resource = - rm->GetOriginalID(rm->GetID(BufferRes(ctx, rs.AtomicCounter[b].name))); + pipe.AtomicBuffers[b].Resource = rm->GetOriginalID(rm->GetID(rs.AtomicCounter[b].res)); pipe.AtomicBuffers[b].Offset = rs.AtomicCounter[b].start; pipe.AtomicBuffers[b].Size = rs.AtomicCounter[b].size; } @@ -1522,15 +1509,14 @@ void GLReplay::SavePipelineState() pipe.ShaderStorageBuffers.resize(ARRAY_COUNT(rs.ShaderStorage)); for(size_t b = 0; b < pipe.ShaderStorageBuffers.size(); b++) { - if(rs.ShaderStorage[b].name == 0) + if(rs.ShaderStorage[b].res.name == 0) { pipe.ShaderStorageBuffers[b].Resource = ResourceId(); pipe.ShaderStorageBuffers[b].Offset = pipe.ShaderStorageBuffers[b].Size = 0; } else { - pipe.ShaderStorageBuffers[b].Resource = - rm->GetOriginalID(rm->GetID(BufferRes(ctx, rs.ShaderStorage[b].name))); + pipe.ShaderStorageBuffers[b].Resource = rm->GetOriginalID(rm->GetID(rs.ShaderStorage[b].res)); pipe.ShaderStorageBuffers[b].Offset = rs.ShaderStorage[b].start; pipe.ShaderStorageBuffers[b].Size = rs.ShaderStorage[b].size; } @@ -1539,13 +1525,13 @@ void GLReplay::SavePipelineState() pipe.Images.resize(ARRAY_COUNT(rs.Images)); for(size_t i = 0; i < pipe.Images.size(); i++) { - if(rs.Images[i].name == 0) + if(rs.Images[i].res.name == 0) { RDCEraseEl(pipe.Images[i]); } else { - ResourceId id = rm->GetID(TextureRes(ctx, rs.Images[i].name)); + ResourceId id = rm->GetID(rs.Images[i].res); pipe.Images[i].Resource = rm->GetOriginalID(id); pipe.Images[i].Level = rs.Images[i].level; pipe.Images[i].Layered = rs.Images[i].layered; @@ -2191,12 +2177,12 @@ void GLReplay::FillCBufferVariables(ResourceId shader, string entryPoint, uint32 outvars, data); } -byte *GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, - const GetTextureDataParams ¶ms, size_t &dataSize) +void GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + const GetTextureDataParams ¶ms, bytebuf &data) { WrappedOpenGL &gl = *m_pDriver; - auto &texDetails = m_pDriver->m_Textures[tex]; + WrappedOpenGL::TextureData &texDetails = m_pDriver->m_Textures[tex]; byte *ret = NULL; @@ -2214,8 +2200,7 @@ byte *GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, if(texType == eGL_NONE) { RDCERR("Trying to get texture data for unknown ID %llu!", tex); - dataSize = 0; - return new byte[0]; + return; } if(texType == eGL_TEXTURE_BUFFER) @@ -2230,14 +2215,13 @@ byte *GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, (GLint *)&offs); gl.glGetTextureLevelParameterivEXT(texname, texType, 0, eGL_TEXTURE_BUFFER_SIZE, (GLint *)&size); - vector data; - GetBufferData(id, offs, size, data); + // TODO optimise this copy + vector bufdata; + GetBufferData(id, offs, size, bufdata); - dataSize = data.size(); - ret = new byte[dataSize]; - memcpy(ret, &data[0], dataSize); + data = bufdata; - return ret; + return; } if(texType == eGL_TEXTURE_2D_ARRAY || texType == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY || @@ -2249,14 +2233,14 @@ byte *GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, arraysize = texDetails.depth; } - if(params.remap) + if(params.remap != RemapTexture::NoRemap) { GLenum remapFormat = eGL_RGBA8; - if(params.remap == eRemap_RGBA8) + if(params.remap == RemapTexture::RGBA8) remapFormat = eGL_RGBA8; - else if(params.remap == eRemap_RGBA16) + else if(params.remap == RemapTexture::RGBA16) remapFormat = eGL_RGBA16F; - else if(params.remap == eRemap_RGBA32) + else if(params.remap == RemapTexture::RGBA32) remapFormat = eGL_RGBA32F; if(intFormat != remapFormat) @@ -2545,12 +2529,14 @@ byte *GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, target = targets[arrayIdx]; } + size_t dataSize = 0; + if(IsCompressedFormat(intFormat)) { dataSize = (size_t)GetCompressedByteSize(width, height, depth, intFormat); // contains a single slice - ret = new byte[dataSize]; + data.resize(dataSize); // Note that for array textures we fetch the whole mip level (all slices at that mip). Since // GL returns all slices together, we cache it and keep the data around. This is because in @@ -2593,7 +2579,7 @@ byte *GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, byte *src = m_GetTexturePrevData[mip]; src += dataSize * arrayIdx; - memcpy(ret, src, dataSize); + memcpy(data.data(), src, dataSize); } else { @@ -2611,7 +2597,7 @@ byte *GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, size_t rowSize = GetByteSize(width, 1, 1, fmt, type); dataSize = GetByteSize(width, height, depth, fmt, type); - ret = new byte[dataSize]; + data.resize(dataSize); // see above for the logic of handling arrays if(arraysize > 1) @@ -2640,7 +2626,7 @@ byte *GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, byte *src = m_GetTexturePrevData[mip]; src += dataSize * arrayIdx; - memcpy(ret, src, dataSize); + memcpy(data.data(), src, dataSize); } else { @@ -2668,7 +2654,7 @@ byte *GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, // invert all slices in a 3D texture for(GLsizei d = 0; d < depth; d++) { - dst = ret + d * sliceSize; + dst = data.data() + d * sliceSize; src = dst + (height - 1) * rowSize; for(GLsizei i = 0; i> 1; i++) @@ -2693,8 +2679,6 @@ byte *GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, if(tempTex) gl.glDeleteTextures(1, &tempTex); - - return ret; } void GLReplay::BuildCustomShader(string source, string entry, const ShaderCompileFlags &compileFlags, @@ -3270,8 +3254,6 @@ vector GLReplay::GetUsage(ResourceId id) return m_pDriver->GetUsage(id); } -#pragma endregion - vector GLReplay::PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx, CompType typeHint) @@ -3378,10 +3360,46 @@ bool GLReplay::IsOutputWindowVisible(uint64_t id) return m_pDriver->m_Platform.IsOutputWindowVisible(m_OutputWindows[id]); } +class GLDummyPlatform : public GLPlatform +{ + virtual GLWindowingData MakeContext(GLWindowingData share) { return GLWindowingData(); } + virtual void DeleteContext(GLWindowingData context) {} + virtual void DeleteReplayContext(GLWindowingData context) {} + virtual void MakeContextCurrent(GLWindowingData data) {} + virtual void SwapBuffers(GLWindowingData context) {} + virtual void GetOutputWindowDimensions(GLWindowingData context, int32_t &w, int32_t &h) {} + virtual bool IsOutputWindowVisible(GLWindowingData context) { return false; } + virtual GLWindowingData MakeOutputWindow(WindowingSystem system, void *data, bool depth, + GLWindowingData share_context) + { + return GLWindowingData(); + } + virtual bool DrawQuads(float width, float height, const std::vector &vertices) + { + return false; + } +}; + +void GL_ProcessStructured(RDCFile *rdc, SDFile &output) +{ + GLHookSet empty = {}; + GLDummyPlatform dummy; + WrappedOpenGL device(empty, dummy); + + device.SetStructuredExport( + rdc->GetSectionProperties(rdc->SectionIndex(SectionType::FrameCapture)).version); + device.ReadLogInitialisation(rdc, true); + + device.GetStructuredFile().swap(output); +} + +static StructuredProcessRegistration GLProcessRegistration(RDC_OpenGL, &GL_ProcessStructured); +static StructuredProcessRegistration GLESProcessRegistration(RDC_OpenGLES, &GL_ProcessStructured); + #if defined(RENDERDOC_SUPPORT_GL) // defined in gl_replay_.cpp -ReplayStatus GL_CreateReplayDevice(const char *logfile, IReplayDriver **driver); +ReplayStatus GL_CreateReplayDevice(RDCFile *rdc, IReplayDriver **driver); static DriverRegistration GLDriverRegistration(RDC_OpenGL, "OpenGL", &GL_CreateReplayDevice); @@ -3390,7 +3408,8 @@ static DriverRegistration GLDriverRegistration(RDC_OpenGL, "OpenGL", &GL_CreateR #if defined(RENDERDOC_SUPPORT_GLES) // defined in gl_replay_egl.cpp -ReplayStatus GLES_CreateReplayDevice(const char *logfile, IReplayDriver **driver); +ReplayStatus GLES_CreateReplayDevice(RDCFile *rdc, IReplayDriver **driver); +void GLES_ProcessStructured(RDCFile *rdc, SDFile &output); static DriverRegistration GLESDriverRegistration(RDC_OpenGLES, "OpenGLES", &GLES_CreateReplayDevice); diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index 5e116fba1..eea323845 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -116,8 +116,9 @@ public: const VKPipe::State &GetVulkanPipelineState() { return m_VKState; } void FreeTargetResource(ResourceId id); - void ReadLogInitialisation(); + void ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers); void ReplayLog(uint32_t endEventID, ReplayLogType replayType); + const SDFile &GetStructuredFile(); vector GetPassEvents(uint32_t eventID); @@ -157,14 +158,14 @@ public: MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &ret); - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, - const GetTextureDataParams ¶ms, size_t &dataSize); + void GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + const GetTextureDataParams ¶ms, bytebuf &data); void ReplaceResource(ResourceId from, ResourceId to); void RemoveReplacement(ResourceId id); vector EnumerateCounters(); - void DescribeCounter(GPUCounter counterID, CounterDescription &desc); + CounterDescription DescribeCounter(GPUCounter counterID); vector FetchCounters(const vector &counters); void RenderMesh(uint32_t eventID, const vector &secondaryDraws, const MeshDisplay &cfg); @@ -221,10 +222,6 @@ public: bool IsRenderOutput(ResourceId id); void FileChanged() {} - void InitCallstackResolver(); - bool HasCallstacks(); - Callstack::StackResolver *GetCallstackResolver(); - // called before any context is created, to init any counters static void PreContextInitCounters(); // called after any context is destroyed, to do corresponding shutdown of counters