joncampbell123 / dosbox-x

DOSBox-X fork of the DOSBox project
GNU General Public License v2.0
2.65k stars 376 forks source link

VSync does not work on Linux #2425

Open silver246 opened 3 years ago

silver246 commented 3 years ago

Running games in fullscreen always cause screen tearing. It is very noticeable in GTA1 when moving around.

Changing vsyncmode to either on, force or host and changing vsyncrate to 60 or 75 seems to have an impact on how fast the game runs but the output gets never sync to the monitors refresh rate. Setting fulldouble to either true or false also has no effect.

When leaving fullscreen mode the tearing disappears because vsync is done by the compositor. After switching back to fullscreen the output gets unredirected and tearing is visible again.

Problem happens to me with the Snap version and current SDL1 and SDL2 builds.

Environment:

rderooy commented 3 years ago

Does your monitor support 70Hz refresh (most DOS resolutions used 70Hz)?

silver246 commented 3 years ago

It only supports 60Hz but vsyncmode = on and vsyncrate = 60 also shows tearing. Does DosBox-X only sync if it detects a screen with 70Hz?

rderooy commented 3 years ago

I'm certainly no expert on this issue, but simple logic would seem to dictate that if the game expects to run at 70Hz, you either need to drop frames to output to a 60Hz monitor (which causes visual glitches, like tearing, but may also effect audio or input handling), or you need to slow the game down to display every frame.

silver246 commented 3 years ago

Yes, that's right. For all VGA games running at 70Hz it is never perfect because most LCD monitors today run at 60Hz. Slowing down the game is bad so only option here is to drop frames but this should not have any effect on audio or input handling because timing is the same only some frames are dropped.

Tearing is a different problem which happens when framebuffer gets modified while sending it to the display. Often this requires an additional buffer to fix it (that's why I also tried enabling fulldouble). But DosBox-X does not seem to do the synchronization even with vsyncmode = force.

silver246 commented 3 years ago

I took a short look at the code and it seems that (for opengl output) setting vsyncmode to host should synchronize the output using the SDL layer. Other options only do synchronization for the DosBox internal VGA emulation things!?

The option vsyncmode = host seems only be used for SDL1 not SDL2? I just tried a quick fix for SDL2 opengl output and first test seems to work ...no more tearing in GTA1.

Here is the patch sdl2_vsync_host.diff.txt, maybe it is useful to fix the problem.

rderooy commented 3 years ago

Thanks, are you running GTA in 3Dfx mode, or in regular mode?

I'm trying to see if I can replicate the tearing, but am perhaps just not noticing it. Even when I set my refresh rate down to 60Hz (both my monitors normally run at 75Hz). I tried GTA both in 3dfx and regular mode, and also tried Epic Pinball, as that was another game I found online with people complaining about tearing. All this with the SDL2 binary and output=auto (=opengl) on Linux with Wayland desktop and DOSBox-X using XWayland.

Do you have something that makes the tearing super clear?

silver246 commented 3 years ago

I am running it in regular mode and DosBox-X need to be in fullscreen to see the tearing. This also happens for me in 3Dfx mode with software emulation. GTA is the game where it is most noticeable for me, especially when driving fast. On other games the tearing is not so visible because most games do not have such fast scrolling.

AFAIK Wayland does always sync the output to the monitors refresh rate but I don't know what happens if XWayland application uses fullscreen. If the output does not get unredirected to bypass the compositing you won't see any tearing. I cannot test it here because I have an nvidia card which does not like Wayland. If you can switch your session to use Xserver you might be able to replicate it.

Wengier commented 3 years ago

@silver246 Thanks for updating the code for the SDL2 build.