renderer_vulkan: pause turbo submissions on inactive queue

This commit is contained in:
Liam 2023-01-07 11:56:31 -05:00
parent 432d48d9c8
commit c19c8ac92c
5 changed files with 40 additions and 0 deletions

View File

@ -112,6 +112,7 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_,
state_tracker, scheduler) { state_tracker, scheduler) {
if (Settings::values.renderer_force_max_clock.GetValue() && device.ShouldBoostClocks()) { if (Settings::values.renderer_force_max_clock.GetValue() && device.ShouldBoostClocks()) {
turbo_mode.emplace(instance, dld); turbo_mode.emplace(instance, dld);
scheduler.RegisterOnSubmit([this] { turbo_mode->QueueSubmitted(); });
} }
Report(); Report();
} catch (const vk::Exception& exception) { } catch (const vk::Exception& exception) {
@ -120,6 +121,7 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_,
} }
RendererVulkan::~RendererVulkan() { RendererVulkan::~RendererVulkan() {
scheduler.RegisterOnSubmit([] {});
void(device.GetLogical().WaitIdle()); void(device.GetLogical().WaitIdle());
} }

View File

@ -213,6 +213,11 @@ void Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_s
.signalSemaphoreCount = num_signal_semaphores, .signalSemaphoreCount = num_signal_semaphores,
.pSignalSemaphores = signal_semaphores.data(), .pSignalSemaphores = signal_semaphores.data(),
}; };
if (on_submit) {
on_submit();
}
switch (const VkResult result = device.GetGraphicsQueue().Submit(submit_info)) { switch (const VkResult result = device.GetGraphicsQueue().Submit(submit_info)) {
case VK_SUCCESS: case VK_SUCCESS:
break; break;

View File

@ -5,6 +5,7 @@
#include <condition_variable> #include <condition_variable>
#include <cstddef> #include <cstddef>
#include <functional>
#include <memory> #include <memory>
#include <thread> #include <thread>
#include <utility> #include <utility>
@ -66,6 +67,11 @@ public:
query_cache = &query_cache_; query_cache = &query_cache_;
} }
// Registers a callback to perform on queue submission.
void RegisterOnSubmit(std::function<void()>&& func) {
on_submit = std::move(func);
}
/// Send work to a separate thread. /// Send work to a separate thread.
template <typename T> template <typename T>
void Record(T&& command) { void Record(T&& command) {
@ -216,6 +222,7 @@ private:
vk::CommandBuffer current_cmdbuf; vk::CommandBuffer current_cmdbuf;
std::unique_ptr<CommandChunk> chunk; std::unique_ptr<CommandChunk> chunk;
std::function<void()> on_submit;
State state; State state;

View File

@ -14,11 +14,21 @@ using namespace Common::Literals;
TurboMode::TurboMode(const vk::Instance& instance, const vk::InstanceDispatch& dld) TurboMode::TurboMode(const vk::Instance& instance, const vk::InstanceDispatch& dld)
: m_device{CreateDevice(instance, dld, VK_NULL_HANDLE)}, m_allocator{m_device, false} { : m_device{CreateDevice(instance, dld, VK_NULL_HANDLE)}, m_allocator{m_device, false} {
{
std::scoped_lock lk{m_submission_lock};
m_submission_time = std::chrono::steady_clock::now();
}
m_thread = std::jthread([&](auto stop_token) { Run(stop_token); }); m_thread = std::jthread([&](auto stop_token) { Run(stop_token); });
} }
TurboMode::~TurboMode() = default; TurboMode::~TurboMode() = default;
void TurboMode::QueueSubmitted() {
std::scoped_lock lk{m_submission_lock};
m_submission_time = std::chrono::steady_clock::now();
m_submission_cv.notify_one();
}
void TurboMode::Run(std::stop_token stop_token) { void TurboMode::Run(std::stop_token stop_token) {
auto& dld = m_device.GetLogical(); auto& dld = m_device.GetLogical();
@ -199,6 +209,13 @@ void TurboMode::Run(std::stop_token stop_token) {
// Wait for completion. // Wait for completion.
fence.Wait(); fence.Wait();
// Wait for the next graphics queue submission if necessary.
std::unique_lock lk{m_submission_lock};
Common::CondvarWait(m_submission_cv, lk, stop_token, [this] {
return (std::chrono::steady_clock::now() - m_submission_time) <=
std::chrono::milliseconds{100};
});
} }
} }

View File

@ -3,6 +3,9 @@
#pragma once #pragma once
#include <chrono>
#include <mutex>
#include "common/polyfill_thread.h" #include "common/polyfill_thread.h"
#include "video_core/vulkan_common/vulkan_device.h" #include "video_core/vulkan_common/vulkan_device.h"
#include "video_core/vulkan_common/vulkan_memory_allocator.h" #include "video_core/vulkan_common/vulkan_memory_allocator.h"
@ -15,11 +18,17 @@ public:
explicit TurboMode(const vk::Instance& instance, const vk::InstanceDispatch& dld); explicit TurboMode(const vk::Instance& instance, const vk::InstanceDispatch& dld);
~TurboMode(); ~TurboMode();
void QueueSubmitted();
private: private:
void Run(std::stop_token stop_token); void Run(std::stop_token stop_token);
Device m_device; Device m_device;
MemoryAllocator m_allocator; MemoryAllocator m_allocator;
std::mutex m_submission_lock;
std::condition_variable_any m_submission_cv;
std::chrono::time_point<std::chrono::steady_clock> m_submission_time{};
std::jthread m_thread; std::jthread m_thread;
}; };