Merge pull request #11417 from K0bin/vk-submit-thread-cleanup

VideoBackends:Vulkan: Clean up submission thread using WorkQueueThread
This commit is contained in:
Pierre Bourdon 2023-04-04 22:02:39 +02:00 committed by GitHub
commit d8fabd37fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 11 additions and 53 deletions

View File

@ -124,7 +124,7 @@ public:
if (m_idle && !m_cancelling.load()) if (m_idle && !m_cancelling.load())
return; return;
m_wait_cond_var.wait(lg, [&] { return m_idle && m_cancelling.load(); }); m_wait_cond_var.wait(lg, [&] { return m_idle && !m_cancelling; });
} }
// If the worker polls IsCanceling(), it can abort its work when Cancelling // If the worker polls IsCanceling(), it can abort its work when Cancelling

View File

@ -26,8 +26,7 @@ CommandBufferManager::~CommandBufferManager()
if (m_use_threaded_submission) if (m_use_threaded_submission)
{ {
WaitForWorkerThreadIdle(); WaitForWorkerThreadIdle();
m_submit_loop->Stop(); m_submit_thread.Shutdown();
m_submit_thread.join();
} }
DestroyCommandBuffers(); DestroyCommandBuffers();
@ -221,40 +220,11 @@ VkDescriptorSet CommandBufferManager::AllocateDescriptorSet(VkDescriptorSetLayou
bool CommandBufferManager::CreateSubmitThread() bool CommandBufferManager::CreateSubmitThread()
{ {
m_submit_loop = std::make_unique<Common::BlockingLoop>(); m_submit_thread.Reset("VK submission thread", [this](PendingCommandBufferSubmit submit) {
m_submit_thread = std::thread([this]() {
Common::SetCurrentThreadName("Vulkan CommandBufferManager SubmitThread");
m_submit_loop->Run([this]() {
PendingCommandBufferSubmit submit;
{
std::lock_guard<std::mutex> guard(m_pending_submit_lock);
if (m_pending_submits.empty())
{
m_submit_loop->AllowSleep();
m_submit_worker_idle = true;
m_submit_worker_condvar.notify_all();
return;
}
submit = m_pending_submits.front();
m_pending_submits.pop_front();
}
SubmitCommandBuffer(submit.command_buffer_index, submit.present_swap_chain, SubmitCommandBuffer(submit.command_buffer_index, submit.present_swap_chain,
submit.present_image_index); submit.present_image_index);
CmdBufferResources& resources = m_command_buffers[submit.command_buffer_index]; CmdBufferResources& resources = m_command_buffers[submit.command_buffer_index];
resources.waiting_for_submit.store(false, std::memory_order_release); resources.waiting_for_submit.store(false, std::memory_order_release);
{
std::lock_guard<std::mutex> guard(m_pending_submit_lock);
if (m_pending_submits.empty())
{
m_submit_worker_idle = true;
m_submit_worker_condvar.notify_all();
}
}
});
}); });
return true; return true;
@ -265,8 +235,7 @@ void CommandBufferManager::WaitForWorkerThreadIdle()
if (!m_use_threaded_submission) if (!m_use_threaded_submission)
return; return;
std::unique_lock lock{m_pending_submit_lock}; m_submit_thread.WaitForCompletion();
m_submit_worker_condvar.wait(lock, [&] { return m_submit_worker_idle; });
} }
void CommandBufferManager::WaitForFenceCounter(u64 fence_counter) void CommandBufferManager::WaitForFenceCounter(u64 fence_counter)
@ -352,14 +321,7 @@ void CommandBufferManager::SubmitCommandBuffer(bool submit_on_worker_thread,
{ {
resources.waiting_for_submit.store(true, std::memory_order_relaxed); resources.waiting_for_submit.store(true, std::memory_order_relaxed);
// Push to the pending submit queue. // Push to the pending submit queue.
{ m_submit_thread.Push({present_swap_chain, present_image_index, m_current_cmd_buffer});
std::lock_guard<std::mutex> guard(m_pending_submit_lock);
m_submit_worker_idle = false;
m_pending_submits.push_back({present_swap_chain, present_image_index, m_current_cmd_buffer});
}
// Wake up the worker thread for a single iteration.
m_submit_loop->Wakeup();
} }
else else
{ {

View File

@ -14,6 +14,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <Common/WorkQueueThread.h>
#include "Common/BlockingLoop.h" #include "Common/BlockingLoop.h"
#include "Common/Flag.h" #include "Common/Flag.h"
#include "Common/Semaphore.h" #include "Common/Semaphore.h"
@ -146,19 +147,14 @@ private:
u32 m_current_cmd_buffer = 0; u32 m_current_cmd_buffer = 0;
// Threaded command buffer execution // Threaded command buffer execution
std::thread m_submit_thread;
std::unique_ptr<Common::BlockingLoop> m_submit_loop;
struct PendingCommandBufferSubmit struct PendingCommandBufferSubmit
{ {
VkSwapchainKHR present_swap_chain; VkSwapchainKHR present_swap_chain;
u32 present_image_index; u32 present_image_index;
u32 command_buffer_index; u32 command_buffer_index;
}; };
Common::WorkQueueThread<PendingCommandBufferSubmit> m_submit_thread;
VkSemaphore m_present_semaphore = VK_NULL_HANDLE; VkSemaphore m_present_semaphore = VK_NULL_HANDLE;
std::deque<PendingCommandBufferSubmit> m_pending_submits;
std::mutex m_pending_submit_lock;
std::condition_variable m_submit_worker_condvar;
bool m_submit_worker_idle = true;
Common::Flag m_last_present_failed; Common::Flag m_last_present_failed;
Common::Flag m_last_present_done; Common::Flag m_last_present_done;
VkResult m_last_present_result = VK_SUCCESS; VkResult m_last_present_result = VK_SUCCESS;