Skip to content
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

Closed
wants to merge 3 commits into from

Conversation

w-flo
Copy link
Contributor

@w-flo w-flo commented Feb 11, 2020

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.

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
@Joshua-Ashton
Copy link
Collaborator

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)

@w-flo
Copy link
Contributor Author

w-flo commented Feb 11, 2020

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.

Joshua-Ashton pushed a commit that referenced this pull request Mar 18, 2020
Fixes flickering when parts of the screen are not redrawn in a frame.

Closes: #1368
Merges: #1437
Joshua-Ashton pushed a commit that referenced this pull request Mar 18, 2020
Fixes flickering when parts of the screen are not redrawn in a frame.

Closes #1368
Merges #1437
@Joshua-Ashton
Copy link
Collaborator

Merged as ba41a52

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[d3d9] Front/Backbuffer flipping leads to flickering in games that don't respect DISCARD SwapEffect
2 participants