diff --git a/src/d3d9/d3d9_options.cpp b/src/d3d9/d3d9_options.cpp index f4a5ee78..bc06dde6 100644 --- a/src/d3d9/d3d9_options.cpp +++ b/src/d3d9/d3d9_options.cpp @@ -47,6 +47,7 @@ namespace dxvk { this->strictPow = config.getOption ("d3d9.strictPow", true); this->lenientClear = config.getOption ("d3d9.lenientClear", false); this->numBackBuffers = config.getOption ("d3d9.numBackBuffers", 0); + this->noExplicitFrontBuffer = config.getOption ("d3d9.noExplicitFrontBuffer", false); this->deferSurfaceCreation = config.getOption ("d3d9.deferSurfaceCreation", false); this->samplerAnisotropy = config.getOption ("d3d9.samplerAnisotropy", -1); this->maxAvailableMemory = config.getOption ("d3d9.maxAvailableMemory", 4096); diff --git a/src/d3d9/d3d9_options.h b/src/d3d9/d3d9_options.h index 385e4fda..bdfe0c8e 100644 --- a/src/d3d9/d3d9_options.h +++ b/src/d3d9/d3d9_options.h @@ -55,6 +55,16 @@ namespace dxvk { /// Overrides buffer count in present parameters. int32_t numBackBuffers; + /// Don't create an explicit front buffer in our own swapchain. The Vulkan swapchain is unaffected. + /// Some games don't handle front/backbuffer flipping very well because they don't always redraw + /// each frame completely, and rely on old pixel data from the previous frame to still be there. + /// When this option is set and a game only requests one backbuffer, there will be no flipping in + /// our own swapchain, so the game will always draw to the same buffer and can rely on old pixel + /// data to still be there after a Present call. + /// This means that D3D9SwapChainEx::GetFrontBufferData returns data from the backbuffer of the + /// previous frame, which is the same as the current backbuffer if only 1 backbuffer was requested. + bool noExplicitFrontBuffer; + /// Defer surface creation bool deferSurfaceCreation; diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index 7264c342..b5336e0e 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -208,7 +208,7 @@ namespace dxvk { return D3DERR_INVALIDCALL; D3D9CommonTexture* dstTexInfo = dst->GetCommonTexture(); - D3D9CommonTexture* srcTexInfo = m_backBuffers[m_presentParams.BackBufferCount]->GetCommonTexture(); + D3D9CommonTexture* srcTexInfo = m_backBuffers.back()->GetCommonTexture(); if (unlikely(dstTexInfo->Desc()->Pool != D3DPOOL_SYSTEMMEM)) return D3DERR_INVALIDCALL; @@ -930,8 +930,9 @@ namespace dxvk { m_resolveImage = nullptr; m_resolveImageView = nullptr; + int NumFrontBuffer = m_parent->GetOptions()->noExplicitFrontBuffer ? 0 : 1; m_backBuffers.clear(); - m_backBuffers.resize(NumBackBuffers + 1); + m_backBuffers.resize(NumBackBuffers + NumFrontBuffer); // Create new back buffer D3D9_COMMON_TEXTURE_DESC desc;