Don't wrap queue readback buffer

* This can fix a potential race condition during capture if capture ends while
  the readback buffer is being resized/created.
This commit is contained in:
baldurk
2025-11-10 13:59:55 +00:00
parent 7cf68de074
commit d20295cf41
3 changed files with 12 additions and 10 deletions
@@ -1092,7 +1092,8 @@ void WrappedID3D12CommandQueue::ExecuteCommandListsInternal(UINT NumCommandLists
queueReadback.Resize(size);
queueReadback.list->Reset(queueReadback.alloc, NULL);
queueReadback.list->CopyBufferRegion(queueReadback.readbackBuf, 0, res, 0, size);
Unwrap(queueReadback.list)
->CopyBufferRegion(queueReadback.unwrappedReadbackBuf, 0, res->GetReal(), 0, size);
queueReadback.list->Close();
ID3D12CommandList *listptr = Unwrap(queueReadback.list);
queueReadback.unwrappedQueue->ExecuteCommandLists(1, &listptr);
+9 -8
View File
@@ -4468,10 +4468,10 @@ void QueueReadbackData::Resize(uint64_t size)
if(readbackSize >= size && size != 0)
return;
if(readbackBuf)
if(unwrappedReadbackBuf)
{
Unwrap(readbackBuf)->Unmap(0, NULL);
SAFE_RELEASE(readbackBuf);
unwrappedReadbackBuf->Unmap(0, NULL);
SAFE_RELEASE(unwrappedReadbackBuf);
readbackMapped = NULL;
}
@@ -4502,11 +4502,12 @@ void QueueReadbackData::Resize(uint64_t size)
heapProps.CreationNodeMask = 1;
heapProps.VisibleNodeMask = 1;
device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &readbackDesc,
D3D12_RESOURCE_STATE_COPY_DEST, NULL, __uuidof(ID3D12Resource),
(void **)&readbackBuf);
// don't intercept the map
Unwrap(readbackBuf)->Map(0, NULL, (void **)&readbackMapped);
// create this unwrapped to avoid intercepting the map during capture or having locking issues
// when creating this resource
device->GetReal()->CreateCommittedResource(
&heapProps, D3D12_HEAP_FLAG_NONE, &readbackDesc, D3D12_RESOURCE_STATE_COPY_DEST, NULL,
__uuidof(ID3D12Resource), (void **)&unwrappedReadbackBuf);
unwrappedReadbackBuf->Map(0, NULL, (void **)&readbackMapped);
}
void WrappedID3D12Device::CreateInternalResources()
+1 -1
View File
@@ -74,7 +74,7 @@ DECLARE_REFLECTION_STRUCT(D3D12InitParams);
struct QueueReadbackData
{
Threading::CriticalSection lock;
ID3D12Resource *readbackBuf = NULL;
ID3D12Resource *unwrappedReadbackBuf = NULL;
byte *readbackMapped = NULL;
uint64_t readbackSize = 0;