mirror of https://github.com/doitsujin/dxvk
[d3d9] Use most recently used swapchain for GetFrontBufferData
This commit is contained in:
parent
eaa732d0b3
commit
a0e39e94fa
|
@ -1093,7 +1093,12 @@ namespace dxvk {
|
||||||
if (unlikely(iSwapChain != 0))
|
if (unlikely(iSwapChain != 0))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
return m_implicitSwapchain->GetFrontBufferData(pDestSurface);
|
D3D9DeviceLock lock = LockDevice();
|
||||||
|
|
||||||
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -7839,6 +7844,7 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_implicitSwapchain = new D3D9SwapChainEx(this, pPresentationParameters, pFullscreenDisplayMode);
|
m_implicitSwapchain = new D3D9SwapChainEx(this, pPresentationParameters, pFullscreenDisplayMode);
|
||||||
|
m_mostRecentlyUsedSwapchain = m_implicitSwapchain.ptr();
|
||||||
|
|
||||||
if (pPresentationParameters->EnableAutoDepthStencil) {
|
if (pPresentationParameters->EnableAutoDepthStencil) {
|
||||||
D3D9_COMMON_TEXTURE_DESC desc;
|
D3D9_COMMON_TEXTURE_DESC desc;
|
||||||
|
|
|
@ -1241,6 +1241,34 @@ namespace dxvk {
|
||||||
|
|
||||||
uint64_t GetCurrentSequenceNumber();
|
uint64_t GetCurrentSequenceNumber();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the swapchain that was used the most recently for presenting
|
||||||
|
* Has to be externally synchronized.
|
||||||
|
*
|
||||||
|
* @return D3D9SwapChainEx* Swapchain
|
||||||
|
*/
|
||||||
|
D3D9SwapChainEx* GetMostRecentlyUsedSwapchain() {
|
||||||
|
return m_mostRecentlyUsedSwapchain;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the swapchain that was used the most recently for presenting
|
||||||
|
* Has to be externally synchronized.
|
||||||
|
*
|
||||||
|
* @param swapchain Swapchain
|
||||||
|
*/
|
||||||
|
void SetMostRecentlyUsedSwapchain(D3D9SwapChainEx* swapchain) {
|
||||||
|
m_mostRecentlyUsedSwapchain = swapchain;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset the most recently swapchain back to the implicit one
|
||||||
|
* Has to be externally synchronized.
|
||||||
|
*/
|
||||||
|
void ResetMostRecentlyUsedSwapchain() {
|
||||||
|
m_mostRecentlyUsedSwapchain = m_implicitSwapchain.ptr();
|
||||||
|
}
|
||||||
|
|
||||||
Com<D3D9InterfaceEx> m_parent;
|
Com<D3D9InterfaceEx> m_parent;
|
||||||
D3DDEVTYPE m_deviceType;
|
D3DDEVTYPE m_deviceType;
|
||||||
HWND m_window;
|
HWND m_window;
|
||||||
|
@ -1403,6 +1431,8 @@ namespace dxvk {
|
||||||
HWND m_fullscreenWindow = NULL;
|
HWND m_fullscreenWindow = NULL;
|
||||||
std::atomic<uint32_t> m_losableResourceCounter = { 0 };
|
std::atomic<uint32_t> m_losableResourceCounter = { 0 };
|
||||||
|
|
||||||
|
D3D9SwapChainEx* m_mostRecentlyUsedSwapchain = nullptr;
|
||||||
|
|
||||||
#ifdef D3D9_ALLOW_UNMAPPING
|
#ifdef D3D9_ALLOW_UNMAPPING
|
||||||
lru_list<D3D9CommonTexture*> m_mappedTextures;
|
lru_list<D3D9CommonTexture*> m_mappedTextures;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -65,6 +65,16 @@ namespace dxvk {
|
||||||
if (this_thread::isInModuleDetachment())
|
if (this_thread::isInModuleDetachment())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
{
|
||||||
|
// Locking here and in Device::GetFrontBufferData
|
||||||
|
// ensures that other threads don't accidentally access a stale pointer.
|
||||||
|
D3D9DeviceLock lock = m_parent->LockDevice();
|
||||||
|
|
||||||
|
if (m_parent->GetMostRecentlyUsedSwapchain() == this) {
|
||||||
|
m_parent->ResetMostRecentlyUsedSwapchain();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DestroyBackBuffers();
|
DestroyBackBuffers();
|
||||||
|
|
||||||
ResetWindowProc(m_window);
|
ResetWindowProc(m_window);
|
||||||
|
@ -112,6 +122,8 @@ namespace dxvk {
|
||||||
DWORD dwFlags) {
|
DWORD dwFlags) {
|
||||||
D3D9DeviceLock lock = m_parent->LockDevice();
|
D3D9DeviceLock lock = m_parent->LockDevice();
|
||||||
|
|
||||||
|
m_parent->SetMostRecentlyUsedSwapchain(this);
|
||||||
|
|
||||||
if (unlikely(m_parent->IsDeviceLost()))
|
if (unlikely(m_parent->IsDeviceLost()))
|
||||||
return D3DERR_DEVICELOST;
|
return D3DERR_DEVICELOST;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue