diff --git a/qrenderdoc/Windows/PixelHistoryView.cpp b/qrenderdoc/Windows/PixelHistoryView.cpp index fa9c5922e..6ef3d5fa7 100644 --- a/qrenderdoc/Windows/PixelHistoryView.cpp +++ b/qrenderdoc/Windows/PixelHistoryView.cpp @@ -281,7 +281,7 @@ public: if(mod.primitiveID == ~0U) ret = tr("Unknown primitive\n"); - if(mod.shaderDiscarded) + if(!mod.Passed()) ret += failureString(mod); return ret; @@ -365,7 +365,7 @@ public: } else { - if(getMod(index).shaderDiscarded) + if(!getMod(index).Passed()) return QBrush(QColor::fromRgb(255, 235, 235)); } } @@ -382,7 +382,7 @@ public: } else { - if(getMod(index).shaderDiscarded) + if(!getMod(index).Passed()) return QBrush(textColor); } } diff --git a/renderdoc/driver/d3d11/d3d11_pixelhistory.cpp b/renderdoc/driver/d3d11/d3d11_pixelhistory.cpp index 28c167a10..bb5461f8e 100644 --- a/renderdoc/driver/d3d11/d3d11_pixelhistory.cpp +++ b/renderdoc/driver/d3d11/d3d11_pixelhistory.cpp @@ -640,6 +640,7 @@ rdcarray D3D11Replay::PixelHistory(rdcarray event // while issuing the above queries we can check to see which tests are enabled so we don't // bother checking if depth testing failed if the depth test was disabled rdcarray flags(events.size()); + std::map depthOps; enum { TestEnabled_BackfaceCulling = 1 << 0, @@ -894,6 +895,8 @@ rdcarray D3D11Replay::PixelHistory(rdcarray event flags[ev] |= (TestEnabled_BackfaceCulling | TestEnabled_DepthClip); } + D3D11_COMPARISON_FUNC depthOp = D3D11_COMPARISON_LESS; + if(curDS) { D3D11_DEPTH_STENCIL_DESC dsDesc; @@ -906,6 +909,12 @@ rdcarray D3D11Replay::PixelHistory(rdcarray event if(dsDesc.DepthFunc == D3D11_COMPARISON_NEVER) flags[ev] |= TestMustFail_DepthTesting; + + depthOp = dsDesc.DepthFunc; + } + else + { + depthOp = D3D11_COMPARISON_ALWAYS; } if(dsDesc.StencilEnable) @@ -933,6 +942,8 @@ rdcarray D3D11Replay::PixelHistory(rdcarray event flags[ev] |= TestEnabled_DepthTesting; } + depthOps[events[ev].eventId] = depthOp; + if(rsDesc.ScissorEnable) { // see if we can find at least one scissor region this pixel could fall into @@ -2424,6 +2435,27 @@ rdcarray D3D11Replay::PixelHistory(rdcarray event shadColSlot++; depthSlot++; } + + // check the depth value between premod/shaderout against the known test if we have valid depth + // values, as we don't have per-fragment depth test information. + if(history[h].preMod.depth >= 0.0f && history[h].shaderOut.depth >= 0.0f) + { + bool passed = true; + if(depthOps[history[h].eventId] == D3D11_COMPARISON_EQUAL) + passed = (history[h].shaderOut.depth == history[h].preMod.depth); + else if(depthOps[history[h].eventId] == D3D11_COMPARISON_NOT_EQUAL) + passed = (history[h].shaderOut.depth != history[h].preMod.depth); + else if(depthOps[history[h].eventId] == D3D11_COMPARISON_LESS) + passed = (history[h].shaderOut.depth < history[h].preMod.depth); + else if(depthOps[history[h].eventId] == D3D11_COMPARISON_LESS_EQUAL) + passed = (history[h].shaderOut.depth <= history[h].preMod.depth); + else if(depthOps[history[h].eventId] == D3D11_COMPARISON_GREATER) + passed = (history[h].shaderOut.depth > history[h].preMod.depth); + else if(depthOps[history[h].eventId] == D3D11_COMPARISON_GREATER_EQUAL) + passed = (history[h].shaderOut.depth >= history[h].preMod.depth); + + history[h].depthTestFailed = !passed; + } } m_pImmediateContext->Unmap(shadoutStoreReadback, 0); diff --git a/renderdoc/driver/vulkan/vk_pixelhistory.cpp b/renderdoc/driver/vulkan/vk_pixelhistory.cpp index e908edd32..05b4565f8 100644 --- a/renderdoc/driver/vulkan/vk_pixelhistory.cpp +++ b/renderdoc/driver/vulkan/vk_pixelhistory.cpp @@ -115,7 +115,7 @@ bool isDirectWrite(ResourceUsage usage) usage == ResourceUsage::GenMips); } -enum +enum : uint32_t { TestEnabled_Culling = 1 << 0, TestEnabled_Scissor = 1 << 1, @@ -133,6 +133,16 @@ enum TestMustFail_DepthTesting = 1 << 12, TestMustFail_StencilTesting = 1 << 13, TestMustFail_SampleMask = 1 << 14, + + DepthTest_Shift = 29, + DepthTest_Always = 0U << DepthTest_Shift, + DepthTest_Never = 1U << DepthTest_Shift, + DepthTest_Equal = 2U << DepthTest_Shift, + DepthTest_NotEqual = 3U << DepthTest_Shift, + DepthTest_Less = 4U << DepthTest_Shift, + DepthTest_LessEqual = 5U << DepthTest_Shift, + DepthTest_Greater = 6U << DepthTest_Shift, + DepthTest_GreaterEqual = 7U << DepthTest_Shift, }; struct CopyPixelParams @@ -1718,6 +1728,7 @@ struct TestsFailedCallback : public VulkanPixelHistoryCallback { } void PreEndCommandBuffer(VkCommandBuffer cmd) {} + bool HasEventFlags(uint32_t eventId) { return m_EventFlags.find(eventId) != m_EventFlags.end(); } uint32_t GetEventFlags(uint32_t eventId) { auto it = m_EventFlags.find(eventId); @@ -1784,6 +1795,27 @@ private: flags |= TestEnabled_DepthTesting; if(pipestate.depthCompareOp == VK_COMPARE_OP_NEVER) flags |= TestMustFail_DepthTesting; + + if(pipestate.depthCompareOp == VK_COMPARE_OP_NEVER) + flags |= DepthTest_Never; + if(pipestate.depthCompareOp == VK_COMPARE_OP_LESS) + flags |= DepthTest_Less; + if(pipestate.depthCompareOp == VK_COMPARE_OP_EQUAL) + flags |= DepthTest_Equal; + if(pipestate.depthCompareOp == VK_COMPARE_OP_LESS_OR_EQUAL) + flags |= DepthTest_LessEqual; + if(pipestate.depthCompareOp == VK_COMPARE_OP_GREATER) + flags |= DepthTest_Greater; + if(pipestate.depthCompareOp == VK_COMPARE_OP_NOT_EQUAL) + flags |= DepthTest_NotEqual; + if(pipestate.depthCompareOp == VK_COMPARE_OP_GREATER_OR_EQUAL) + flags |= DepthTest_GreaterEqual; + if(pipestate.depthCompareOp == VK_COMPARE_OP_ALWAYS) + flags |= DepthTest_Always; + } + else + { + flags |= DepthTest_Always; } if(pipestate.stencilTestEnable) @@ -3270,8 +3302,6 @@ rdcarray VulkanReplay::PixelHistory(rdcarray even } } - SAFE_DELETE(tfCb); - // Try to read memory back EventInfo *eventsInfo; @@ -3450,9 +3480,37 @@ rdcarray VulkanReplay::PixelHistory(rdcarray even history[h].preMod = history[h - 1].postMod; } } + + // check the depth value between premod/shaderout against the known test if we have valid + // depth values, as we don't have per-fragment depth test information. + if(history[h].preMod.depth >= 0.0f && history[h].shaderOut.depth >= 0.0f && tfCb && + tfCb->HasEventFlags(history[h].eventId)) + { + uint32_t flags = tfCb->GetEventFlags(history[h].eventId); + + flags &= 0x7 << DepthTest_Shift; + + bool passed = true; + if(flags == DepthTest_Equal) + passed = (history[h].shaderOut.depth == history[h].preMod.depth); + else if(flags == DepthTest_NotEqual) + passed = (history[h].shaderOut.depth != history[h].preMod.depth); + else if(flags == DepthTest_Less) + passed = (history[h].shaderOut.depth < history[h].preMod.depth); + else if(flags == DepthTest_LessEqual) + passed = (history[h].shaderOut.depth <= history[h].preMod.depth); + else if(flags == DepthTest_Greater) + passed = (history[h].shaderOut.depth > history[h].preMod.depth); + else if(flags == DepthTest_GreaterEqual) + passed = (history[h].shaderOut.depth >= history[h].preMod.depth); + + history[h].depthTestFailed = !passed; + } } } + SAFE_DELETE(tfCb); + GetDebugManager()->PixelHistoryDestroyResources(resources); ObjDisp(dev)->DestroyQueryPool(Unwrap(dev), occlusionPool, NULL); delete shaderCache;