protonscr

Display modes for all monitors should be restored instead of only restoring specific one monitor

dxvkclosed dxgid3d9
doitsujin/dxvk#2064 · opened 2021-05-18 by zzhiyi · updated 2021-05-31 · 6 comments · github
Zzzhiyi 2021-05-18 github

Please see
https://source.winehq.org/git/wine.git/commitdiff/df90c0ef7ea053606e684901073b26368f34ac26
https://source.winehq.org/git/wine.git/commitdiff/ef81152c8cd17f1bfb2950753428a95a81728c97
https://source.winehq.org/git/wine.git/commitdiff/b911e560458ac7a05c04758efb8f5286a47cae7d

DXVK's RestoreMonitorDisplayMode() only restores the display mode for a specific monitor, which might cause monitor layout changes after mode changes. I would have implemented this myself if I find the time. Reporting it here if anyone wants to fix this.

Ddoitsujin maintainer 2021-05-18 github

What exactly is the issue here?

Zzzhiyi 2021-05-18 github

When using ChangeDisplaySettingsExW to change the primary monitor resolution while a secondary monitor is present. It's possible that the monitor layout will change, e.g., from aligning horizontally to vertically. And then if we only restore the primary monitor resolution, the layout is not kept. Some games expect the monitor layout is kept and the tests prove it. For example, there is a chance that RiME will hang on KDE if you quickly get in and out of fullscreen mode multiple times.

Ddoitsujin maintainer 2021-05-18 github

Why does the layout change and why does restoring all monitors solve that problem? Doing so should be a no-op for all monitors that the game isn't currently running on since we're not changing the mode in the first place?

Zzzhiyi 2021-05-25 github

The layout change is caused by calling ChangeDisplaySettings for a specific monitor. It happens in cases when moving the secondary monitor in one direction is closer than moving it to the original direction. For example, a primary 3840x2160 monitor and secondary 800x600 monitor on the right with the top side aligned horizontally. Now call ChangeDisplaySettings to set the primary monitor to 800x600. If the secondary monitor moves to the left. Then the offset is 3840-800=3040. However, if it moves upwards, it's -600. abs(-600) < abs(3040) so the secondary monitor end up on the top side of the primary monitor. You can test it on Windows as well. Finally restoring the primary monitor will keep the secondary monitor on the top side. Thus a layout change. I don't remember the exact reason why the layout change will solve the hang. If DXVK's DXGI can pass wine's DXGI tests, then things should be fine.

Also, CDS_FULLSCREEN may have something to do with this but it's not implemented in Wine. It might affect how monitors get restored. I'll have to look into it.

Ddoitsujin maintainer 2021-05-31 github

Does 1743a27669a9b2bc6ea6e6529c5bb9ea45876dc1 fix the problem? I can't really test this properly since i don't have a multi-monitor setup on my desktop and can't really reproduce these issues on my notebook.

Ddoitsujin maintainer 2021-05-31 github

Actually, yeah, when changing the order around I get failures without that commit but not with it, so it should work.

Nothing extracted yet.