mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-19 05:52:11 +01:00
[d3d9] Add option to disable the explicit frontbuffer
The Vulkan swapchain is unaffected by this, but we don't create an "internal" frontbuffer in D3D9SwapChainEx if this option is set. This breaks GetFrontBufferData (which returns backbuffer data if the option is enabled), but it disables front/backbuffer flipping. Most windows drivers apparently always use the same backbuffer for all frames in windowed mode. At least one game (ZUSI 3) seems to rely on this behavior, and only redraws dirty regions for each frame instead of redrawing everything. With buffer flips, this leads to flickering. When enabling this new noExplicitFrontBuffer option, the flickering disappears.
This commit is contained in:
parent
6a8933cf31
commit
1a4b15a82d
@ -47,6 +47,7 @@ namespace dxvk {
|
||||
this->strictPow = config.getOption<bool> ("d3d9.strictPow", true);
|
||||
this->lenientClear = config.getOption<bool> ("d3d9.lenientClear", false);
|
||||
this->numBackBuffers = config.getOption<int32_t> ("d3d9.numBackBuffers", 0);
|
||||
this->noExplicitFrontBuffer = config.getOption<bool> ("d3d9.noExplicitFrontBuffer", false);
|
||||
this->deferSurfaceCreation = config.getOption<bool> ("d3d9.deferSurfaceCreation", false);
|
||||
this->samplerAnisotropy = config.getOption<int32_t> ("d3d9.samplerAnisotropy", -1);
|
||||
this->maxAvailableMemory = config.getOption<int32_t> ("d3d9.maxAvailableMemory", 4096);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user