diff --git a/renderdoc/api/replay/replay_enums.h b/renderdoc/api/replay/replay_enums.h index e91cd663f..c6f2b4d9a 100644 --- a/renderdoc/api/replay/replay_enums.h +++ b/renderdoc/api/replay/replay_enums.h @@ -128,12 +128,14 @@ enum TextureDisplayOverlay eTexOverlay_None = 0, eTexOverlay_Drawcall, eTexOverlay_Wireframe, - eTexOverlay_DepthBoth, - eTexOverlay_StencilBoth, + eTexOverlay_Depth, + eTexOverlay_Stencil, eTexOverlay_BackfaceCull, eTexOverlay_ViewportScissor, eTexOverlay_NaN, eTexOverlay_Clipping, + eTexOverlay_ClearBeforePass, + eTexOverlay_ClearBeforeDraw, eTexOverlay_QuadOverdrawPass, eTexOverlay_QuadOverdrawDraw, }; diff --git a/renderdoc/driver/d3d11/d3d11_analyse.cpp b/renderdoc/driver/d3d11/d3d11_analyse.cpp index f3fc9a272..433cb749e 100644 --- a/renderdoc/driver/d3d11/d3d11_analyse.cpp +++ b/renderdoc/driver/d3d11/d3d11_analyse.cpp @@ -3292,6 +3292,40 @@ ResourceId D3D11DebugManager::RenderOverlay(ResourceId texid, TextureDisplayOver SAFE_RELEASE(os); SAFE_RELEASE(rs); } + else if(overlay == eTexOverlay_ClearBeforePass || overlay == eTexOverlay_ClearBeforeDraw) + { + vector events = passEvents; + + if(overlay == eTexOverlay_ClearBeforeDraw) + events.clear(); + + events.push_back(eventID); + + if(!events.empty()) + { + if(overlay == eTexOverlay_ClearBeforePass) + m_WrappedDevice->ReplayLog(frameID, 0, events[0], eReplay_WithoutDraw); + + D3D11RenderState *state = m_WrappedContext->GetCurrentPipelineState(); + + for(size_t i=0; i < ARRAY_COUNT(state->OM.RenderTargets); i++) + if(state->OM.RenderTargets[i]) + m_WrappedContext->ClearRenderTargetView(state->OM.RenderTargets[i], black); + + for(size_t i=0; i < events.size(); i++) + { + m_WrappedDevice->ReplayLog(frameID, events[i], events[i], eReplay_OnlyDraw); + + if(overlay == eTexOverlay_ClearBeforePass) + { + m_WrappedDevice->ReplayLog(frameID, events[i], events[i], eReplay_OnlyDraw); + + if(i+1 < events.size()) + m_WrappedDevice->ReplayLog(frameID, events[i], events[i+1], eReplay_WithoutDraw); + } + } + } + } else if(overlay == eTexOverlay_QuadOverdrawPass || overlay == eTexOverlay_QuadOverdrawDraw) { SCOPED_TIMER("Quad Overdraw"); @@ -3535,14 +3569,14 @@ ResourceId D3D11DebugManager::RenderOverlay(ResourceId texid, TextureDisplayOver if(!cur.StencilEnable) cur.StencilEnable = D3D11_COMPARISON_ALWAYS; - if(overlay == eTexOverlay_DepthBoth || - overlay == eTexOverlay_StencilBoth) + if(overlay == eTexOverlay_Depth || + overlay == eTexOverlay_Stencil) { ID3D11DepthStencilState *os = NULL; D3D11_DEPTH_STENCIL_DESC d = dsDesc; - if(overlay == eTexOverlay_DepthBoth) + if(overlay == eTexOverlay_Depth) { dsDesc.DepthEnable = d.DepthEnable = TRUE; dsDesc.StencilEnable = d.StencilEnable = FALSE; @@ -3578,7 +3612,7 @@ ResourceId D3D11DebugManager::RenderOverlay(ResourceId texid, TextureDisplayOver break; } } - else if(overlay == eTexOverlay_StencilBoth) + else if(overlay == eTexOverlay_Stencil) { dsDesc.DepthEnable = d.DepthEnable = FALSE; dsDesc.StencilEnable = d.StencilEnable = TRUE; @@ -3679,11 +3713,11 @@ ResourceId D3D11DebugManager::RenderOverlay(ResourceId texid, TextureDisplayOver d = dsDesc; - if(overlay == eTexOverlay_DepthBoth) + if(overlay == eTexOverlay_Depth) { d.DepthFunc = cur.DepthFunc; } - else if(overlay == eTexOverlay_StencilBoth) + else if(overlay == eTexOverlay_Stencil) { d.FrontFace = cur.FrontFace; d.BackFace = cur.BackFace; diff --git a/renderdoc/driver/gl/gl_debug.cpp b/renderdoc/driver/gl/gl_debug.cpp index 2adfbb8af..f6db2f596 100644 --- a/renderdoc/driver/gl/gl_debug.cpp +++ b/renderdoc/driver/gl/gl_debug.cpp @@ -1883,7 +1883,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overl gl.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4); } - else if(overlay == eTexOverlay_DepthBoth || overlay == eTexOverlay_StencilBoth) + else if(overlay == eTexOverlay_Depth || overlay == eTexOverlay_Stencil) { float black[] = { 0.0f, 0.0f, 0.0f, 0.0f }; gl.glClearBufferfv(eGL_COLOR, 0, black); @@ -1960,7 +1960,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overl float green[] = { 0.0f, 1.0f, 0.0f, 1.0f }; gl.glProgramUniform4fv(DebugData.genericFSProg, colLoc, 1, green); - if(overlay == eTexOverlay_DepthBoth) + if(overlay == eTexOverlay_Depth) { if(rs.Enabled[GLRenderState::eEnabled_DepthTest]) gl.glEnable(eGL_DEPTH_TEST); @@ -2025,6 +2025,38 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overl ReplayLog(frameID, 0, eventID, eReplay_OnlyDraw); } + else if(overlay == eTexOverlay_ClearBeforeDraw || overlay == eTexOverlay_ClearBeforePass) + { + vector events = passEvents; + + if(overlay == eTexOverlay_QuadOverdrawDraw) + events.clear(); + + events.push_back(eventID); + + if(!events.empty()) + { + if(overlay == eTexOverlay_ClearBeforePass) + ReplayLog(frameID, 0, events[0], eReplay_WithoutDraw); + + float black[] = { 0.0f, 0.0f, 0.0f, 0.0f }; + for(int i=0; i < 8; i++) + gl.glClearBufferfv(eGL_COLOR, i, black); + + for(size_t i=0; i < events.size(); i++) + { + ReplayLog(frameID, events[i], events[i], eReplay_OnlyDraw); + + if(overlay == eTexOverlay_ClearBeforePass) + { + ReplayLog(frameID, events[i], events[i], eReplay_OnlyDraw); + + if(i+1 < events.size()) + ReplayLog(frameID, events[i], events[i+1], eReplay_WithoutDraw); + } + } + } + } else if(overlay == eTexOverlay_QuadOverdrawDraw || overlay == eTexOverlay_QuadOverdrawPass) { if(DebugData.quadoverdraw420) diff --git a/renderdoc/replay/replay_output.cpp b/renderdoc/replay/replay_output.cpp index 395797d55..b0c2e9384 100644 --- a/renderdoc/replay/replay_output.cpp +++ b/renderdoc/replay/replay_output.cpp @@ -37,6 +37,7 @@ ReplayOutput::ReplayOutput(ReplayRenderer *parent, void *w) m_MainOutput.dirty = true; m_OverlayDirty = true; + m_ForceOverlayRefresh = false; m_pDevice = parent->GetDevice(); @@ -87,7 +88,17 @@ bool ReplayOutput::SetOutputConfig( const OutputConfig &o ) bool ReplayOutput::SetTextureDisplay(const TextureDisplay &o) { if(o.overlay != m_RenderData.texDisplay.overlay) + { + if(m_RenderData.texDisplay.overlay == eTexOverlay_ClearBeforeDraw || + m_RenderData.texDisplay.overlay == eTexOverlay_ClearBeforePass) + { + // by necessity these overlays modify the actual texture, not an + // independent overlay texture. So if we disable them, we must + // refresh the log. + m_ForceOverlayRefresh = true; + } m_OverlayDirty = true; + } m_RenderData.texDisplay = o; m_MainOutput.dirty = true; return true; @@ -513,6 +524,11 @@ void ReplayOutput::DisplayTex() m_pDevice->ReplayLog(m_FrameID, 0, m_EventID, eReplay_OnlyDraw); } } + else if(m_ForceOverlayRefresh) + { + m_ForceOverlayRefresh = false; + m_pDevice->ReplayLog(m_FrameID, 0, m_EventID, eReplay_Full); + } if(m_RenderData.texDisplay.CustomShader != ResourceId()) { diff --git a/renderdoc/replay/replay_renderer.h b/renderdoc/replay/replay_renderer.h index 6f88f3b6e..2a4ae1ef5 100644 --- a/renderdoc/replay/replay_renderer.h +++ b/renderdoc/replay/replay_renderer.h @@ -79,6 +79,7 @@ private: size_t m_ID; bool m_OverlayDirty; + bool m_ForceOverlayRefresh; IReplayDriver *m_pDevice; diff --git a/renderdocui/Interop/Enums.cs b/renderdocui/Interop/Enums.cs index df1c15910..8c9c0da65 100644 --- a/renderdocui/Interop/Enums.cs +++ b/renderdocui/Interop/Enums.cs @@ -130,12 +130,14 @@ namespace renderdoc None = 0, Drawcall, Wireframe, - DepthBoth, - StencilBoth, + Depth, + Stencil, BackfaceCull, ViewportScissor, NaN, Clipping, + ClearBeforePass, + ClearBeforeDraw, QuadOverdrawPass, QuadOverdrawDraw, }; diff --git a/renderdocui/Windows/TextureViewer.Designer.cs b/renderdocui/Windows/TextureViewer.Designer.cs index c32468bd0..c70605839 100644 --- a/renderdocui/Windows/TextureViewer.Designer.cs +++ b/renderdocui/Windows/TextureViewer.Designer.cs @@ -560,6 +560,8 @@ "Viewport/Scissor Region", "NaN/INF/-ve Display", "Clipping", + "Clear Before Pass", + "Clear Before Draw", "Quad Overdraw (Pass)", "Quad Overdraw (Draw)"}); this.overlay.Name = "overlay";