diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index e6e72cdca7..b1c802f607 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -177,6 +177,8 @@ try RendererVulkan::~RendererVulkan() { scheduler.RegisterOnSubmit([] {}); + // Acquire submit_mutex before WaitIdle to prevent simultaneous queue access + std::scoped_lock lock{scheduler.submit_mutex}; void(device.GetLogical().WaitIdle()); } diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index 0f54dd5ade..e70e55085c 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp @@ -30,7 +30,8 @@ BlitScreen::~BlitScreen() = default; void BlitScreen::WaitIdle() { present_manager.WaitPresent(); scheduler.Finish(); - device.GetLogical().WaitIdle(); + // Note: scheduler.Finish() already waits for GPU and synchronizes submit_mutex + // Calling device.WaitIdle() here causes threading errors (simultaneous queue access) } void BlitScreen::SetWindowAdaptPass() {