From 758dc805bbf7453ec328429c7bbbc97f6b62494d Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Thu, 5 Sep 2024 20:58:01 -0600 Subject: [PATCH] [dxgi] Prevent recursive fullscreen mode change. --- src/dxgi/dxgi_swapchain.cpp | 14 +++++++++++++- src/dxgi/dxgi_swapchain.h | 1 + src/util/util_misc.h | 12 +++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 682473065..5319db1d6 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -658,6 +658,12 @@ namespace dxvk { HRESULT DxgiSwapChain::EnterFullscreenMode(IDXGIOutput1* pTarget) { + if (m_ModeChangeInProgress) { + Logger::warn("Nested EnterFullscreenMode"); + return DXGI_STATUS_MODE_CHANGE_IN_PROGRESS; + } + scoped_bool in_progress(m_ModeChangeInProgress); + Com output = pTarget; if (!wsi::isWindow(m_window)) @@ -718,6 +724,12 @@ namespace dxvk { HRESULT DxgiSwapChain::LeaveFullscreenMode() { + if (m_ModeChangeInProgress) { + Logger::warn("Nested LeaveFullscreenMode"); + return DXGI_STATUS_MODE_CHANGE_IN_PROGRESS; + } + scoped_bool in_progress(m_ModeChangeInProgress); + if (FAILED(RestoreDisplayMode(m_monitor))) Logger::warn("DXGI: LeaveFullscreenMode: Failed to restore display mode"); @@ -731,7 +743,7 @@ namespace dxvk { SetGammaControl(0, nullptr); ReleaseMonitorData(); } - + // Restore internal state m_descFs.Windowed = TRUE; m_target = nullptr; diff --git a/src/dxgi/dxgi_swapchain.h b/src/dxgi/dxgi_swapchain.h index 4bdad9d0f..73be5ab7a 100644 --- a/src/dxgi/dxgi_swapchain.h +++ b/src/dxgi/dxgi_swapchain.h @@ -184,6 +184,7 @@ namespace dxvk { DXGI_SWAP_CHAIN_DESC1 m_desc; DXGI_SWAP_CHAIN_FULLSCREEN_DESC m_descFs; UINT m_presentId; + bool m_ModeChangeInProgress = false; Com m_presenter; Com m_presenter1; diff --git a/src/util/util_misc.h b/src/util/util_misc.h index da56f6448..12ee99980 100644 --- a/src/util/util_misc.h +++ b/src/util/util_misc.h @@ -43,4 +43,14 @@ namespace dxvk { return duration.count() / refreshPeriod.count(); } -} \ No newline at end of file + struct scoped_bool { + scoped_bool(bool &v) : m_val(v) { + m_val = true; + } + ~scoped_bool() { + m_val = false; + } + + bool& m_val; + }; +}