diff options
| -rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_scheduler.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_scheduler.h | 7 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_turbo_mode.cpp | 17 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_turbo_mode.h | 9 |
5 files changed, 40 insertions, 0 deletions
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 52855120c..8233c07d3 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp | |||
| @@ -112,6 +112,7 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_, | |||
| 112 | state_tracker, scheduler) { | 112 | state_tracker, scheduler) { |
| 113 | if (Settings::values.renderer_force_max_clock.GetValue() && device.ShouldBoostClocks()) { | 113 | if (Settings::values.renderer_force_max_clock.GetValue() && device.ShouldBoostClocks()) { |
| 114 | turbo_mode.emplace(instance, dld); | 114 | turbo_mode.emplace(instance, dld); |
| 115 | scheduler.RegisterOnSubmit([this] { turbo_mode->QueueSubmitted(); }); | ||
| 115 | } | 116 | } |
| 116 | Report(); | 117 | Report(); |
| 117 | } catch (const vk::Exception& exception) { | 118 | } catch (const vk::Exception& exception) { |
| @@ -120,6 +121,7 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_, | |||
| 120 | } | 121 | } |
| 121 | 122 | ||
| 122 | RendererVulkan::~RendererVulkan() { | 123 | RendererVulkan::~RendererVulkan() { |
| 124 | scheduler.RegisterOnSubmit([] {}); | ||
| 123 | void(device.GetLogical().WaitIdle()); | 125 | void(device.GetLogical().WaitIdle()); |
| 124 | } | 126 | } |
| 125 | 127 | ||
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index c2e53a5d5..e03685af1 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp | |||
| @@ -213,6 +213,11 @@ void Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_s | |||
| 213 | .signalSemaphoreCount = num_signal_semaphores, | 213 | .signalSemaphoreCount = num_signal_semaphores, |
| 214 | .pSignalSemaphores = signal_semaphores.data(), | 214 | .pSignalSemaphores = signal_semaphores.data(), |
| 215 | }; | 215 | }; |
| 216 | |||
| 217 | if (on_submit) { | ||
| 218 | on_submit(); | ||
| 219 | } | ||
| 220 | |||
| 216 | switch (const VkResult result = device.GetGraphicsQueue().Submit(submit_info)) { | 221 | switch (const VkResult result = device.GetGraphicsQueue().Submit(submit_info)) { |
| 217 | case VK_SUCCESS: | 222 | case VK_SUCCESS: |
| 218 | break; | 223 | break; |
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.h b/src/video_core/renderer_vulkan/vk_scheduler.h index 3858c506c..bd4cb0f7e 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.h +++ b/src/video_core/renderer_vulkan/vk_scheduler.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | #include <condition_variable> | 6 | #include <condition_variable> |
| 7 | #include <cstddef> | 7 | #include <cstddef> |
| 8 | #include <functional> | ||
| 8 | #include <memory> | 9 | #include <memory> |
| 9 | #include <thread> | 10 | #include <thread> |
| 10 | #include <utility> | 11 | #include <utility> |
| @@ -66,6 +67,11 @@ public: | |||
| 66 | query_cache = &query_cache_; | 67 | query_cache = &query_cache_; |
| 67 | } | 68 | } |
| 68 | 69 | ||
| 70 | // Registers a callback to perform on queue submission. | ||
| 71 | void RegisterOnSubmit(std::function<void()>&& func) { | ||
| 72 | on_submit = std::move(func); | ||
| 73 | } | ||
| 74 | |||
| 69 | /// Send work to a separate thread. | 75 | /// Send work to a separate thread. |
| 70 | template <typename T> | 76 | template <typename T> |
| 71 | void Record(T&& command) { | 77 | void Record(T&& command) { |
| @@ -216,6 +222,7 @@ private: | |||
| 216 | vk::CommandBuffer current_cmdbuf; | 222 | vk::CommandBuffer current_cmdbuf; |
| 217 | 223 | ||
| 218 | std::unique_ptr<CommandChunk> chunk; | 224 | std::unique_ptr<CommandChunk> chunk; |
| 225 | std::function<void()> on_submit; | ||
| 219 | 226 | ||
| 220 | State state; | 227 | State state; |
| 221 | 228 | ||
diff --git a/src/video_core/renderer_vulkan/vk_turbo_mode.cpp b/src/video_core/renderer_vulkan/vk_turbo_mode.cpp index 852b86f84..c42594149 100644 --- a/src/video_core/renderer_vulkan/vk_turbo_mode.cpp +++ b/src/video_core/renderer_vulkan/vk_turbo_mode.cpp | |||
| @@ -14,11 +14,21 @@ using namespace Common::Literals; | |||
| 14 | 14 | ||
| 15 | TurboMode::TurboMode(const vk::Instance& instance, const vk::InstanceDispatch& dld) | 15 | TurboMode::TurboMode(const vk::Instance& instance, const vk::InstanceDispatch& dld) |
| 16 | : m_device{CreateDevice(instance, dld, VK_NULL_HANDLE)}, m_allocator{m_device, false} { | 16 | : m_device{CreateDevice(instance, dld, VK_NULL_HANDLE)}, m_allocator{m_device, false} { |
| 17 | { | ||
| 18 | std::scoped_lock lk{m_submission_lock}; | ||
| 19 | m_submission_time = std::chrono::steady_clock::now(); | ||
| 20 | } | ||
| 17 | m_thread = std::jthread([&](auto stop_token) { Run(stop_token); }); | 21 | m_thread = std::jthread([&](auto stop_token) { Run(stop_token); }); |
| 18 | } | 22 | } |
| 19 | 23 | ||
| 20 | TurboMode::~TurboMode() = default; | 24 | TurboMode::~TurboMode() = default; |
| 21 | 25 | ||
| 26 | void TurboMode::QueueSubmitted() { | ||
| 27 | std::scoped_lock lk{m_submission_lock}; | ||
| 28 | m_submission_time = std::chrono::steady_clock::now(); | ||
| 29 | m_submission_cv.notify_one(); | ||
| 30 | } | ||
| 31 | |||
| 22 | void TurboMode::Run(std::stop_token stop_token) { | 32 | void TurboMode::Run(std::stop_token stop_token) { |
| 23 | auto& dld = m_device.GetLogical(); | 33 | auto& dld = m_device.GetLogical(); |
| 24 | 34 | ||
| @@ -199,6 +209,13 @@ void TurboMode::Run(std::stop_token stop_token) { | |||
| 199 | 209 | ||
| 200 | // Wait for completion. | 210 | // Wait for completion. |
| 201 | fence.Wait(); | 211 | fence.Wait(); |
| 212 | |||
| 213 | // Wait for the next graphics queue submission if necessary. | ||
| 214 | std::unique_lock lk{m_submission_lock}; | ||
| 215 | Common::CondvarWait(m_submission_cv, lk, stop_token, [this] { | ||
| 216 | return (std::chrono::steady_clock::now() - m_submission_time) <= | ||
| 217 | std::chrono::milliseconds{100}; | ||
| 218 | }); | ||
| 202 | } | 219 | } |
| 203 | } | 220 | } |
| 204 | 221 | ||
diff --git a/src/video_core/renderer_vulkan/vk_turbo_mode.h b/src/video_core/renderer_vulkan/vk_turbo_mode.h index 2060e2395..99b5ac50b 100644 --- a/src/video_core/renderer_vulkan/vk_turbo_mode.h +++ b/src/video_core/renderer_vulkan/vk_turbo_mode.h | |||
| @@ -3,6 +3,9 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <chrono> | ||
| 7 | #include <mutex> | ||
| 8 | |||
| 6 | #include "common/polyfill_thread.h" | 9 | #include "common/polyfill_thread.h" |
| 7 | #include "video_core/vulkan_common/vulkan_device.h" | 10 | #include "video_core/vulkan_common/vulkan_device.h" |
| 8 | #include "video_core/vulkan_common/vulkan_memory_allocator.h" | 11 | #include "video_core/vulkan_common/vulkan_memory_allocator.h" |
| @@ -15,11 +18,17 @@ public: | |||
| 15 | explicit TurboMode(const vk::Instance& instance, const vk::InstanceDispatch& dld); | 18 | explicit TurboMode(const vk::Instance& instance, const vk::InstanceDispatch& dld); |
| 16 | ~TurboMode(); | 19 | ~TurboMode(); |
| 17 | 20 | ||
| 21 | void QueueSubmitted(); | ||
| 22 | |||
| 18 | private: | 23 | private: |
| 19 | void Run(std::stop_token stop_token); | 24 | void Run(std::stop_token stop_token); |
| 20 | 25 | ||
| 21 | Device m_device; | 26 | Device m_device; |
| 22 | MemoryAllocator m_allocator; | 27 | MemoryAllocator m_allocator; |
| 28 | std::mutex m_submission_lock; | ||
| 29 | std::condition_variable_any m_submission_cv; | ||
| 30 | std::chrono::time_point<std::chrono::steady_clock> m_submission_time{}; | ||
| 31 | |||
| 23 | std::jthread m_thread; | 32 | std::jthread m_thread; |
| 24 | }; | 33 | }; |
| 25 | 34 | ||