Quantise pixel history depth when doing per-fragment comparisons

This commit is contained in:
baldurk
2020-07-17 16:49:59 +01:00
parent 7a885ae9bd
commit 05e2761fb8
2 changed files with 43 additions and 12 deletions
+24 -6
View File
@@ -641,6 +641,7 @@ rdcarray<PixelModification> D3D11Replay::PixelHistory(rdcarray<EventUsage> event
// bother checking if depth testing failed if the depth test was disabled
rdcarray<uint32_t> flags(events.size());
std::map<uint32_t, D3D11_COMPARISON_FUNC> depthOps;
std::map<uint32_t, DXGI_FORMAT> depthFormats;
enum
{
TestEnabled_BackfaceCulling = 1 << 0,
@@ -1093,6 +1094,8 @@ rdcarray<PixelModification> D3D11Replay::PixelHistory(rdcarray<EventUsage> event
RDCERR("Unexpected size of depth buffer");
}
depthFormats[events[ev].eventId] = desc2d.Format;
bool srvable = (dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) &&
(desc2d.BindFlags & D3D11_BIND_SHADER_RESOURCE) > 0;
@@ -2440,19 +2443,34 @@ rdcarray<PixelModification> D3D11Replay::PixelHistory(rdcarray<EventUsage> event
// values, as we don't have per-fragment depth test information.
if(history[h].preMod.depth >= 0.0f && history[h].shaderOut.depth >= 0.0f)
{
DXGI_FORMAT dfmt = depthFormats[history[h].eventId];
float shadDepth = history[h].shaderOut.depth;
// quantise depth to match before comparing
if(dfmt == DXGI_FORMAT_D24_UNORM_S8_UINT || dfmt == DXGI_FORMAT_X24_TYPELESS_G8_UINT ||
dfmt == DXGI_FORMAT_R24_UNORM_X8_TYPELESS || dfmt == DXGI_FORMAT_R24G8_TYPELESS)
{
shadDepth = float(uint32_t(float(shadDepth * 0xffffff))) / float(0xffffff);
}
else if(dfmt == DXGI_FORMAT_D16_UNORM || dfmt == DXGI_FORMAT_R16_TYPELESS ||
dfmt == DXGI_FORMAT_R16_UNORM)
{
shadDepth = float(uint32_t(float(shadDepth * 0xffff))) / float(0xffff);
}
bool passed = true;
if(depthOps[history[h].eventId] == D3D11_COMPARISON_EQUAL)
passed = (history[h].shaderOut.depth == history[h].preMod.depth);
passed = (shadDepth == history[h].preMod.depth);
else if(depthOps[history[h].eventId] == D3D11_COMPARISON_NOT_EQUAL)
passed = (history[h].shaderOut.depth != history[h].preMod.depth);
passed = (shadDepth != history[h].preMod.depth);
else if(depthOps[history[h].eventId] == D3D11_COMPARISON_LESS)
passed = (history[h].shaderOut.depth < history[h].preMod.depth);
passed = (shadDepth < history[h].preMod.depth);
else if(depthOps[history[h].eventId] == D3D11_COMPARISON_LESS_EQUAL)
passed = (history[h].shaderOut.depth <= history[h].preMod.depth);
passed = (shadDepth <= history[h].preMod.depth);
else if(depthOps[history[h].eventId] == D3D11_COMPARISON_GREATER)
passed = (history[h].shaderOut.depth > history[h].preMod.depth);
passed = (shadDepth > history[h].preMod.depth);
else if(depthOps[history[h].eventId] == D3D11_COMPARISON_GREATER_EQUAL)
passed = (history[h].shaderOut.depth >= history[h].preMod.depth);
passed = (shadDepth >= history[h].preMod.depth);
history[h].depthTestFailed = !passed;
}
+19 -6
View File
@@ -3541,19 +3541,32 @@ rdcarray<PixelModification> VulkanReplay::PixelHistory(rdcarray<EventUsage> even
flags &= 0x7 << DepthTest_Shift;
VkFormat dfmt = cb.GetDepthFormat(eid);
float shadDepth = history[h].shaderOut.depth;
// quantise depth to match before comparing
if(dfmt == VK_FORMAT_D24_UNORM_S8_UINT || dfmt == VK_FORMAT_X8_D24_UNORM_PACK32)
{
shadDepth = float(uint32_t(float(shadDepth * 0xffffff))) / float(0xffffff);
}
else if(dfmt == VK_FORMAT_D16_UNORM || dfmt == VK_FORMAT_D16_UNORM_S8_UINT)
{
shadDepth = float(uint32_t(float(shadDepth * 0xffff))) / float(0xffff);
}
bool passed = true;
if(flags == DepthTest_Equal)
passed = (history[h].shaderOut.depth == history[h].preMod.depth);
passed = (shadDepth == history[h].preMod.depth);
else if(flags == DepthTest_NotEqual)
passed = (history[h].shaderOut.depth != history[h].preMod.depth);
passed = (shadDepth != history[h].preMod.depth);
else if(flags == DepthTest_Less)
passed = (history[h].shaderOut.depth < history[h].preMod.depth);
passed = (shadDepth < history[h].preMod.depth);
else if(flags == DepthTest_LessEqual)
passed = (history[h].shaderOut.depth <= history[h].preMod.depth);
passed = (shadDepth <= history[h].preMod.depth);
else if(flags == DepthTest_Greater)
passed = (history[h].shaderOut.depth > history[h].preMod.depth);
passed = (shadDepth > history[h].preMod.depth);
else if(flags == DepthTest_GreaterEqual)
passed = (history[h].shaderOut.depth >= history[h].preMod.depth);
passed = (shadDepth >= history[h].preMod.depth);
history[h].depthTestFailed = !passed;
}