mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-29 21:30:53 +00:00
Make sure that when checking persistent maps, refdata matches serialised
* The comment goes into more detail, but basically if there's a delay between fetching the first full-flush of the map, and fetching the ref data, some changes could happen in between and get lost.
This commit is contained in:
@@ -686,9 +686,11 @@ struct MemMapState
|
||||
{
|
||||
MemMapState()
|
||||
: mapOffset(0), mapSize(0)
|
||||
, mapFlushed(false), mapCoherent(false), mappedPtr(NULL), refData(NULL)
|
||||
, needRefData(false), mapFlushed(false), mapCoherent(false)
|
||||
, mappedPtr(NULL), refData(NULL)
|
||||
{ }
|
||||
VkDeviceSize mapOffset, mapSize;
|
||||
bool needRefData;
|
||||
bool mapFlushed;
|
||||
bool mapCoherent;
|
||||
byte *mappedPtr;
|
||||
|
||||
@@ -593,16 +593,26 @@ VkResult WrappedVulkan::vkQueueSubmit(
|
||||
(VkDeviceMemory)(uint64_t)record->Resource,
|
||||
state.mapOffset+diffStart, diffEnd-diffStart
|
||||
};
|
||||
// this causes the call within to allocate state.refData and copy what was
|
||||
// serialised into it. We want to copy *precisely* the serialised data,
|
||||
// otherwise there is a gap in time between serialising out a snapshot of
|
||||
// the buffer and whenever we then copy into the ref data, e.g. below.
|
||||
// during this time, data could be written to the buffer and it won't have
|
||||
// been caught in the serialised snapshot, and if it doesn't change then
|
||||
// it *also* won't be caught in any future FindDiffRange() calls.
|
||||
//
|
||||
// Note: it's still possible that data is being written to by the
|
||||
// application while it's being serialised out in the snapshot below. That
|
||||
// is OK, since the application is responsible for ensuring it's not writing
|
||||
// data that would be needed by the GPU in this submit. As long as the
|
||||
// refdata we use for future use is identical to what was serialised, we
|
||||
// shouldn't miss anything
|
||||
state.needRefData = true;
|
||||
vkFlushMappedMemoryRanges(dev, 1, &range);
|
||||
state.mapFlushed = false;
|
||||
}
|
||||
|
||||
GetResourceManager()->MarkPendingDirty(record->GetResourceID());
|
||||
|
||||
// allocate ref data so we can compare next time to minimise serialised data
|
||||
if(state.refData == NULL)
|
||||
state.refData = Serialiser::AllocAlignedBuffer((size_t)state.mapSize, 64);
|
||||
memcpy(state.refData, state.mappedPtr, (size_t)state.mapSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -487,6 +487,25 @@ bool WrappedVulkan::Serialise_vkFlushMappedMemoryRanges(
|
||||
SERIALISE_ELEMENT(uint64_t, memSize, pMemRanges->size);
|
||||
SERIALISE_ELEMENT_BUF(byte*, data, state->mappedPtr + (size_t)memOffset, (size_t)memSize);
|
||||
|
||||
// if we need to save off this serialised buffer as reference for future comparison,
|
||||
// do so now. See the call to vkFlushMappedMemoryRanges in WrappedVulkan::vkQueueSubmit()
|
||||
if(m_State >= WRITING && state->needRefData && !state->refData)
|
||||
{
|
||||
// if we're in this case, the range should be for the whole memory region.
|
||||
RDCASSERT(memOffset == 0 && memSize == state->mapSize);
|
||||
|
||||
// it's no longer safe to use state->mappedPtr, we need to save *precisely* what
|
||||
// was serialised. We do this by copying out of the serialiser since we know this
|
||||
// memory is not changing
|
||||
size_t offs = size_t(localSerialiser->GetOffset() - memSize);
|
||||
|
||||
byte *serialisedData = localSerialiser->GetRawPtr(offs);
|
||||
|
||||
// allocate ref data so we can compare next time to minimise serialised data
|
||||
state->refData = Serialiser::AllocAlignedBuffer((size_t)state->mapSize);
|
||||
memcpy(state->refData, serialisedData, (size_t)state->mapSize);
|
||||
}
|
||||
|
||||
if(m_State < WRITING)
|
||||
{
|
||||
device = GetResourceManager()->GetLiveHandle<VkDevice>(devId);
|
||||
|
||||
Reference in New Issue
Block a user