mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-24 15:36:33 +00:00
Ensure only one thread at a time uses GPU readbacks during capture
* This was already done on D3D12 but Vulkan was missing the appropriate locks
This commit is contained in:
@@ -2698,8 +2698,10 @@ void VulkanDebugManager::FillWithDiscardPatternOnHost(VkDevice device, DiscardTy
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanDebugManager::InitReadbackBuffer(VkDeviceSize sz)
|
||||
VulkanDebugManager::ReadbackWindow VulkanDebugManager::LockReadbackBuffer(VkDeviceSize sz)
|
||||
{
|
||||
m_ReadbackLock.Lock();
|
||||
|
||||
if(m_ReadbackWindow.TotalSize() < sz)
|
||||
{
|
||||
if(m_ReadbackWindow.TotalSize() > 0)
|
||||
@@ -2722,6 +2724,13 @@ void VulkanDebugManager::InitReadbackBuffer(VkDeviceSize sz)
|
||||
CHECK_VKR(m_pDriver, VK_ERROR_MEMORY_MAP_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
return {m_ReadbackWindow.UnwrappedBuffer(), m_ReadbackWindow.UnwrappedMemory(), m_ReadbackPtr};
|
||||
}
|
||||
|
||||
void VulkanDebugManager::UnlockReadbackBuffer()
|
||||
{
|
||||
m_ReadbackLock.Unlock();
|
||||
}
|
||||
|
||||
void VulkanReplay::AllocAndAddReservedDescriptors(
|
||||
|
||||
@@ -83,10 +83,15 @@ public:
|
||||
VkImageLayout curLayout, VkImageSubresourceRange discardRange,
|
||||
VkRect2D discardRect);
|
||||
|
||||
void InitReadbackBuffer(VkDeviceSize sz);
|
||||
byte *GetReadbackPtr() { return m_ReadbackPtr; }
|
||||
VkBuffer GetUnwrappedReadbackBuffer() { return m_ReadbackWindow.UnwrappedBuffer(); }
|
||||
VkDeviceMemory GetUnwrappedReadbackMemory() { return m_ReadbackWindow.UnwrappedMemory(); }
|
||||
struct ReadbackWindow
|
||||
{
|
||||
VkBuffer unwrappedBuffer;
|
||||
VkDeviceMemory unwrappedMemory;
|
||||
byte *ptr;
|
||||
};
|
||||
|
||||
ReadbackWindow LockReadbackBuffer(VkDeviceSize sz);
|
||||
void UnlockReadbackBuffer();
|
||||
VkPipelineCache GetPipelineCache() { return m_PipelineCache; }
|
||||
VkPipeline GetCustomPipeline() { return m_Custom.TexPipeline; }
|
||||
VkPipeline GetDummyPipeline() { return m_DummyPipeline; }
|
||||
@@ -134,6 +139,7 @@ private:
|
||||
// GetBufferData
|
||||
GPUBuffer m_ReadbackWindow;
|
||||
byte *m_ReadbackPtr = NULL;
|
||||
Threading::CriticalSection m_ReadbackLock;
|
||||
|
||||
// CacheMeshDisplayPipelines
|
||||
std::map<uint64_t, VKMeshDisplayPipelines> m_CachedMeshPipelines;
|
||||
|
||||
@@ -1228,7 +1228,8 @@ void WrappedVulkan::CaptureQueueSubmit(VkQueue queue,
|
||||
{
|
||||
RDCDEBUG("Reading back %s with GPU for comparison", ToStr(record->GetResourceID()).c_str());
|
||||
|
||||
GetDebugManager()->InitReadbackBuffer(state.mapOffset + state.mapSize);
|
||||
VulkanDebugManager::ReadbackWindow readback =
|
||||
GetDebugManager()->LockReadbackBuffer(state.mapOffset + state.mapSize);
|
||||
|
||||
// immediately issue a command buffer to copy back the data. We do that on this queue to
|
||||
// avoid complexity with synchronising with another queue, but the transfer queue if
|
||||
@@ -1250,8 +1251,7 @@ void WrappedVulkan::CaptureQueueSubmit(VkQueue queue,
|
||||
VkBufferCopy region = {state.mapOffset, state.mapOffset, state.mapSize};
|
||||
|
||||
ObjDisp(copycmd)->CmdCopyBuffer(Unwrap(copycmd), Unwrap(state.wholeMemBuf),
|
||||
GetDebugManager()->GetUnwrappedReadbackBuffer(), 1,
|
||||
®ion);
|
||||
readback.unwrappedBuffer, 1, ®ion);
|
||||
|
||||
// wait for transfer to finish before reading on CPU
|
||||
VkBufferMemoryBarrier bufBarrier = {
|
||||
@@ -1261,7 +1261,7 @@ void WrappedVulkan::CaptureQueueSubmit(VkQueue queue,
|
||||
VK_ACCESS_HOST_READ_BIT,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
GetDebugManager()->GetUnwrappedReadbackBuffer(),
|
||||
readback.unwrappedBuffer,
|
||||
0,
|
||||
VK_WHOLE_SIZE,
|
||||
};
|
||||
@@ -1291,7 +1291,7 @@ void WrappedVulkan::CaptureQueueSubmit(VkQueue queue,
|
||||
VkMappedMemoryRange range = {
|
||||
VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
||||
NULL,
|
||||
GetDebugManager()->GetUnwrappedReadbackMemory(),
|
||||
readback.unwrappedMemory,
|
||||
0,
|
||||
VK_WHOLE_SIZE,
|
||||
};
|
||||
@@ -1300,7 +1300,7 @@ void WrappedVulkan::CaptureQueueSubmit(VkQueue queue,
|
||||
ObjDisp(queue)->InvalidateMappedMemoryRanges(Unwrap(m_Device), 1, &range);
|
||||
RDCASSERTEQUAL(copyret, VK_SUCCESS);
|
||||
|
||||
state.cpuReadPtr = GetDebugManager()->GetReadbackPtr();
|
||||
state.cpuReadPtr = readback.ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1349,6 +1349,9 @@ void WrappedVulkan::CaptureQueueSubmit(VkQueue queue,
|
||||
|
||||
// restore this just in case
|
||||
state.cpuReadPtr = state.mappedPtr;
|
||||
|
||||
if(state.readbackOnGPU)
|
||||
GetDebugManager()->UnlockReadbackBuffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user