Try to clear the depth buffer for the ClearBeforePass/Draw overlays

This functionality can be very valuable when debugging shadow map
rendering, for example. Because the correct value to clear to might not
be known, the depth function is checked to see what to clear to. If the
depth function is equal, not equal, or always, depth is not cleared, to
avoid producing incorrect (and not useful) results.
This commit is contained in:
Steve Karolewics
2019-12-18 23:02:32 -08:00
committed by Baldur Karlsson
parent e46837b332
commit 36906d9edf
4 changed files with 104 additions and 0 deletions
+32
View File
@@ -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);
+28
View File
@@ -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<WrappedID3D12PipelineState>(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;
+18
View File
@@ -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);
+26
View File
@@ -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,
};