From 3d86ecd94dae0936cfa770b001473921119ee18e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 18 Jul 2019 22:52:20 +0200 Subject: [PATCH] [dxvk] Estimate GPU idle time based on cleanup thread activity We'll assume that GPU idle time == time spent waiting for new command lists to be added to the queue of the cleanup thread. This isn't entirely accurate, especially if CPU load is very high, but should be good enough. --- src/dxvk/dxvk_queue.cpp | 13 ++++++++++--- src/dxvk/dxvk_queue.h | 13 +++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_queue.cpp b/src/dxvk/dxvk_queue.cpp index 53cf838b1..746475a22 100644 --- a/src/dxvk/dxvk_queue.cpp +++ b/src/dxvk/dxvk_queue.cpp @@ -137,9 +137,16 @@ namespace dxvk { std::unique_lock lock(m_mutex); while (!m_stopped.load()) { - m_submitCond.wait(lock, [this] { - return m_stopped.load() || !m_finishQueue.empty(); - }); + if (m_finishQueue.empty()) { + auto t0 = std::chrono::high_resolution_clock::now(); + + m_submitCond.wait(lock, [this] { + return m_stopped.load() || !m_finishQueue.empty(); + }); + + auto t1 = std::chrono::high_resolution_clock::now(); + m_gpuIdle += std::chrono::duration_cast(t1 - t0).count(); + } if (m_stopped.load()) return; diff --git a/src/dxvk/dxvk_queue.h b/src/dxvk/dxvk_queue.h index 59b77fb87..50ea26b52 100644 --- a/src/dxvk/dxvk_queue.h +++ b/src/dxvk/dxvk_queue.h @@ -80,6 +80,18 @@ namespace dxvk { uint32_t pendingSubmissions() const { return m_pending.load(); } + + /** + * \brief Retrieves estimated GPU idle time + * + * This is a monotonically increasing counter + * which can be evaluated periodically in order + * to calculate the GPU load. + * \returns Accumulated GPU idle time, in us + */ + uint64_t gpuIdleTicks() const { + return m_gpuIdle.load(); + } /** * \brief Submits a command list asynchronously @@ -147,6 +159,7 @@ namespace dxvk { std::atomic m_stopped = { false }; std::atomic m_pending = { 0u }; + std::atomic m_gpuIdle = { 0ull }; std::mutex m_mutex; std::mutex m_mutexQueue;