New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] [d3d9] Add option to disable the explicit frontbuffer #1437
Conversation
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.
Fixes flickering when parts of the screen are not redrawn in a frame. Closes: doitsujin#1368
I would like to see if we can actually fix this issue without an app profile. I think it is related to the swap effect that the game is using -- currently we are entirely disregarding that and I know there are some quirks wrt. buffer count/front buffer with those (probably the same in D3D11 too @doitsujin) |
As far as I can tell (I don't have a lot of apitrace experience though, so you may want to double check - trace is in the bug report), the game uses the DISCARD swap effect to be able to use MSAA, like almost every other game. MSAA is only allowed when using DISCARD. However, DISCARD requires the game to always draw complete frames: "An application that uses this swap effect should update an entire back buffer before invoking a Present operation that displays it.". So it's perfectly legal for dxvk to flip buffers, or even throw away old buffers, or fill them with random noise, when a game uses DISCARD. ZUSI 3 apparently ignores that part and gets away with it because most Windows drivers implement "COPY" swapeffect semantics ("the [Present] operation leaves the content of the back buffer unchanged") when requesting DISCARD in windowed mode, because that is apparently the most efficient thing to do when working with the Windows compositor (?). Initially I also assumed that the bug is caused by unimplemented "COPY" swapeffect in dxvk, but it looks like ZUSI 3 really requests DISCARD and then fails to follow DISCARD rules. This is also why the same bug occurs on Windows when setting ZUSI 3 to use exclusive fullscreen. Edit: TL;DR: I believe the current dxvk swapchain implementation is valid for the DISCARD swapeffect, which is used by this game (and almost every other game). Only COPY and maybe FLIP swapeffects need more work, but I don't know any games that use them. |
Merged as ba41a52 |
I'm not too happy about this, especially the wording. "Explicit frontbuffer" was the best term I was able to come up with. Maybe you can suggest a better name if the patch is acceptable in general.
Maybe there are better approaches to fix the issue, but this one seemed the easiest to implement so I gave it a try, and it fixes #1368 for me.
I reproduced the same ZUSI 3 bevhior on Windows by setting the game to "DirectX fullscreen" (aka exclusive fullscreen). So I'm almost convinced now that Zusi 3 does not redraw the full screen in every frame, only regions that have changed vs. the previous frame. So there is probably nothing other than a workaround similar to this one to fix it in dxvk. Exclusive fullscreen is marked as "special use only" in the game so I guess there are no plans to fix the game itself.