Merge pull request #9581 from liamwhite/turbo2
renderer_vulkan: pause turbo submissions on inactive queue
This commit is contained in:
		| @@ -99,6 +99,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) { | ||||||
| @@ -107,6 +108,7 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_, | |||||||
| } | } | ||||||
|  |  | ||||||
| RendererVulkan::~RendererVulkan() { | RendererVulkan::~RendererVulkan() { | ||||||
|  |     scheduler.RegisterOnSubmit([] {}); | ||||||
|     void(device.GetLogical().WaitIdle()); |     void(device.GetLogical().WaitIdle()); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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; | ||||||
|   | |||||||
| @@ -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; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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}; | ||||||
|  |         }); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user