From e62b1417fd3198892c41be440ac33edbd3e397ba Mon Sep 17 00:00:00 2001 From: xbzk Date: Sat, 25 Apr 2026 18:27:45 -0300 Subject: [PATCH] [vk_query_cache] add soft recover for GetQueryResults=VK_TIMEOUT --- src/video_core/fence_manager.h | 8 +++++++- src/video_core/renderer_vulkan/vk_query_cache.cpp | 13 +++++++++++++ src/video_core/renderer_vulkan/vk_scheduler.cpp | 11 ++++++++++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/video_core/fence_manager.h b/src/video_core/fence_manager.h index 2ddae39750..edfc1422ae 100644 --- a/src/video_core/fence_manager.h +++ b/src/video_core/fence_manager.h @@ -16,6 +16,7 @@ #include #include "common/common_types.h" +#include "common/logging.h" #include "common/settings.h" #include "common/thread.h" #include "video_core/delayed_destruction_ring.h" @@ -214,7 +215,12 @@ private: if (!current_fence->IsStubbed()) { WaitFence(current_fence); } - PopAsyncFlushes(); + try { + PopAsyncFlushes(); + } catch (const std::exception& e) { + LOG_CRITICAL(Render_Vulkan, "GPUFencingThread: exception in PopAsyncFlushes: {}", e.what()); + throw; + } for (auto& operation : current_operations) { operation(); } diff --git a/src/video_core/renderer_vulkan/vk_query_cache.cpp b/src/video_core/renderer_vulkan/vk_query_cache.cpp index 6aea5d18a8..e4016ac769 100644 --- a/src/video_core/renderer_vulkan/vk_query_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_query_cache.cpp @@ -4,6 +4,7 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later +#include #include #include #include @@ -74,10 +75,22 @@ public: switch (query_result) { case VK_SUCCESS: return; + case VK_TIMEOUT: { + static std::atomic soft_fault_count{0}; + const u32 n = soft_fault_count.fetch_add(1, std::memory_order_relaxed) + 1; + LOG_WARNING(Render_Vulkan, + "GetQueryResults VK_TIMEOUT #{}: pool={} start={} size={}", + n, index, start, size); + std::fill_n(&host_results[start], size, 0ULL); + return; + } case VK_ERROR_DEVICE_LOST: device.ReportLoss(); [[fallthrough]]; default: + LOG_CRITICAL(Render_Vulkan, + "GetQueryResults failed: result={} pool={} start={} size={}", + static_cast(query_result), index, start, size); throw vk::Exception(query_result); } } diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index fdaf9baacc..79ef8d1baa 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -223,7 +223,16 @@ void Scheduler::WorkerThread(std::stop_token stop_token) { // Perform the work, tracking whether the chunk was a submission // before executing. const bool has_submit = work->HasSubmit(); - work->ExecuteAll(current_cmdbuf, current_upload_cmdbuf); + try { + work->ExecuteAll(current_cmdbuf, current_upload_cmdbuf); + } catch (const vk::Exception& e) { + LOG_CRITICAL(Render_Vulkan, "VulkanWorker: vk::Exception in ExecuteAll: result={}", + static_cast(e.GetResult())); + throw; + } catch (const std::exception& e) { + LOG_CRITICAL(Render_Vulkan, "VulkanWorker: exception in ExecuteAll: {}", e.what()); + throw; + } // If the chunk was a submission, reallocate the command buffer. if (has_submit) {