mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-17 04:57:09 +00:00
Ensure pixel history is consistent about unknown depth or colour data
This commit is contained in:
@@ -2535,17 +2535,26 @@ struct ModificationValue
|
||||
}
|
||||
DOCUMENT(R"(The color value.
|
||||
|
||||
If the modifications are for a color target, tthe contents will all be ``0``.
|
||||
|
||||
:type: PixelValue
|
||||
)");
|
||||
PixelValue col;
|
||||
|
||||
DOCUMENT(R"(The depth output, as a ``float``.
|
||||
DOCUMENT(R"(The depth value.
|
||||
|
||||
If depth is not available/in-use for this modification, it will be ``-1.0``.
|
||||
|
||||
:type: float
|
||||
)");
|
||||
float depth;
|
||||
|
||||
DOCUMENT(R"(The stencil output, or ``-1`` if not available.
|
||||
DOCUMENT(R"(The stencil value.
|
||||
|
||||
If stencil is not available for this modification, it will be negative. If stencil is not available
|
||||
at all and not in use then the stencil value will be ``-1``. If stencil was in use but can't be
|
||||
determined due to the pixel history implementation using stencil for its own purposes, the value
|
||||
will be ``-2``. This will only happen when looking at multiple modifications from the same event.
|
||||
|
||||
:type: int
|
||||
)");
|
||||
|
||||
@@ -319,6 +319,8 @@ rdcarray<PixelModification> D3D11Replay::PixelHistory(rdcarray<EventUsage> event
|
||||
details.texFmt = GetTypedFormat(details.texFmt, typeCast);
|
||||
details.texFmt = GetNonSRGBFormat(details.texFmt);
|
||||
|
||||
const bool targetImageIsDepth = IsDepthFormat(details.texFmt);
|
||||
|
||||
SCOPED_TIMER("D3D11DebugManager::PixelHistory");
|
||||
|
||||
if(sampleIdx > details.sampleCount)
|
||||
@@ -1081,7 +1083,20 @@ rdcarray<PixelModification> D3D11Replay::PixelHistory(rdcarray<EventUsage> event
|
||||
|
||||
{
|
||||
ID3D11DepthStencilView *dsv = NULL;
|
||||
m_pImmediateContext->OMGetRenderTargets(0, NULL, &dsv);
|
||||
|
||||
if(events[ev].usage == ResourceUsage::Clear)
|
||||
{
|
||||
if(targetImageIsDepth)
|
||||
{
|
||||
dsv = (ID3D11DepthStencilView *)m_pDevice->GetResourceManager()->GetCurrentResource(
|
||||
events[ev].view);
|
||||
dsv->AddRef();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pImmediateContext->OMGetRenderTargets(0, NULL, &dsv);
|
||||
}
|
||||
|
||||
if(dsv)
|
||||
{
|
||||
@@ -2325,7 +2340,26 @@ rdcarray<PixelModification> D3D11Replay::PixelHistory(rdcarray<EventUsage> event
|
||||
const ActionDescription *action = m_pDevice->GetAction(history[h].eventId);
|
||||
|
||||
if(action->flags & ActionFlags::Clear)
|
||||
{
|
||||
if(action->flags & ActionFlags::ClearDepthStencil)
|
||||
{
|
||||
// no colour information with depth clears
|
||||
RDCEraseEl(history[h].preMod.col);
|
||||
RDCEraseEl(history[h].postMod.col);
|
||||
RDCEraseEl(history[h].shaderOut.col);
|
||||
}
|
||||
else if(action->flags & ActionFlags::ClearColor)
|
||||
{
|
||||
// no depth information with colour clears
|
||||
history[h].preMod.depth = -1;
|
||||
history[h].preMod.stencil = -1;
|
||||
history[h].postMod.depth = -1;
|
||||
history[h].postMod.stencil = -1;
|
||||
history[h].shaderOut.depth = -1;
|
||||
history[h].shaderOut.stencil = -1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// reset discarded offset every event
|
||||
if(h > 0 && history[h].eventId != history[h - 1].eventId)
|
||||
@@ -2563,7 +2597,10 @@ rdcarray<PixelModification> D3D11Replay::PixelHistory(rdcarray<EventUsage> event
|
||||
history[h].shaderOut.depth = -1.0f;
|
||||
history[h].shaderOut.stencil = -1;
|
||||
if(!lastMod)
|
||||
history[h].postMod = lastKnownGood;
|
||||
{
|
||||
history[h].postMod.col = lastKnownGood.col;
|
||||
history[h].postMod.depth = lastKnownGood.depth;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2575,6 +2612,13 @@ rdcarray<PixelModification> D3D11Replay::PixelHistory(rdcarray<EventUsage> event
|
||||
depthSlot++;
|
||||
}
|
||||
|
||||
if(targetImageIsDepth)
|
||||
{
|
||||
RDCEraseEl(history[h].preMod.col);
|
||||
RDCEraseEl(history[h].shaderOut.col);
|
||||
RDCEraseEl(history[h].postMod.col);
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
@@ -2996,6 +2996,8 @@ rdcarray<PixelModification> D3D12Replay::PixelHistory(rdcarray<EventUsage> event
|
||||
if(IsTypelessFormat(resDesc.Format))
|
||||
resDesc.Format = GetTypedFormat(resDesc.Format, typeCast);
|
||||
|
||||
const bool targetImageIsDepth = IsDepthFormat(resDesc.Format);
|
||||
|
||||
// TODO: perhaps should allocate most resources after D3D12OcclusionCallback, since we will
|
||||
// get a smaller subset of events that passed the occlusion query.
|
||||
D3D12PixelHistoryResources resources = {};
|
||||
@@ -3205,7 +3207,13 @@ rdcarray<PixelModification> D3D12Replay::PixelHistory(rdcarray<EventUsage> event
|
||||
|
||||
const D3D12EventInfo &ei = eventsInfo[eventIndex];
|
||||
|
||||
if(multisampled)
|
||||
if(targetImageIsDepth)
|
||||
{
|
||||
RDCEraseEl(mod.preMod);
|
||||
RDCEraseEl(mod.shaderOut);
|
||||
RDCEraseEl(mod.postMod);
|
||||
}
|
||||
else if(multisampled)
|
||||
{
|
||||
// If the resource uses MSAA, the copy pixel already expands it to floats
|
||||
// TODO: Need to verify this works as expected with uint/int MSAA targets
|
||||
@@ -3220,40 +3228,36 @@ rdcarray<PixelModification> D3D12Replay::PixelHistory(rdcarray<EventUsage> event
|
||||
FillInColor(fmt, ei.postmod, mod.postMod);
|
||||
}
|
||||
|
||||
EventInfo eventInfo = eventInfos[eid];
|
||||
bool hasDepth = eventInfo.hasDepth;
|
||||
DXGI_FORMAT depthFormat = cb.GetDepthFormat(mod.eventId);
|
||||
|
||||
if(hasDepth)
|
||||
if(eventInfos[eid].hasDepth && depthFormat != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
DXGI_FORMAT depthFormat = cb.GetDepthFormat(mod.eventId);
|
||||
if(depthFormat != DXGI_FORMAT_UNKNOWN)
|
||||
mod.preMod.stencil = ei.premod.stencil;
|
||||
mod.postMod.stencil = ei.postmod.stencil;
|
||||
if(multisampled)
|
||||
{
|
||||
mod.preMod.stencil = ei.premod.stencil;
|
||||
mod.postMod.stencil = ei.postmod.stencil;
|
||||
if(multisampled)
|
||||
{
|
||||
mod.preMod.depth = ei.premod.depth.fdepth;
|
||||
mod.postMod.depth = ei.postmod.depth.fdepth;
|
||||
}
|
||||
else
|
||||
{
|
||||
mod.preMod.depth = GetDepthValue(depthFormat, ei.premod);
|
||||
mod.postMod.depth = GetDepthValue(depthFormat, ei.postmod);
|
||||
}
|
||||
mod.preMod.depth = ei.premod.depth.fdepth;
|
||||
mod.postMod.depth = ei.postmod.depth.fdepth;
|
||||
}
|
||||
else
|
||||
{
|
||||
mod.preMod.depth = GetDepthValue(depthFormat, ei.premod);
|
||||
mod.postMod.depth = GetDepthValue(depthFormat, ei.postmod);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mod.preMod.stencil = -1;
|
||||
mod.preMod.depth = -1;
|
||||
// set shaderOut here, for non-shader events that won't be filled in below
|
||||
mod.shaderOut.depth = -1;
|
||||
mod.shaderOut.stencil = -1;
|
||||
mod.postMod.stencil = -1;
|
||||
mod.postMod.depth = -1;
|
||||
}
|
||||
|
||||
int32_t frags = int32_t(ei.dsWithoutShaderDiscard[0]);
|
||||
int32_t fragsClipped = int32_t(ei.dsWithShaderDiscard[0]);
|
||||
mod.shaderOut.col.intValue[0] = frags;
|
||||
mod.shaderOut.col.intValue[1] = fragsClipped;
|
||||
bool someFragsClipped = (fragsClipped < frags);
|
||||
mod.primitiveID = someFragsClipped;
|
||||
|
||||
@@ -3367,41 +3371,73 @@ rdcarray<PixelModification> D3D12Replay::PixelHistory(rdcarray<EventUsage> event
|
||||
discardOffset = 0;
|
||||
if(eventsWithFrags.find(eid) != eventsWithFrags.end())
|
||||
{
|
||||
bool hasDepth = eventInfos[eid].hasDepth && cb.GetDepthFormat(eid) != DXGI_FORMAT_UNKNOWN;
|
||||
|
||||
if(history[h].shaderDiscarded)
|
||||
{
|
||||
discardOffset++;
|
||||
RDCEraseEl(history[h].shaderOut);
|
||||
history[h].shaderOut.depth = -1;
|
||||
history[h].shaderOut.stencil = -1;
|
||||
if(hasDepth && (h < history.size() - 1) && (history[h].eventId == history[h + 1].eventId))
|
||||
history[h].shaderOut.stencil = -2;
|
||||
// Copy previous post-mod value if its not the first event
|
||||
if(h > 0)
|
||||
history[h].postMod = history[h - 1].postMod;
|
||||
{
|
||||
history[h].postMod.col = history[h - 1].postMod.col;
|
||||
history[h].postMod.depth = history[h - 1].postMod.depth;
|
||||
if(!hasDepth)
|
||||
history[h].postMod.stencil = -1;
|
||||
else if((h < history.size() - 1) && (history[h].eventId == history[h + 1].eventId))
|
||||
history[h].postMod.stencil = -2;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(perFragmentCB.ContainsEvent(eid))
|
||||
{
|
||||
uint32_t offset = perFragmentCB.GetEventOffset(eid) + f - discardOffset;
|
||||
if(multisampled)
|
||||
memcpy(history[h].shaderOut.col.floatValue.data(), &fragInfo[offset].shaderOut.color[0],
|
||||
history[h].shaderOut.col.floatValue.byteSize());
|
||||
else
|
||||
FillInColor(shaderOutFormat, fragInfo[offset].shaderOut, history[h].shaderOut);
|
||||
|
||||
if(multisampled)
|
||||
history[h].shaderOut.depth = fragInfo[offset].shaderOut.depth.fdepth;
|
||||
if(targetImageIsDepth)
|
||||
{
|
||||
RDCEraseEl(history[h].shaderOut.col);
|
||||
}
|
||||
else
|
||||
history[h].shaderOut.depth =
|
||||
GetDepthValue(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, fragInfo[offset].shaderOut);
|
||||
{
|
||||
if(multisampled)
|
||||
memcpy(history[h].shaderOut.col.floatValue.data(), &fragInfo[offset].shaderOut.color[0],
|
||||
history[h].shaderOut.col.floatValue.byteSize());
|
||||
else
|
||||
FillInColor(shaderOutFormat, fragInfo[offset].shaderOut, history[h].shaderOut);
|
||||
}
|
||||
|
||||
if(hasDepth)
|
||||
{
|
||||
if(multisampled)
|
||||
history[h].shaderOut.depth = fragInfo[offset].shaderOut.depth.fdepth;
|
||||
else
|
||||
history[h].shaderOut.depth =
|
||||
GetDepthValue(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, fragInfo[offset].shaderOut);
|
||||
}
|
||||
|
||||
if((h < history.size() - 1) && (history[h].eventId == history[h + 1].eventId))
|
||||
{
|
||||
// Get post-modification value if this is not the last fragment for the event.
|
||||
ConvertAndFillInColor(shaderOutFormat, fragInfo[offset].postMod, fmt, history[h].postMod);
|
||||
if(!targetImageIsDepth)
|
||||
{
|
||||
ConvertAndFillInColor(shaderOutFormat, fragInfo[offset].postMod, fmt,
|
||||
history[h].postMod);
|
||||
}
|
||||
|
||||
// MSAA depth is expanded out to floats in the compute shader
|
||||
if(multisampled)
|
||||
history[h].postMod.depth = fragInfo[offset].postMod.depth.fdepth;
|
||||
else
|
||||
history[h].postMod.depth =
|
||||
GetDepthValue(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, fragInfo[offset].postMod);
|
||||
history[h].postMod.stencil = -2;
|
||||
if(hasDepth)
|
||||
{
|
||||
if(multisampled)
|
||||
history[h].postMod.depth = fragInfo[offset].postMod.depth.fdepth;
|
||||
else
|
||||
history[h].postMod.depth =
|
||||
GetDepthValue(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, fragInfo[offset].postMod);
|
||||
history[h].postMod.stencil = -2;
|
||||
}
|
||||
}
|
||||
// If it is not the first fragment for the event, set the preMod to the
|
||||
// postMod of the previous fragment.
|
||||
|
||||
@@ -1061,19 +1061,47 @@ void readPixelValues(WrappedOpenGL *driver, const GLPixelHistoryResources &resou
|
||||
}
|
||||
}
|
||||
|
||||
modValue.depth = depthValues[i];
|
||||
if(readStencil)
|
||||
const ActionDescription *action = driver->GetAction(history[historyIndex + i].eventId);
|
||||
if(action->flags & ActionFlags::ClearColor)
|
||||
{
|
||||
modValue.stencil = stencilValues[i];
|
||||
modValue.depth = -1;
|
||||
modValue.stencil = -1;
|
||||
}
|
||||
else
|
||||
else if(history[historyIndex + i].directShaderWrite && !resources.depthTarget)
|
||||
{
|
||||
// if this isn't the last fragment in this event, the stencil is unavailable
|
||||
modValue.depth = -1;
|
||||
if(historyIndex + i + 1 < history.size() &&
|
||||
history[historyIndex + i].eventId == history[historyIndex + i + 1].eventId)
|
||||
modValue.stencil = -2;
|
||||
else
|
||||
modValue.stencil = history[historyIndex + i].postMod.stencil;
|
||||
modValue.stencil = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(action->flags & ActionFlags::ClearDepthStencil)
|
||||
{
|
||||
RDCEraseEl(modValue.col);
|
||||
}
|
||||
|
||||
modValue.depth = depthValues[i];
|
||||
if(readStencil)
|
||||
{
|
||||
modValue.stencil = stencilValues[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
// if this isn't the last fragment in this event, the postmod stencil is unavailable
|
||||
if(modType == ModType::PostMod && historyIndex + i + 1 < history.size() &&
|
||||
history[historyIndex + i].eventId == history[historyIndex + i + 1].eventId)
|
||||
modValue.stencil = -2;
|
||||
// if this isn't the first fragment in this event, the premod stencil is unavailable
|
||||
else if(modType == ModType::PreMod && historyIndex + i > 0 &&
|
||||
history[historyIndex + i].eventId == history[historyIndex + i - 1].eventId)
|
||||
modValue.stencil = -2;
|
||||
else
|
||||
modValue.stencil = modType == ModType::PreMod ? history[historyIndex + i].preMod.stencil
|
||||
: history[historyIndex + i].postMod.stencil;
|
||||
}
|
||||
}
|
||||
|
||||
if(modType == ModType::PreMod)
|
||||
@@ -1101,10 +1129,45 @@ void readPixelValuesMS(WrappedOpenGL *driver, const GLPixelHistoryResources &res
|
||||
{
|
||||
modValue.col.floatValue[j] = pixelValue[j];
|
||||
}
|
||||
modValue.depth = pixelValue[depthOffset];
|
||||
if(readStencil)
|
||||
|
||||
const ActionDescription *action = driver->GetAction(history[historyIndex].eventId);
|
||||
if(action->flags & ActionFlags::ClearColor)
|
||||
{
|
||||
modValue.stencil = *(int *)&pixelValue[stencilOffset];
|
||||
modValue.depth = -1;
|
||||
modValue.stencil = -1;
|
||||
}
|
||||
else if(history[historyIndex].directShaderWrite && !resources.depthTarget)
|
||||
{
|
||||
modValue.depth = -1;
|
||||
if(historyIndex + 1 < history.size() &&
|
||||
history[historyIndex].eventId == history[historyIndex + 1].eventId)
|
||||
modValue.stencil = -2;
|
||||
else
|
||||
modValue.stencil = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(action->flags & ActionFlags::ClearDepthStencil)
|
||||
{
|
||||
RDCEraseEl(modValue.col);
|
||||
}
|
||||
|
||||
modValue.depth = pixelValue[depthOffset];
|
||||
if(readStencil)
|
||||
{
|
||||
modValue.stencil = *(int *)&pixelValue[stencilOffset];
|
||||
}
|
||||
else
|
||||
{
|
||||
// if this isn't the last fragment in this event, the postmod stencil is unavailable
|
||||
if(modType == ModType::PostMod && historyIndex + 1 < history.size() &&
|
||||
history[historyIndex].eventId == history[historyIndex + 1].eventId)
|
||||
modValue.stencil = -2;
|
||||
// if this isn't the first fragment in this event, the premod stencil is unavailable
|
||||
else if(modType == ModType::PreMod && historyIndex > 0 &&
|
||||
history[historyIndex].eventId == history[historyIndex - 1].eventId)
|
||||
modValue.stencil = -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1310,12 +1373,14 @@ ModificationValue readShaderOutMS(WrappedOpenGL *driver, const GLPixelHistoryRes
|
||||
struct EventFragmentData
|
||||
{
|
||||
std::map<uint32_t, uint32_t> eventFragments;
|
||||
std::map<uint32_t, GLbitfield> eventFBMask;
|
||||
rdcarray<uint32_t> fragmentsClipped;
|
||||
};
|
||||
|
||||
// This function gets:
|
||||
// - calculates the number of fragments per event
|
||||
// - per-event whether some fragments were discarded
|
||||
// - a per-event mask of which of colour/depth is bound and valid
|
||||
// - reads the shader output values per event (per-fragment shader output is fetched later)
|
||||
EventFragmentData QueryNumFragmentsByEvent(WrappedOpenGL *driver, GLPixelHistoryResources &resources,
|
||||
const rdcarray<EventUsage> &modEvents,
|
||||
@@ -1328,6 +1393,7 @@ EventFragmentData QueryNumFragmentsByEvent(WrappedOpenGL *driver, GLPixelHistory
|
||||
|
||||
EventFragmentData ret;
|
||||
std::map<uint32_t, uint32_t> &eventFragments = ret.eventFragments;
|
||||
std::map<uint32_t, GLbitfield> &eventFBMask = ret.eventFBMask;
|
||||
rdcarray<uint32_t> &fragmentsClipped = ret.fragmentsClipped;
|
||||
|
||||
for(size_t i = 0; i < modEvents.size(); ++i)
|
||||
@@ -1335,6 +1401,8 @@ EventFragmentData QueryNumFragmentsByEvent(WrappedOpenGL *driver, GLPixelHistory
|
||||
GLRenderState state;
|
||||
state.FetchState(driver);
|
||||
|
||||
eventFBMask[modEvents[i].eventId] = getFramebufferCopyMask(driver);
|
||||
|
||||
uint32_t colIdx = getFramebufferColIndex(driver, resources.target);
|
||||
|
||||
GLenum colourFormat = getCurrentTextureFormat(driver, colIdx);
|
||||
@@ -1503,6 +1571,20 @@ EventFragmentData QueryNumFragmentsByEvent(WrappedOpenGL *driver, GLPixelHistory
|
||||
}
|
||||
}
|
||||
|
||||
if(modEvents[i].usage == ResourceUsage::Clear)
|
||||
{
|
||||
history[i].shaderOut = history[i].postMod;
|
||||
if(resources.depthTarget)
|
||||
RDCEraseEl(history[i].shaderOut.col);
|
||||
}
|
||||
|
||||
if(isDirectWrite(modEvents[i].usage))
|
||||
{
|
||||
RDCEraseEl(history[i].shaderOut);
|
||||
history[i].shaderOut.depth = -1;
|
||||
history[i].shaderOut.stencil = -1;
|
||||
}
|
||||
|
||||
eventFragments.emplace(modEvents[i].eventId, numFragmentsWithoutDiscard);
|
||||
if(numFragmentsWithoutDiscard > numFragments)
|
||||
fragmentsClipped.push_back(modEvents[i].eventId);
|
||||
@@ -1916,6 +1998,8 @@ void QueryShaderOutPerFragment(WrappedOpenGL *driver, GLReplay *replay,
|
||||
modValue.stencil = historyIndex->shaderOut.stencil;
|
||||
|
||||
historyIndex->shaderOut = modValue;
|
||||
if(resources.depthTarget)
|
||||
RDCEraseEl(historyIndex->shaderOut.col);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1935,6 +2019,8 @@ void QueryShaderOutPerFragment(WrappedOpenGL *driver, GLReplay *replay,
|
||||
historyIndex->shaderOut =
|
||||
readShaderOutMS(driver, resources, copyFramebuffer, sampleIndex, 0, 0);
|
||||
historyIndex->shaderOut.stencil = oldStencil;
|
||||
if(resources.depthTarget)
|
||||
RDCEraseEl(historyIndex->shaderOut.col);
|
||||
}
|
||||
historyIndex++;
|
||||
}
|
||||
@@ -2760,6 +2846,30 @@ rdcarray<PixelModification> GLReplay::PixelHistory(rdcarray<EventUsage> events,
|
||||
eventFragmentData, textureDesc.msSamp, sampleIdx, textureWidth,
|
||||
textureHeight);
|
||||
|
||||
// clear depth or colour information when not available
|
||||
for(size_t h = 0; h < history.size(); h++)
|
||||
{
|
||||
GLbitfield fbMask = eventFragmentData.eventFBMask[history[h].eventId];
|
||||
|
||||
if((fbMask & GL_COLOR_BUFFER_BIT) == 0)
|
||||
{
|
||||
RDCEraseEl(history[h].preMod.col);
|
||||
RDCEraseEl(history[h].postMod.col);
|
||||
}
|
||||
if((fbMask & GL_DEPTH_BUFFER_BIT) == 0)
|
||||
{
|
||||
history[h].preMod.depth = -1;
|
||||
history[h].shaderOut.depth = -1;
|
||||
history[h].postMod.depth = -1;
|
||||
}
|
||||
if((fbMask & GL_STENCIL_BUFFER_BIT) == 0)
|
||||
{
|
||||
history[h].preMod.stencil = -1;
|
||||
history[h].shaderOut.stencil = -1;
|
||||
history[h].postMod.stencil = -1;
|
||||
}
|
||||
}
|
||||
|
||||
CalculateFragmentDepthTests(m_pDriver, resources, modEvents, history, eventFragments);
|
||||
|
||||
PixelHistoryDestroyResources(m_pDriver, resources);
|
||||
|
||||
@@ -2390,7 +2390,7 @@ private:
|
||||
rect.rect.extent.width = 1;
|
||||
rect.rect.extent.height = 1;
|
||||
rect.baseArrayLayer = 0;
|
||||
rect.layerCount = m_CallbackInfo.layers;
|
||||
rect.layerCount = 1;
|
||||
ObjDisp(cmd)->CmdClearAttachments(Unwrap(cmd), 1, &att, 1, &rect);
|
||||
}
|
||||
|
||||
@@ -3514,7 +3514,7 @@ struct VulkanPixelHistoryPerFragmentCallback : VulkanPixelHistoryCallback
|
||||
sizeof(clearAtts[0].clearValue.color));
|
||||
|
||||
clearAtts[1].aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
clearAtts[1].clearValue.depthStencil.depth = premod.depth;
|
||||
clearAtts[1].clearValue.depthStencil.depth = RDCCLAMP(premod.depth, 0.0f, 1.0f);
|
||||
|
||||
if(IsDepthOrStencilFormat(m_CallbackInfo.targetImageFormat))
|
||||
ObjDisp(cmd)->CmdClearAttachments(Unwrap(cmd), 1, clearAtts + 1, 1, &rect);
|
||||
@@ -4722,8 +4722,17 @@ rdcarray<PixelModification> VulkanReplay::PixelHistory(rdcarray<EventUsage> even
|
||||
continue;
|
||||
}
|
||||
const EventInfo &ei = eventsInfo[eventIndex];
|
||||
FillInColor(fmt, ei.premod, mod.preMod);
|
||||
FillInColor(fmt, ei.postmod, mod.postMod);
|
||||
if(IsDepthOrStencilFormat(imginfo.format))
|
||||
{
|
||||
RDCEraseEl(mod.preMod);
|
||||
RDCEraseEl(mod.shaderOut);
|
||||
RDCEraseEl(mod.postMod);
|
||||
}
|
||||
else
|
||||
{
|
||||
FillInColor(fmt, ei.premod, mod.preMod);
|
||||
FillInColor(fmt, ei.postmod, mod.postMod);
|
||||
}
|
||||
VkFormat depthFormat = cb.GetDepthFormat(mod.eventId);
|
||||
if(depthFormat != VK_FORMAT_UNDEFINED)
|
||||
{
|
||||
@@ -4740,11 +4749,19 @@ rdcarray<PixelModification> VulkanReplay::PixelHistory(rdcarray<EventUsage> even
|
||||
mod.postMod.depth = GetDepthValue(depthFormat, ei.postmod);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mod.preMod.depth = -1;
|
||||
mod.preMod.stencil = -1;
|
||||
// set shaderOut here, for non-shader events that won't be filled in below
|
||||
mod.shaderOut.depth = -1;
|
||||
mod.shaderOut.stencil = -1;
|
||||
mod.postMod.depth = -1;
|
||||
mod.postMod.stencil = -1;
|
||||
}
|
||||
|
||||
int32_t frags = int32_t(ei.dsWithoutShaderDiscard[4]);
|
||||
int32_t fragsClipped = int32_t(ei.dsWithShaderDiscard[4]);
|
||||
mod.shaderOut.col.intValue[0] = frags;
|
||||
mod.shaderOut.col.intValue[1] = fragsClipped;
|
||||
bool someFragsClipped = (fragsClipped < frags);
|
||||
mod.primitiveID = someFragsClipped;
|
||||
// Draws in secondary command buffers will fail this check,
|
||||
@@ -4875,29 +4892,63 @@ rdcarray<PixelModification> VulkanReplay::PixelHistory(rdcarray<EventUsage> even
|
||||
if(history[h].shaderDiscarded)
|
||||
{
|
||||
discardOffset++;
|
||||
RDCEraseEl(history[h].shaderOut);
|
||||
history[h].shaderOut.depth = -1;
|
||||
history[h].shaderOut.stencil = -1;
|
||||
if(cb.GetDepthFormat(eid) != VK_FORMAT_UNDEFINED && (h < history.size() - 1) &&
|
||||
(history[h].eventId == history[h + 1].eventId))
|
||||
history[h].shaderOut.stencil = -2;
|
||||
// Copy previous post-mod value if its not the first event
|
||||
if(h > 0)
|
||||
history[h].postMod = history[h - 1].postMod;
|
||||
{
|
||||
history[h].postMod.col = history[h - 1].postMod.col;
|
||||
history[h].postMod.depth = history[h - 1].postMod.depth;
|
||||
if(cb.GetDepthFormat(eid) == VK_FORMAT_UNDEFINED)
|
||||
history[h].postMod.stencil = -1;
|
||||
else if((h < history.size() - 1) && (history[h].eventId == history[h + 1].eventId))
|
||||
history[h].postMod.stencil = -2;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
uint32_t offset = perFragmentCB.GetEventOffset(eid) + f - discardOffset;
|
||||
FillInColor(shaderOutFormat, bp[offset].shaderOut, history[h].shaderOut);
|
||||
|
||||
if(!IsDepthOrStencilFormat(imginfo.format))
|
||||
{
|
||||
FillInColor(shaderOutFormat, bp[offset].shaderOut, history[h].shaderOut);
|
||||
// Zero out elements the shader didn't write to.
|
||||
for(int i = fmt.compCount; i < 4; i++)
|
||||
history[h].shaderOut.col.floatValue[i] = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCEraseEl(history[h].shaderOut.col);
|
||||
}
|
||||
|
||||
history[h].shaderOut.depth = bp[offset].shaderOut.depth.fdepth;
|
||||
// Zero out elements the shader didn't write to.
|
||||
for(int i = fmt.compCount; i < 4; i++)
|
||||
history[h].shaderOut.col.floatValue[i] = 0.0f;
|
||||
if(cb.GetDepthFormat(eid) == VK_FORMAT_UNDEFINED)
|
||||
{
|
||||
history[h].shaderOut.depth = -1;
|
||||
history[h].shaderOut.stencil = -1;
|
||||
}
|
||||
|
||||
if((h < history.size() - 1) && (history[h].eventId == history[h + 1].eventId))
|
||||
{
|
||||
// Get post-modification value if this is not the last fragment for the event.
|
||||
FillInColor(fmt, bp[offset].postMod, history[h].postMod);
|
||||
if(!IsDepthOrStencilFormat(imginfo.format))
|
||||
{
|
||||
FillInColor(fmt, bp[offset].postMod, history[h].postMod);
|
||||
}
|
||||
|
||||
// MSAA depth is expanded out to floats in the compute shader
|
||||
if((uint32_t)callbackInfo.samples > 1)
|
||||
history[h].postMod.depth = bp[offset].postMod.depth.fdepth;
|
||||
else
|
||||
history[h].postMod.depth =
|
||||
GetDepthValue(VK_FORMAT_D32_SFLOAT_S8_UINT, bp[offset].postMod);
|
||||
history[h].postMod.stencil = -2;
|
||||
if(cb.GetDepthFormat(eid) != VK_FORMAT_UNDEFINED)
|
||||
{
|
||||
if((uint32_t)callbackInfo.samples > 1)
|
||||
history[h].postMod.depth = bp[offset].postMod.depth.fdepth;
|
||||
else
|
||||
history[h].postMod.depth =
|
||||
GetDepthValue(VK_FORMAT_D32_SFLOAT_S8_UINT, bp[offset].postMod);
|
||||
history[h].postMod.stencil = -2;
|
||||
}
|
||||
}
|
||||
// If it is not the first fragment for the event, set the preMod to the
|
||||
// postMod of the previous fragment.
|
||||
|
||||
Reference in New Issue
Block a user