From e5c55ca0e00e4536b5642b2f1591520f9fae7350 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Sat, 1 Mar 2025 14:05:09 +0100 Subject: [PATCH] [dxvk] Add CS thread load to the HUD --- src/dxvk/dxvk_cs.cpp | 21 ++++++++++++++++----- src/dxvk/dxvk_stats.h | 1 + src/dxvk/hud/dxvk_hud_item.cpp | 15 +++++++++++++++ src/dxvk/hud/dxvk_hud_item.h | 4 ++++ 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/dxvk/dxvk_cs.cpp b/src/dxvk/dxvk_cs.cpp index 9e4458981..5803780e5 100644 --- a/src/dxvk/dxvk_cs.cpp +++ b/src/dxvk/dxvk_cs.cpp @@ -202,11 +202,22 @@ namespace dxvk { while (!m_stopped.load()) { { std::unique_lock lock(m_mutex); - m_condOnAdd.wait(lock, [this] { - return (!m_queueOrdered.queue.empty()) - || (!m_queueHighPrio.queue.empty()) - || (m_stopped.load()); - }); + auto pred = [this] { return + !m_queueOrdered.queue.empty() + || !m_queueHighPrio.queue.empty() + || m_stopped.load(); + }; + + if (unlikely(!pred())) { + auto t0 = dxvk::high_resolution_clock::now(); + + m_condOnAdd.wait(lock, [&] { + return pred(); + }); + + auto t1 = dxvk::high_resolution_clock::now(); + m_device->addStatCtr(DxvkStatCounter::CsIdleTicks, std::chrono::duration_cast(t1 - t0).count()); + } std::swap(ordered, m_queueOrdered.queue); std::swap(highPrio, m_queueHighPrio.queue); diff --git a/src/dxvk/dxvk_stats.h b/src/dxvk/dxvk_stats.h index 606e09f8f..0ee777df7 100644 --- a/src/dxvk/dxvk_stats.h +++ b/src/dxvk/dxvk_stats.h @@ -28,6 +28,7 @@ namespace dxvk { GpuIdleTicks, ///< GPU idle time in microseconds CsSyncCount, ///< CS thread synchronizations CsSyncTicks, ///< Time spent waiting on CS + CsIdleTicks, ///< CS thread idle time in microseconds CsChunkCount, ///< Submitted CS chunks DescriptorPoolCount, ///< Descriptor pool count DescriptorSetCount, ///< Descriptor sets allocated diff --git a/src/dxvk/hud/dxvk_hud_item.cpp b/src/dxvk/hud/dxvk_hud_item.cpp index 9c2a2f873..1c6a48df7 100644 --- a/src/dxvk/hud/dxvk_hud_item.cpp +++ b/src/dxvk/hud/dxvk_hud_item.cpp @@ -1446,6 +1446,17 @@ namespace dxvk::hud { ? str::format(m_maxCsSyncCount, " (", (syncTicks / 10), ".", (syncTicks % 10), " ms)") : str::format(m_maxCsSyncCount); + uint64_t currCsIdleTicks = counters.getCtr(DxvkStatCounter::CsIdleTicks); + + m_diffCsIdleTicks = currCsIdleTicks - m_prevCsIdleTicks; + m_prevCsIdleTicks = currCsIdleTicks; + + uint64_t busyTicks = ticks > m_diffCsIdleTicks + ? uint64_t(ticks - m_diffCsIdleTicks) + : uint64_t(0); + + m_csLoadString = str::format((100 * busyTicks) / ticks, "%"); + m_maxCsSyncCount = 0; m_maxCsSyncTicks = 0; @@ -1469,6 +1480,10 @@ namespace dxvk::hud { renderer.drawText(16, position, 0xff40ff40, "CS syncs:"); renderer.drawText(16, { position.x + 132, position.y }, 0xffffffffu, m_csSyncString); + position.y += 20; + renderer.drawText(16, position, 0xff40ff40, "CS load:"); + renderer.drawText(16, { position.x + 132, position.y }, 0xffffffffu, m_csLoadString); + position.y += 8; return position; } diff --git a/src/dxvk/hud/dxvk_hud_item.h b/src/dxvk/hud/dxvk_hud_item.h index 9e6274d17..ce0ede475 100644 --- a/src/dxvk/hud/dxvk_hud_item.h +++ b/src/dxvk/hud/dxvk_hud_item.h @@ -645,14 +645,18 @@ namespace dxvk::hud { uint64_t m_prevCsSyncCount = 0; uint64_t m_prevCsSyncTicks = 0; uint64_t m_prevCsChunks = 0; + uint64_t m_prevCsIdleTicks = 0; uint64_t m_maxCsSyncCount = 0; uint64_t m_maxCsSyncTicks = 0; + uint64_t m_diffCsIdleTicks = 0; + uint64_t m_updateCount = 0; std::string m_csSyncString; std::string m_csChunkString; + std::string m_csLoadString; dxvk::high_resolution_clock::time_point m_lastUpdate = dxvk::high_resolution_clock::now();