From 057961a1aec9d82b24337c96c2ed902d4b3bc4c8 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Wed, 7 Feb 2024 00:12:01 +0100 Subject: [PATCH] [d3d9] Use most recently used swapchain for GetFrontBufferData --- src/d3d9/d3d9_device.cpp | 6 +++++- src/d3d9/d3d9_device.h | 14 ++++++++++++++ src/d3d9/d3d9_swapchain.cpp | 10 ++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index a5fc7f5da32..ce3cd9c6108 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -1083,7 +1083,10 @@ namespace dxvk { if (unlikely(iSwapChain != 0)) return D3DERR_INVALIDCALL; - return m_implicitSwapchain->GetFrontBufferData(pDestSurface); + // In windowed mode, GetFrontBufferData takes a screenshot of the entire screen. + // We use the last used swapchain as a workaround. + // Total War: Medieval 2 relies on this. + return m_mostRecentlyUsedSwapchain->GetFrontBufferData(pDestSurface); } @@ -7813,6 +7816,7 @@ namespace dxvk { } else m_implicitSwapchain = new D3D9SwapChainEx(this, pPresentationParameters, pFullscreenDisplayMode); + m_mostRecentlyUsedSwapchain = m_implicitSwapchain.ptr(); if (pPresentationParameters->EnableAutoDepthStencil) { D3D9_COMMON_TEXTURE_DESC desc; diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 2fc74c83656..e72ac514c50 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -1241,6 +1241,18 @@ namespace dxvk { uint64_t GetCurrentSequenceNumber(); + D3D9SwapChainEx* GetLastUsedSwapchain() { + return m_mostRecentlyUsedSwapchain; + } + + void SetLastUsedSwapchain(D3D9SwapChainEx* swapchain) { + m_mostRecentlyUsedSwapchain = swapchain; + } + + void ResetLastUsedSwapchain() { + m_mostRecentlyUsedSwapchain = m_implicitSwapchain.ptr(); + } + Com m_parent; D3DDEVTYPE m_deviceType; HWND m_window; @@ -1403,6 +1415,8 @@ namespace dxvk { HWND m_fullscreenWindow = NULL; std::atomic m_losableResourceCounter = { 0 }; + D3D9SwapChainEx* m_mostRecentlyUsedSwapchain = nullptr; + #ifdef D3D9_ALLOW_UNMAPPING lru_list m_mappedTextures; #endif diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index a19ca55aafa..6dddb6929b2 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -65,6 +65,14 @@ namespace dxvk { if (this_thread::isInModuleDetachment()) return; + { + D3D9DeviceLock lock = m_parent->LockDevice(); + + if (m_parent->GetLastUsedSwapchain() == this) { + m_parent->ResetLastUsedSwapchain(); + } + } + DestroyBackBuffers(); ResetWindowProc(m_window); @@ -112,6 +120,8 @@ namespace dxvk { DWORD dwFlags) { D3D9DeviceLock lock = m_parent->LockDevice(); + m_parent->SetLastUsedSwapchain(this); + if (unlikely(m_parent->IsDeviceLost())) return D3DERR_DEVICELOST;