From b9021ea469c45ceb7da00131170d50de92f37555 Mon Sep 17 00:00:00 2001 From: GPUCode Date: Sun, 5 Mar 2023 01:27:39 +0200 Subject: [PATCH] renderer_vulkan: Address various sync issues * Drop Common::SPSCQueue as it sometimes gives garbage frames. * Reduce master semaphore timeout to allow the wait to recover in cases wher it gets stuck --- .../renderer_vulkan/vk_master_semaphore.h | 2 +- .../renderer_vulkan/vk_renderpass_cache.cpp | 2 +- .../renderer_vulkan/vk_scheduler.cpp | 3 --- .../renderer_vulkan/vk_texture_mailbox.cpp | 2 +- .../renderer_vulkan/vk_texture_mailbox.h | 27 ++++++++++++++++--- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_master_semaphore.h b/src/video_core/renderer_vulkan/vk_master_semaphore.h index 55081eab2..2fa33f445 100644 --- a/src/video_core/renderer_vulkan/vk_master_semaphore.h +++ b/src/video_core/renderer_vulkan/vk_master_semaphore.h @@ -15,7 +15,7 @@ namespace Vulkan { class Instance; -constexpr u64 WAIT_TIMEOUT = std::numeric_limits::max(); +constexpr u64 WAIT_TIMEOUT = 1000000000; class MasterSemaphore { public: diff --git a/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp b/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp index d3050ed5a..ccda54a5e 100644 --- a/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp @@ -229,7 +229,7 @@ void RenderpassCache::EndRendering() { // The Mali guide recommends flushing at the end of each major renderpass // Testing has shown this has a significant effect on rendering performance if (cmd_count > 20 && instance.ShouldFlush()) { - scheduler.Flush(); + // scheduler.Flush(); cmd_count = 0; } } diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index 5f8426656..e45a30376 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -74,9 +74,6 @@ void Scheduler::WorkerThread(std::stop_token stop_token) { std::unique_ptr work; { std::unique_lock lock{work_mutex}; - if (work_queue.empty()) { - wait_cv.notify_all(); - } Common::CondvarWait(work_cv, lock, stop_token, [&] { return !work_queue.empty(); }); if (stop_token.stop_requested()) { continue; diff --git a/src/video_core/renderer_vulkan/vk_texture_mailbox.cpp b/src/video_core/renderer_vulkan/vk_texture_mailbox.cpp index 7fbc360e7..4005eed0c 100644 --- a/src/video_core/renderer_vulkan/vk_texture_mailbox.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_mailbox.cpp @@ -45,7 +45,7 @@ PresentMailbox::PresentMailbox(const Instance& instance_, Swapchain& swapchain_, frame.cmdbuf = command_buffers[i]; frame.render_ready = device.createSemaphore({}); frame.present_done = device.createFence({.flags = vk::FenceCreateFlagBits::eSignaled}); - free_queue.Push(&frame); + free_queue.queue.push(&frame); } present_thread = std::jthread([this](std::stop_token token) { PresentThread(token); }); diff --git a/src/video_core/renderer_vulkan/vk_texture_mailbox.h b/src/video_core/renderer_vulkan/vk_texture_mailbox.h index b2ede0662..ca21baf7e 100644 --- a/src/video_core/renderer_vulkan/vk_texture_mailbox.h +++ b/src/video_core/renderer_vulkan/vk_texture_mailbox.h @@ -7,7 +7,6 @@ #include #include #include "common/polyfill_thread.h" -#include "common/threadsafe_queue.h" #include "video_core/renderer_vulkan/vk_common.h" VK_DEFINE_HANDLE(VmaAllocation) @@ -52,6 +51,28 @@ private: void CopyToSwapchain(Frame* frame); void RecreateSwapchain(); + struct FrameQueue { + void Push(Frame* frame) { + std::scoped_lock lock{mutex}; + queue.push(frame); + cv.notify_one(); + } + + Frame* PopWait(std::stop_token token = {}) { + std::unique_lock lock{mutex}; + if (queue.empty()) { + Common::CondvarWait(cv, lock, token, [this] { return !queue.empty(); }); + } + Frame* frame = queue.front(); + queue.pop(); + return frame; + } + + std::queue queue; + std::condition_variable_any cv; + std::mutex mutex; + }; + private: const Instance& instance; Swapchain& swapchain; @@ -60,8 +81,8 @@ private: vk::CommandPool command_pool; vk::Queue graphics_queue; std::array swap_chain{}; - Common::SPSCQueue free_queue{}; - Common::SPSCQueue present_queue{}; + FrameQueue free_queue; + FrameQueue present_queue; std::jthread present_thread; std::mutex swapchain_mutex; std::condition_variable swapchain_cv;