Ver Fonte

renderer_vulkan: pause turbo submissions on inactive queue

Liam há 3 anos atrás
pai
commit
c19c8ac92c

+ 2 - 0
src/video_core/renderer_vulkan/renderer_vulkan.cpp

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

+ 5 - 0
src/video_core/renderer_vulkan/vk_scheduler.cpp

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

+ 7 - 0
src/video_core/renderer_vulkan/vk_scheduler.h

@@ -5,6 +5,7 @@
 
 #include <condition_variable>
 #include <cstddef>
+#include <functional>
 #include <memory>
 #include <thread>
 #include <utility>
@@ -66,6 +67,11 @@ public:
         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.
     template <typename T>
     void Record(T&& command) {
@@ -216,6 +222,7 @@ private:
     vk::CommandBuffer current_cmdbuf;
 
     std::unique_ptr<CommandChunk> chunk;
+    std::function<void()> on_submit;
 
     State state;
 

+ 17 - 0
src/video_core/renderer_vulkan/vk_turbo_mode.cpp

@@ -14,11 +14,21 @@ using namespace Common::Literals;
 
 TurboMode::TurboMode(const vk::Instance& instance, const vk::InstanceDispatch& dld)
     : 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); });
 }
 
 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) {
     auto& dld = m_device.GetLogical();
 
@@ -199,6 +209,13 @@ void TurboMode::Run(std::stop_token stop_token) {
 
         // Wait for completion.
         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};
+        });
     }
 }
 

+ 9 - 0
src/video_core/renderer_vulkan/vk_turbo_mode.h

@@ -3,6 +3,9 @@
 
 #pragma once
 
+#include <chrono>
+#include <mutex>
+
 #include "common/polyfill_thread.h"
 #include "video_core/vulkan_common/vulkan_device.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);
     ~TurboMode();
 
+    void QueueSubmitted();
+
 private:
     void Run(std::stop_token stop_token);
 
     Device m_device;
     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;
 };