From 9fa587e13c469bde8761175f4fa1ae6dfdcf6d17 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 17 Sep 2022 05:01:36 +0200 Subject: [PATCH] [dxgi] Always use swap chain-local present count for frame statistics Doesn't appear to match Windows behaviour, but there may be scenarios when we can't query the current monitor. Statistics still need to be consistent in this case. See #2933. --- src/dxgi/dxgi_swapchain.cpp | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 9d7bb47f2..3ebf48346 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -177,7 +177,16 @@ namespace dxvk { if (!std::exchange(s_errorShown, true)) Logger::warn("DxgiSwapChain::GetFrameStatistics: Frame statistics may be inaccurate"); - // If possible, use the monitor's frame statistics + // Populate frame statistics with local present count and current time + auto t1Counter = dxvk::high_resolution_clock::get_counter(); + + pStats->PresentCount = m_presentCount; + pStats->PresentRefreshCount = 0; + pStats->SyncRefreshCount = 0; + pStats->SyncQPCTime.QuadPart = t1Counter; + pStats->SyncGPUTime.QuadPart = 0; + + // If possible, use the monitor's frame statistics for vblank stats DXGI_VK_MONITOR_DATA* monitorData = nullptr; if (SUCCEEDED(AcquireMonitorData(m_monitor, &monitorData))) { @@ -185,24 +194,13 @@ namespace dxvk { monitorData->LastMode.RefreshRate.Numerator, monitorData->LastMode.RefreshRate.Denominator); - auto t1Counter = dxvk::high_resolution_clock::get_counter(); - auto t0 = dxvk::high_resolution_clock::get_time_from_counter(monitorData->FrameStats.SyncQPCTime.QuadPart); auto t1 = dxvk::high_resolution_clock::get_time_from_counter(t1Counter); - pStats->PresentCount = monitorData->FrameStats.PresentCount; pStats->PresentRefreshCount = monitorData->FrameStats.PresentRefreshCount; pStats->SyncRefreshCount = monitorData->FrameStats.SyncRefreshCount + computeRefreshCount(t0, t1, refreshPeriod); - pStats->SyncQPCTime.QuadPart = t1Counter; - pStats->SyncGPUTime.QuadPart = 0; ReleaseMonitorData(); - } else { - pStats->PresentCount = m_presentCount; - pStats->PresentRefreshCount = 0; - pStats->SyncRefreshCount = 0; - pStats->SyncQPCTime.QuadPart = dxvk::high_resolution_clock::get_counter(); - pStats->SyncGPUTime.QuadPart = 0; } return S_OK; @@ -300,7 +298,7 @@ namespace dxvk { } // Update frame statistics - DXGI_VK_MONITOR_DATA* monitorData; + DXGI_VK_MONITOR_DATA* monitorData = nullptr; if (SUCCEEDED(AcquireMonitorData(m_monitor, &monitorData))) { auto refreshPeriod = computeRefreshPeriod( @@ -313,10 +311,9 @@ namespace dxvk { monitorData->FrameStats.PresentCount += 1; monitorData->FrameStats.PresentRefreshCount = monitorData->FrameStats.SyncRefreshCount + computeRefreshCount(t0, t1, refreshPeriod); ReleaseMonitorData(); - } else { - m_presentCount += 1; } + m_presentCount += 1; return S_OK; }