diff --git a/renderdoc/driver/vulkan/vk_debug.cpp b/renderdoc/driver/vulkan/vk_debug.cpp index 4ee805c5a..32ca1de29 100644 --- a/renderdoc/driver/vulkan/vk_debug.cpp +++ b/renderdoc/driver/vulkan/vk_debug.cpp @@ -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( diff --git a/renderdoc/driver/vulkan/vk_debug.h b/renderdoc/driver/vulkan/vk_debug.h index d87fa1717..a1bde0d4f 100644 --- a/renderdoc/driver/vulkan/vk_debug.h +++ b/renderdoc/driver/vulkan/vk_debug.h @@ -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 m_CachedMeshPipelines; diff --git a/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp index cb21f2b0d..b61091128 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp @@ -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(); } } }