mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-21 05:05:44 +00:00
D3D11: Improve pixel history discarded fragments Closes #3040
Include the discarded offset when indexing to get the post mod data per fragment Do not include the discarded offset when indexing to get the primitive ID per fragment (primitive ID uses a replacement shader which is not affected by discards in the original shader) Store the post mod depth data in slot 1 of the depth output to make the indexing simpler to keep track of discarded fragments Set the post mod data for discarded fragments (excluding the final fragment) to be the known texture after (which starts as the pre mod data and is updated for non-discarded fragments).
This commit is contained in:
@@ -2152,18 +2152,17 @@ rdcarray<PixelModification> D3D11Replay::PixelHistory(rdcarray<EventUsage> event
|
||||
GetDebugManager()->PixelHistoryCopyPixel(colourCopyParams, postColSlot, 0);
|
||||
postColSlot++;
|
||||
|
||||
GetDebugManager()->PixelHistoryCopyPixel(depthCopyParams, depthSlot, 0);
|
||||
depthSlot++;
|
||||
GetDebugManager()->PixelHistoryCopyPixel(depthCopyParams, depthSlot, 1);
|
||||
}
|
||||
|
||||
m_pImmediateContext->OMSetDepthStencilState(m_PixelHistory.StencIncrEqDepthState,
|
||||
history[h].fragIndex);
|
||||
|
||||
m_pImmediateContext->ClearDepthStencilView(
|
||||
shaddepthOutputDSV, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, cleardepth, 0);
|
||||
|
||||
// fetch shader output value & primitive ID
|
||||
{
|
||||
m_pImmediateContext->OMSetDepthStencilState(m_PixelHistory.StencIncrEqDepthState,
|
||||
history[h].fragIndex);
|
||||
|
||||
m_pImmediateContext->ClearDepthStencilView(
|
||||
shaddepthOutputDSV, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, cleardepth, 0);
|
||||
|
||||
m_pImmediateContext->OMGetBlendState(&curBS, blendFactor, &curSample);
|
||||
|
||||
m_pImmediateContext->OMSetBlendState(NULL, blendFactor, curSample);
|
||||
@@ -2253,6 +2252,10 @@ rdcarray<PixelModification> D3D11Replay::PixelHistory(rdcarray<EventUsage> event
|
||||
// offset.
|
||||
uint32_t discardedOffset = 0;
|
||||
|
||||
ModificationValue lastKnownGood = {};
|
||||
if(!history.isEmpty())
|
||||
lastKnownGood = history[0].preMod;
|
||||
|
||||
for(size_t h = 0; h < history.size(); h++)
|
||||
{
|
||||
const ActionDescription *action = m_pDevice->GetAction(history[h].eventId);
|
||||
@@ -2260,35 +2263,50 @@ rdcarray<PixelModification> D3D11Replay::PixelHistory(rdcarray<EventUsage> event
|
||||
if(action->flags & ActionFlags::Clear)
|
||||
continue;
|
||||
|
||||
// reset discarded offset every event
|
||||
if(h > 0 && history[h].eventId != history[h - 1].eventId)
|
||||
{
|
||||
discardedOffset = 0;
|
||||
lastKnownGood = history[h].preMod;
|
||||
}
|
||||
|
||||
// if we're not the last modification in our event, need to fetch post fragment value
|
||||
bool lastMod = true;
|
||||
if(h + 1 < history.size() && history[h].eventId == history[h + 1].eventId)
|
||||
{
|
||||
lastMod = false;
|
||||
// colour
|
||||
{
|
||||
byte *data = pixstoreData + sizeof(Vec4f) * pixstoreStride * postColSlot;
|
||||
uint32_t offsettedSlot = (postColSlot - discardedOffset);
|
||||
byte *data = pixstoreData + sizeof(Vec4f) * pixstoreStride * offsettedSlot;
|
||||
memcpy(&history[h].postMod.col.uintValue[0], data, sizeof(Vec4f));
|
||||
}
|
||||
|
||||
float *depthdata = (float *)(pixstoreDepthData + sizeof(Vec4f) * pixstoreStride * depthSlot);
|
||||
{
|
||||
uint32_t offsettedSlot = (depthSlot - discardedOffset);
|
||||
RDCASSERT(discardedOffset <= depthSlot);
|
||||
// post fragment depth is in slot 1 of the depth
|
||||
float *depthdata = (float *)(pixstoreDepthData +
|
||||
sizeof(Vec4f) * pixstoreStride * offsettedSlot + sizeof(Vec4f));
|
||||
|
||||
// this is not exactly the right value when the original depth was D16, it will be slightly
|
||||
// higher precision than the actual value but that's better than not having a value at all,
|
||||
// and allows us to identify fragments within a draw which fail the depth test.
|
||||
if(history[h].preMod.depth >= 0.0f)
|
||||
history[h].postMod.depth = *depthdata;
|
||||
// this is not exactly the right value when the original depth was D16, it will be slightly
|
||||
// higher precision than the actual value but that's better than not having a value at all,
|
||||
// and allows us to identify fragments within a draw which fail the depth test.
|
||||
if(history[h].preMod.depth >= 0.0f)
|
||||
history[h].postMod.depth = *depthdata;
|
||||
|
||||
// we can't retrieve stencil value after each fragment, as we use stencil to identify the
|
||||
// fragment
|
||||
if(history[h].preMod.stencil >= 0)
|
||||
history[h].postMod.stencil = -2;
|
||||
else
|
||||
history[h].postMod.stencil = -1;
|
||||
// we can't retrieve stencil value after each fragment, as we use stencil to identify the
|
||||
// fragment
|
||||
if(history[h].preMod.stencil >= 0)
|
||||
history[h].postMod.stencil = -2;
|
||||
else
|
||||
history[h].postMod.stencil = -1;
|
||||
}
|
||||
|
||||
// in each case we only mark as "unknown" when the depth/stencil isn't already known to be
|
||||
// unbound
|
||||
|
||||
postColSlot++;
|
||||
depthSlot++;
|
||||
}
|
||||
|
||||
// if we're not the first modification in our event, set our preMod to the previous postMod
|
||||
@@ -2297,12 +2315,6 @@ rdcarray<PixelModification> D3D11Replay::PixelHistory(rdcarray<EventUsage> event
|
||||
history[h].preMod = history[h - 1].postMod;
|
||||
}
|
||||
|
||||
// reset discarded offset every event
|
||||
if(h > 0 && history[h].eventId != history[h - 1].eventId)
|
||||
{
|
||||
discardedOffset = 0;
|
||||
}
|
||||
|
||||
// fetch shader output value
|
||||
{
|
||||
bool someFragsClipped = history[h].primitiveID != 0;
|
||||
@@ -2311,13 +2323,14 @@ rdcarray<PixelModification> D3D11Replay::PixelHistory(rdcarray<EventUsage> event
|
||||
{
|
||||
// shader output is always 4 32bit components, so we can copy straight
|
||||
uint32_t offsettedSlot = (shadColSlot - discardedOffset);
|
||||
RDCASSERT(discardedOffset * 2 <= shadColSlot);
|
||||
RDCASSERT(discardedOffset <= shadColSlot);
|
||||
|
||||
byte *data = shadoutStoreData + sizeof(Vec4f) * pixstoreStride * offsettedSlot;
|
||||
|
||||
memcpy(&history[h].shaderOut.col.uintValue[0], data, 4 * sizeof(float));
|
||||
|
||||
// primitive ID is in the next slot after that
|
||||
// primitive ID is in slot 1 and ignores any discards
|
||||
data = shadoutStoreData + sizeof(Vec4f) * pixstoreStride * shadColSlot;
|
||||
memcpy(&history[h].primitiveID, data + sizeof(Vec4f), sizeof(uint32_t));
|
||||
}
|
||||
|
||||
@@ -2436,6 +2449,12 @@ rdcarray<PixelModification> D3D11Replay::PixelHistory(rdcarray<EventUsage> event
|
||||
RDCEraseEl(history[h].shaderOut);
|
||||
history[h].shaderOut.depth = -1.0f;
|
||||
history[h].shaderOut.stencil = -1;
|
||||
if(!lastMod)
|
||||
history[h].postMod = lastKnownGood;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastKnownGood = history[h].postMod;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user