From 8b91c8540b4a36f21d90901c08ceb9ac1564d5bd Mon Sep 17 00:00:00 2001 From: baldurk Date: Sat, 17 Jan 2015 18:38:16 +0000 Subject: [PATCH] Pass through Read FBO, and handle Draw/Read Buffers indirection --- renderdoc/api/replay/gl_pipestate.h | 19 +++-- renderdoc/core/replay_proxy.cpp | 5 +- renderdoc/driver/gl/gl_replay.cpp | 79 ++++++++++++++++--- renderdocui/Code/CommonPipelineState.cs | 14 +++- renderdocui/Interop/GLPipelineState.cs | 22 ++++-- .../PipelineState/GLPipelineStateViewer.cs | 8 +- 6 files changed, 113 insertions(+), 34 deletions(-) diff --git a/renderdoc/api/replay/gl_pipestate.h b/renderdoc/api/replay/gl_pipestate.h index c99baba4c..4b69cfd27 100644 --- a/renderdoc/api/replay/gl_pipestate.h +++ b/renderdoc/api/replay/gl_pipestate.h @@ -213,15 +213,22 @@ struct GLPipelineState struct FrameBuffer { - FrameBuffer() : FBO(), Depth(), Stencil() {} - - ResourceId FBO; + FrameBuffer() : FramebufferSRGB(false), Dither(false) {} bool32 FramebufferSRGB; + bool32 Dither; - rdctype::array Color; - ResourceId Depth; - ResourceId Stencil; + struct FBO + { + FBO() : Obj(), Depth(), Stencil() {} + ResourceId Obj; + rdctype::array Color; + ResourceId Depth; + ResourceId Stencil; + + rdctype::array DrawBuffers; + int32_t ReadBuffer; + } m_DrawFBO, m_ReadFBO; struct BlendState { diff --git a/renderdoc/core/replay_proxy.cpp b/renderdoc/core/replay_proxy.cpp index 9c5ecdf7b..5fe03dee8 100644 --- a/renderdoc/core/replay_proxy.cpp +++ b/renderdoc/core/replay_proxy.cpp @@ -299,10 +299,7 @@ void Serialiser::Serialise(const char *name, GLPipelineState::VertexInput &el) template<> void Serialiser::Serialise(const char *name, GLPipelineState::FrameBuffer &el) { - Serialise("", el.FBO); - Serialise("", el.Color); - Serialise("", el.Depth); - Serialise("", el.Stencil); + Serialise("", el.FramebufferSRGB); } template<> diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 0ccb72899..f7a479520 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -327,14 +327,14 @@ vector GLReplay::GetBufferData(ResourceId buff, uint32_t offset, uint32_t bool GLReplay::IsRenderOutput(ResourceId id) { - for(int32_t i=0; i < m_CurPipelineState.m_FB.Color.count; i++) + for(int32_t i=0; i < m_CurPipelineState.m_FB.m_DrawFBO.Color.count; i++) { - if(m_CurPipelineState.m_FB.Color[i] == id) + if(m_CurPipelineState.m_FB.m_DrawFBO.Color[i] == id) return true; } - if(m_CurPipelineState.m_FB.Depth == id || - m_CurPipelineState.m_FB.Stencil == id) + if(m_CurPipelineState.m_FB.m_DrawFBO.Depth == id || + m_CurPipelineState.m_FB.m_DrawFBO.Stencil == id) return true; return false; @@ -1542,8 +1542,10 @@ void GLReplay::SavePipelineState() // Frame buffer - GLuint curFBO = 0; - gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&curFBO); + GLuint curDrawFBO = 0; + gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&curDrawFBO); + GLuint curReadFBO = 0; + gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint*)&curReadFBO); GLint numCols = 8; gl.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols); @@ -1558,7 +1560,8 @@ void GLReplay::SavePipelineState() RDCASSERT(numCols <= 32); // we should never bind the true default framebuffer - if the app did, we will have our fake bound - RDCASSERT(curFBO != 0); + RDCASSERT(curDrawFBO != 0); + RDCASSERT(curReadFBO != 0); { GLenum type = eGL_TEXTURE; @@ -1575,19 +1578,69 @@ void GLReplay::SavePipelineState() gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curStencil); gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); if(type == eGL_RENDERBUFFER) rbStencil = true; + + pipe.m_FB.m_DrawFBO.Obj = rm->GetOriginalID(rm->GetID(FramebufferRes(ctx, curDrawFBO))); + create_array_uninit(pipe.m_FB.m_DrawFBO.Color, numCols); + for(GLint i=0; i < numCols; i++) + pipe.m_FB.m_DrawFBO.Color[i] = rm->GetOriginalID(rm->GetID(rbCol[i] ? RenderbufferRes(ctx, curCol[i]) : TextureRes(ctx, curCol[i]))); + + pipe.m_FB.m_DrawFBO.Depth = rm->GetOriginalID(rm->GetID(rbDepth ? RenderbufferRes(ctx, curDepth) : TextureRes(ctx, curDepth))); + pipe.m_FB.m_DrawFBO.Stencil = rm->GetOriginalID(rm->GetID(rbStencil ? RenderbufferRes(ctx, curStencil) : TextureRes(ctx, curStencil))); + + create_array_uninit(pipe.m_FB.m_DrawFBO.DrawBuffers, numCols); + for(GLint i=0; i < numCols; i++) + { + GLenum b = eGL_NONE; + gl.glGetIntegerv(GLenum(eGL_DRAW_BUFFER0 + i), (GLint *)&b); + if(b >= eGL_COLOR_ATTACHMENT0 && b <= GLenum(eGL_COLOR_ATTACHMENT0+numCols)) + pipe.m_FB.m_DrawFBO.DrawBuffers[i] = b-eGL_COLOR_ATTACHMENT0; + else + pipe.m_FB.m_DrawFBO.DrawBuffers[i] = -1; + } + + pipe.m_FB.m_DrawFBO.ReadBuffer = -1; } - pipe.m_FB.FBO = rm->GetOriginalID(rm->GetID(FramebufferRes(ctx, curFBO))); - create_array_uninit(pipe.m_FB.Color, numCols); - for(GLint i=0; i < numCols; i++) - pipe.m_FB.Color[i] = rm->GetOriginalID(rm->GetID(rbCol[i] ? RenderbufferRes(ctx, curCol[i]) : TextureRes(ctx, curCol[i]))); + { + GLenum type = eGL_TEXTURE; + for(GLint i=0; i < numCols; i++) + { + gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curCol[i]); + gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + if(type == eGL_RENDERBUFFER) rbCol[i] = true; + } - pipe.m_FB.Depth = rm->GetOriginalID(rm->GetID(rbDepth ? RenderbufferRes(ctx, curDepth) : TextureRes(ctx, curDepth))); - pipe.m_FB.Stencil = rm->GetOriginalID(rm->GetID(rbStencil ? RenderbufferRes(ctx, curStencil) : TextureRes(ctx, curStencil))); + gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curDepth); + gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + if(type == eGL_RENDERBUFFER) rbDepth = true; + gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curStencil); + gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + if(type == eGL_RENDERBUFFER) rbStencil = true; + + pipe.m_FB.m_ReadFBO.Obj = rm->GetOriginalID(rm->GetID(FramebufferRes(ctx, curReadFBO))); + create_array_uninit(pipe.m_FB.m_ReadFBO.Color, numCols); + for(GLint i=0; i < numCols; i++) + pipe.m_FB.m_ReadFBO.Color[i] = rm->GetOriginalID(rm->GetID(rbCol[i] ? RenderbufferRes(ctx, curCol[i]) : TextureRes(ctx, curCol[i]))); + + pipe.m_FB.m_ReadFBO.Depth = rm->GetOriginalID(rm->GetID(rbDepth ? RenderbufferRes(ctx, curDepth) : TextureRes(ctx, curDepth))); + pipe.m_FB.m_ReadFBO.Stencil = rm->GetOriginalID(rm->GetID(rbStencil ? RenderbufferRes(ctx, curStencil) : TextureRes(ctx, curStencil))); + + create_array_uninit(pipe.m_FB.m_ReadFBO.DrawBuffers, numCols); + for(GLint i=0; i < numCols; i++) + pipe.m_FB.m_ReadFBO.DrawBuffers[i] = -1; + + GLenum b = eGL_NONE; + gl.glGetIntegerv(eGL_READ_BUFFER, (GLint *)&b); + if(b >= eGL_COLOR_ATTACHMENT0 && b <= GLenum(eGL_COLOR_ATTACHMENT0+numCols)) + pipe.m_FB.m_DrawFBO.ReadBuffer = b-eGL_COLOR_ATTACHMENT0; + else + pipe.m_FB.m_DrawFBO.ReadBuffer = -1; + } memcpy(pipe.m_FB.m_Blending.BlendFactor, rs.BlendColor, sizeof(rs.BlendColor)); pipe.m_FB.FramebufferSRGB = rs.Enabled[GLRenderState::eEnabled_FramebufferSRGB]; + pipe.m_FB.Dither = rs.Enabled[GLRenderState::eEnabled_Dither]; RDCCOMPILE_ASSERT(ARRAY_COUNT(rs.Blends) == ARRAY_COUNT(rs.ColorMasks), "Color masks and blends mismatched"); create_array_uninit(pipe.m_FB.m_Blending.Blends, ARRAY_COUNT(rs.Blends)); diff --git a/renderdocui/Code/CommonPipelineState.cs b/renderdocui/Code/CommonPipelineState.cs index ff19f84bd..cab4da32f 100644 --- a/renderdocui/Code/CommonPipelineState.cs +++ b/renderdocui/Code/CommonPipelineState.cs @@ -537,7 +537,15 @@ namespace renderdocui.Code } else if (IsLogGL) { - return m_GL.m_FB.Color; + ResourceId[] ret = new ResourceId[m_GL.m_FB.m_DrawFBO.DrawBuffers.Length]; + for(int i=0; i < m_GL.m_FB.m_DrawFBO.DrawBuffers.Length; i++) + { + int db = m_GL.m_FB.m_DrawFBO.DrawBuffers[i]; + if(db >= 0) + ret[i] = m_GL.m_FB.m_DrawFBO.Color[db]; + } + + return ret; } } @@ -554,7 +562,7 @@ namespace renderdocui.Code return m_D3D11.m_OM.DepthTarget.Resource; if (IsLogGL) - return m_GL.m_FB.Depth; + return m_GL.m_FB.m_DrawFBO.Depth; } return ResourceId.Null; @@ -571,7 +579,7 @@ namespace renderdocui.Code return m_D3D11.m_OM.DepthTarget.Resource; if (IsLogGL) - return m_GL.m_FB.Stencil; + return m_GL.m_FB.m_DrawFBO.Stencil; } return ResourceId.Null; diff --git a/renderdocui/Interop/GLPipelineState.cs b/renderdocui/Interop/GLPipelineState.cs index 7ef3c7cb5..d68cd82e2 100644 --- a/renderdocui/Interop/GLPipelineState.cs +++ b/renderdocui/Interop/GLPipelineState.cs @@ -241,14 +241,24 @@ namespace renderdoc [StructLayout(LayoutKind.Sequential)] public class FrameBuffer { - public ResourceId FBO; - public bool FramebufferSRGB; - [CustomMarshalAs(CustomUnmanagedType.TemplatedArray)] - public ResourceId[] Color; - public ResourceId Depth; - public ResourceId Stencil; + [StructLayout(LayoutKind.Sequential)] + public class FBO + { + public ResourceId Obj; + + [CustomMarshalAs(CustomUnmanagedType.TemplatedArray)] + public ResourceId[] Color; + public ResourceId Depth; + public ResourceId Stencil; + + [CustomMarshalAs(CustomUnmanagedType.TemplatedArray)] + public Int32[] DrawBuffers; + public Int32 ReadBuffer; + }; + [CustomMarshalAs(CustomUnmanagedType.CustomClass)] + public FBO m_DrawFBO, m_ReadFBO; [StructLayout(LayoutKind.Sequential)] public class BlendState diff --git a/renderdocui/Windows/PipelineState/GLPipelineStateViewer.cs b/renderdocui/Windows/PipelineState/GLPipelineStateViewer.cs index 0ec625073..750d65ccd 100644 --- a/renderdocui/Windows/PipelineState/GLPipelineStateViewer.cs +++ b/renderdocui/Windows/PipelineState/GLPipelineStateViewer.cs @@ -949,8 +949,12 @@ namespace renderdocui.Windows.PipelineState targetOutputs.Nodes.Clear(); { int i = 0; - foreach (var p in state.m_FB.Color) + foreach (var db in state.m_FB.m_DrawFBO.DrawBuffers) { + ResourceId p = ResourceId.Null; + + if (db >= 0) p = state.m_FB.m_DrawFBO.Color[db]; + if (p != ResourceId.Null || showEmpty.Checked) { UInt32 w = 1, h = 1, d = 1; @@ -1009,7 +1013,7 @@ namespace renderdocui.Windows.PipelineState { int i = 0; - foreach (ResourceId depthstencil in new ResourceId[] { state.m_FB.Depth, state.m_FB.Stencil }) + foreach (ResourceId depthstencil in new ResourceId[] { state.m_FB.m_DrawFBO.Depth, state.m_FB.m_DrawFBO.Stencil }) { if (depthstencil != ResourceId.Null || showEmpty.Checked) {