Skip to content

Commit

Permalink
D3D12 Pixel History fix device removed with large number of fragments
Browse files Browse the repository at this point in the history
Destination copy buffer was sized to the number of events, this did not guarantee enough storage for the per fragment data i.e. small number of events with large of fragments per event

Reserve space for at least 256 fragments or 128 events in the buffer
Do not get data for fragments if the buffer does not have enough space

In the problem case the buffer went from 4KB to 28KB
  • Loading branch information
Zorro666 committed Nov 7, 2024
1 parent 0be2b86 commit d1663d9
Showing 1 changed file with 27 additions and 1 deletion.
28 changes: 27 additions & 1 deletion renderdoc/driver/d3d12/d3d12_pixelhistory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@
#include "d3d12_replay.h"
#include "d3d12_shader_cache.h"

const uint32_t D3D12_PIXEL_HISTORY_MIN_EVENTS_TO_STORE = 128;
const uint32_t D3D12_PIXEL_HISTORY_MIN_FRAGMENTS_TO_STORE = 256;

struct D3D12CopyPixelParams
{
// The image being copied from
Expand Down Expand Up @@ -2096,9 +2099,17 @@ struct D3D12PixelHistoryPerFragmentCallback : D3D12PixelHistoryCallback

rdcarray<D3D12Descriptor> origRts = state.rts;

uint32_t maxFrags =
(UINT)(m_CallbackInfo.dstBuffer->GetDesc().Width / sizeof(D3D12PerFragmentInfo));
// Get primitive ID and shader output value for each fragment.
for(uint32_t f = 0; f < numFragmentsInEvent; f++)
{
if(fragsProcessed + numFragmentsInEvent > maxFrags)
{
RDCERR("Pixel History exceeded maximum number of fragments to process Max %d %d %d",
maxFrags, fragsProcessed, numFragmentsInEvent);
break;
}
for(uint32_t i = 0; i < 2; i++)
{
uint32_t storeOffset = (fragsProcessed + f) * sizeof(D3D12PerFragmentInfo);
Expand Down Expand Up @@ -2187,6 +2198,13 @@ struct D3D12PixelHistoryPerFragmentCallback : D3D12PixelHistoryCallback
// For every fragment except the last one, retrieve post-modification value.
for(uint32_t f = 0; f < numFragmentsInEvent - 1; ++f)
{
if(fragsProcessed + numFragmentsInEvent > maxFrags)
{
RDCERR("Pixel History exceeded maximum number of fragments to process Max %d %d %d",
maxFrags, fragsProcessed, numFragmentsInEvent);
break;
}

D3D12MarkerRegion region(cmd,
StringFormat::Fmt("Getting postmod for fragment %u in %u", f, eid));

Expand Down Expand Up @@ -2715,7 +2733,15 @@ bool D3D12DebugManager::PixelHistorySetupResources(D3D12PixelHistoryResources &r
bufDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
bufDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;

bufDesc.Width = AlignUp((uint32_t)(numEvents * sizeof(D3D12EventInfo)), 4096U);
numEvents = RDCMAX(numEvents, D3D12_PIXEL_HISTORY_MIN_EVENTS_TO_STORE);
uint32_t bufferEventsSize = numEvents * sizeof(D3D12EventInfo);

uint32_t numFragments = D3D12_PIXEL_HISTORY_MIN_FRAGMENTS_TO_STORE;
uint32_t bufferFragmentsSize = numFragments * sizeof(D3D12PerFragmentInfo);

uint32_t bufferSize = RDCMAX(bufferEventsSize, bufferFragmentsSize);

bufDesc.Width = AlignUp(bufferSize, 4096U);

hr = m_pDevice->CreateCommittedResource(&readbackHeapProps, D3D12_HEAP_FLAG_NONE, &bufDesc,
D3D12_RESOURCE_STATE_COPY_DEST, NULL,
Expand Down

0 comments on commit d1663d9

Please sign in to comment.