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
This commit is contained in:
@@ -15,7 +15,7 @@ namespace Vulkan {
|
||||
|
||||
class Instance;
|
||||
|
||||
constexpr u64 WAIT_TIMEOUT = std::numeric_limits<u64>::max();
|
||||
constexpr u64 WAIT_TIMEOUT = 1000000000;
|
||||
|
||||
class MasterSemaphore {
|
||||
public:
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -74,9 +74,6 @@ void Scheduler::WorkerThread(std::stop_token stop_token) {
|
||||
std::unique_ptr<CommandChunk> 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;
|
||||
|
@@ -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); });
|
||||
|
@@ -7,7 +7,6 @@
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#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<Frame*> 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<Frame, SWAP_CHAIN_SIZE> swap_chain{};
|
||||
Common::SPSCQueue<Frame*> free_queue{};
|
||||
Common::SPSCQueue<Frame*, true> present_queue{};
|
||||
FrameQueue free_queue;
|
||||
FrameQueue present_queue;
|
||||
std::jthread present_thread;
|
||||
std::mutex swapchain_mutex;
|
||||
std::condition_variable swapchain_cv;
|
||||
|
Reference in New Issue
Block a user