diff --git a/renderdoc/driver/d3d11/d3d11_overlay.cpp b/renderdoc/driver/d3d11/d3d11_overlay.cpp index 31c235e11..59c36c38d 100644 --- a/renderdoc/driver/d3d11/d3d11_overlay.cpp +++ b/renderdoc/driver/d3d11/d3d11_overlay.cpp @@ -609,6 +609,38 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float if(state.OM.RenderTargets[i]) m_pImmediateContext->ClearRenderTargetView(state.OM.RenderTargets[i], &clearCol.x); + // Try to clear depth as well, to help debug shadow rendering + if(state.OM.DepthView && IsDepthFormat(details.srvFormat)) + { + if(state.OM.DepthStencilState) + { + D3D11_DEPTH_STENCIL_DESC desc; + state.OM.DepthStencilState->GetDesc(&desc); + + // If the depth func is equal or not equal, don't clear at all since the output would be + // altered in an way that would cause replay to produce mostly incorrect results. + // Similarly, skip if the depth func is always, as we'd have a 50% chance of guessing the + // wrong clear value. + if(desc.DepthFunc != D3D11_COMPARISON_EQUAL && + desc.DepthFunc != D3D11_COMPARISON_NOT_EQUAL && + desc.DepthFunc != D3D11_COMPARISON_ALWAYS) + { + // If the depth func is less or less equal, clear to 1 instead of 0 + bool depthFuncLess = desc.DepthFunc == D3D11_COMPARISON_LESS || + desc.DepthFunc == D3D11_COMPARISON_LESS_EQUAL; + float depthClear = depthFuncLess ? 1.0f : 0.0f; + + m_pImmediateContext->ClearDepthStencilView(state.OM.DepthView, D3D11_CLEAR_DEPTH, + depthClear, 0); + } + } + else + { + // Without a depth stencil state set, the comparison func is D3D11_COMPARISON_LESS + m_pImmediateContext->ClearDepthStencilView(state.OM.DepthView, D3D11_CLEAR_DEPTH, 1.0f, 0); + } + } + for(size_t i = 0; i < events.size(); i++) { m_pDevice->ReplayLog(events[i], events[i], eReplay_OnlyDraw); diff --git a/renderdoc/driver/d3d12/d3d12_overlay.cpp b/renderdoc/driver/d3d12/d3d12_overlay.cpp index 55fb8831d..b3b4c3ab1 100644 --- a/renderdoc/driver/d3d12/d3d12_overlay.cpp +++ b/renderdoc/driver/d3d12/d3d12_overlay.cpp @@ -675,6 +675,34 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float &clearCol.x, 0, NULL); } + // Try to clear depth as well, to help debug shadow rendering + if(rs.dsv.GetResResourceId() != ResourceId() && IsDepthFormat(resourceDesc.Format)) + { + WrappedID3D12PipelineState *origPSO = + m_pDevice->GetResourceManager()->GetCurrentAs(rs.pipe); + if(origPSO && origPSO->IsGraphics()) + { + D3D12_COMPARISON_FUNC depthFunc = origPSO->graphics->DepthStencilState.DepthFunc; + + // If the depth func is equal or not equal, don't clear at all since the output would be + // altered in an way that would cause replay to produce mostly incorrect results. + // Similarly, skip if the depth func is always, as we'd have a 50% chance of guessing the + // wrong clear value. + if(depthFunc != D3D12_COMPARISON_FUNC_EQUAL && + depthFunc != D3D12_COMPARISON_FUNC_NOT_EQUAL && + depthFunc != D3D12_COMPARISON_FUNC_ALWAYS) + { + // If the depth func is less or less equal, clear to 1 instead of 0 + bool depthFuncLess = depthFunc == D3D12_COMPARISON_FUNC_LESS || + depthFunc == D3D12_COMPARISON_FUNC_LESS_EQUAL; + float depthClear = depthFuncLess ? 1.0f : 0.0f; + + Unwrap(list)->ClearDepthStencilView(Unwrap(GetDebugManager()->GetTempDescriptor(rs.dsv)), + D3D12_CLEAR_FLAG_DEPTH, depthClear, 0, 0, NULL); + } + } + } + list->Close(); list = NULL; diff --git a/renderdoc/driver/gl/gl_overlay.cpp b/renderdoc/driver/gl/gl_overlay.cpp index 28b4f3c9e..46c3f2ee3 100644 --- a/renderdoc/driver/gl/gl_overlay.cpp +++ b/renderdoc/driver/gl/gl_overlay.cpp @@ -935,6 +935,24 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec for(int i = 0; i < 8; i++) drv.glClearBufferfv(eGL_COLOR, i, &clearCol.x); + // Try to clear depth as well, to help debug shadow rendering + if(IsDepthStencilFormat(texDetails.internalFormat)) + { + // If the depth func is equal or not equal, don't clear at all since the output would be + // altered in an way that would cause replay to produce mostly incorrect results. + // Similarly, skip if the depth func is always, as we'd have a 50% chance of guessing the + // wrong clear value. + if(rs.DepthFunc != eGL_EQUAL && rs.DepthFunc != eGL_NOTEQUAL && rs.DepthFunc != eGL_ALWAYS) + { + // Don't use the render state's depth clear value, as this overlay should show as much + // information as possible. Instead, clear to the value that would cause the most depth + // writes to happen. + bool depthFuncLess = rs.DepthFunc == eGL_LESS || rs.DepthFunc == eGL_LEQUAL; + float depthClear = depthFuncLess ? 1.0f : 0.0f; + drv.glClearBufferfv(eGL_DEPTH, 0, &depthClear); + } + } + for(size_t i = 0; i < events.size(); i++) { m_pDriver->ReplayLog(events[i], events[i], eReplay_OnlyDraw); diff --git a/renderdoc/driver/vulkan/vk_overlay.cpp b/renderdoc/driver/vulkan/vk_overlay.cpp index 2585bf10f..16b8864c3 100644 --- a/renderdoc/driver/vulkan/vk_overlay.cpp +++ b/renderdoc/driver/vulkan/vk_overlay.cpp @@ -1635,6 +1635,32 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa atts.push_back(clearatt); } + // Try to clear depth as well, to help debug shadow rendering + if(m_pDriver->m_RenderState.graphics.pipeline != ResourceId() && + IsDepthOrStencilFormat(iminfo.format)) + { + const VulkanCreationInfo::Pipeline &p = + m_pDriver->m_CreationInfo.m_Pipeline[m_pDriver->m_RenderState.graphics.pipeline]; + + // If the depth func is equal or not equal, don't clear at all since the output would be + // altered in an way that would cause replay to produce mostly incorrect results. + // Similarly, skip if the depth func is always, as we'd have a 50% chance of guessing the + // wrong clear value. + if(p.depthCompareOp != VK_COMPARE_OP_EQUAL && p.depthCompareOp != VK_COMPARE_OP_NOT_EQUAL && + p.depthCompareOp != VK_COMPARE_OP_ALWAYS) + { + // If the depth func is less or less equal, clear to 1 instead of 0 + bool depthFuncLess = p.depthCompareOp == VK_COMPARE_OP_LESS || + p.depthCompareOp == VK_COMPARE_OP_LESS_OR_EQUAL; + float depthClear = depthFuncLess ? 1.0f : 0.0f; + + VkClearAttachment clearDepthAtt = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, {}}; + clearDepthAtt.clearValue.depthStencil.depth = depthClear; + + atts.push_back(clearDepthAtt); + } + } + VkClearRect rect = { {{0, 0}, {fb.width, fb.height}}, 0, 1, };