From 066aedf08583f4e19d8f6fe0ede988922709f4a9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 17 Jan 2025 23:21:31 +0100 Subject: [PATCH] [d3d9] Pass display refresh rate around in windowed mode --- src/d3d9/d3d9_swapchain.cpp | 47 +++++++++++++++++++++++++++++-------- src/d3d9/d3d9_swapchain.h | 4 ++-- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index f68c5ed27..13c29c41c 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -171,6 +171,7 @@ namespace dxvk { // We aren't going to device loss simply because // 99% of D3D9 games don't handle this properly and // just end up crashing (like with alt-tab loss) + UpdateDisplayRefreshRate(); UpdateTargetFrameRate(presentInterval); PresentImage(presentInterval); return D3D_OK; @@ -980,7 +981,11 @@ namespace dxvk { m_latencyTracker = m_device->createLatencyTracker(entry->second.presenter); } - m_wctx = &entry->second; + if (m_wctx != &entry->second) { + m_wctx = &entry->second; + m_displayRefreshRateDirty = true; + } + return true; } @@ -1168,9 +1173,35 @@ namespace dxvk { } - void D3D9SwapChainEx::NotifyDisplayRefreshRate( - double RefreshRate) { - m_displayRefreshRate = RefreshRate; + void D3D9SwapChainEx::UpdateDisplayRefreshRate() { + if (!m_displayRefreshRateDirty) + return; + + m_displayRefreshRateDirty = false; + + if (!m_monitor && m_window != m_presentParams.hDeviceWindow) { + m_displayRefreshRate = 0.0; + return; + } + + HMONITOR monitor = m_monitor; + + if (!monitor) + monitor = wsi::getWindowMonitor(m_window); + + if (!monitor) { + m_displayRefreshRate = 0.0; + return; + } + + wsi::WsiMode wsiMode = { }; + + if (wsi::getCurrentDisplayMode(monitor, &wsiMode)) { + m_displayRefreshRate = double(wsiMode.refreshRate.numerator) + / double(wsiMode.refreshRate.denominator); + } else { + m_displayRefreshRate = 0.0; + } } @@ -1250,11 +1281,7 @@ namespace dxvk { if (!wsi::setWindowMode(monitor, m_window, &m_windowState, wsiMode)) return D3DERR_NOTAVAILABLE; - if (wsi::getCurrentDisplayMode(monitor, &wsiMode)) - NotifyDisplayRefreshRate(double(wsiMode.refreshRate.numerator) / double(wsiMode.refreshRate.denominator)); - else - NotifyDisplayRefreshRate(0.0); - + m_displayRefreshRateDirty = true; return D3D_OK; } @@ -1266,7 +1293,7 @@ namespace dxvk { if (!wsi::restoreDisplayMode()) return D3DERR_NOTAVAILABLE; - NotifyDisplayRefreshRate(0.0); + m_displayRefreshRateDirty = true; return D3D_OK; } diff --git a/src/d3d9/d3d9_swapchain.h b/src/d3d9/d3d9_swapchain.h index 9f69e44c5..cbc42c0bc 100644 --- a/src/d3d9/d3d9_swapchain.h +++ b/src/d3d9/d3d9_swapchain.h @@ -173,6 +173,7 @@ namespace dxvk { wsi::DxvkWindowState m_windowState; + bool m_displayRefreshRateDirty = true; double m_displayRefreshRate = 0.0; double m_targetFrameRate = 0.0; @@ -215,8 +216,7 @@ namespace dxvk { void NormalizePresentParameters(D3DPRESENT_PARAMETERS* pPresentParams); - void NotifyDisplayRefreshRate( - double RefreshRate); + void UpdateDisplayRefreshRate(); HRESULT EnterFullscreenMode( D3DPRESENT_PARAMETERS* pPresentParams,