protonscr

Proton 4.11 causes tearing when redering resolution != output resolution

protonclosed
ValveSoftware/Proton#2932 · opened 2019-07-31 by Oschowa · updated 2019-08-08 · 29 comments · github
3 matching comments, n / p to jump
OOschowa 2019-07-31 github

With Proton 4.11 multiple games (I tested Sekiro and Dark Souls Remastered) show screen tearing when the rendering resolution does not match the output resolution, specifically 1080p rendering on a 4k screen. The issue is not present with Proton 4.2-9, or with 1080p rendering on a 1080p screen. DXVK version seems to be irrelevant, I tested the versions shipped in the respective Proton release and latest master for borh.

Tested on
Arch Linux
GPU RX580
kernel 5.2.5
mesa-aco 5c60772
DE Gnome 3.32

Log files of a Sekiro run:
steam-814380.log
sekiro_d3d11.log
sekiro_dxgi.log

Jjarrard 2019-08-01 github

even with vsync enabled ingame?

OOschowa 2019-08-01 github

Both games enable vsync unconditionally and you can tell from the d3d11.log that the fifo present mode is used.

Jjarrard 2019-08-01 github

and your sure triple buffering is enabled also? sometimes desktops need special environment settings for it.

OOschowa 2019-08-01 github

Vsync works fine with every game with 4.2, native titles and standalone wine on my setup, but not with 4.11. It also works when rendering resolution == output resolution on 4.11.

Jjarrard 2019-08-01 github

Yeah well I wouldn't be surprised, I've had a few issues with freezes or crashing in 4.11 myself, but I can't really report it atm because I don't have the correct cooler on my GPU so it gets quite hot.

Waiting on parts to turn up...

OOschowa 2019-08-01 github

I've identified 6bf75252 winex11.drv: Report real display modes in the fs hack as the commit which introduces the issue. Replacing winex11.drv.so and fakedlls/winex11.drv with a version with this commit reverted fixes the issue.

Aaeikum 2019-08-01 github

@Oschowa Thanks a lot for digging into it. If you don't mind going a little further, I have two things to ask. First would be to gather a log of normal Proton 4.11-1 with +x11settings added to the WINEDEBUG log. Second would be to try building current 4.11, and adding a quick hack to set freq = 60 at the start of X11DRV_Settings_AddOneMode. Like this:

diff --git a/dlls/winex11.drv/settings.c b/dlls/winex11.drv/settings.c
index df8ad17d255..f41d9421daa 100644
--- a/dlls/winex11.drv/settings.c
+++ b/dlls/winex11.drv/settings.c
@@ -97,6 +97,8 @@ BOOL X11DRV_Settings_AddOneMode(unsigned int width, unsigned int height, unsigne
     }
     if (bpp == 0) bpp = dwBpp;
 
+    freq = 60;
+
     for(i = 0; i < dd_mode_count; ++i)
     {
         if(dd_modes[i].width == width &&
Jjarrard 2019-08-01 github

hopefully freq = 60; isn't an official fix idea because it needs to detect the resolutions sync rate properly.

Aaeikum 2019-08-01 github

Of course not. Like I said, it's a quick hack :) My theory is that our rounding when converting the dot clock rate that X11 reports, to the Windows FPS value, is causing the mode to report 59 FPS to the game, and causing tearing. If that is true (the log will tell) and hacking it to 60 fixes it, then I'll look at how we are doing our rounding and how it can be changed to round to 60 instead of 59.

OOschowa 2019-08-01 github

Thanks for looking into it.

Log of unmodified 4.11 with +x11settings:
steam-814380 unmodified.log

Unfortunately, the freq = 60; hack does not work around the problem, here is a log with it applied:
steam-814380.log

Aaeikum 2019-08-01 github

Hum, rats. While you're at it, could you also grab a log of a successful run on 4.2-9?

OOschowa 2019-08-01 github

Successful run with 4.2-9:
steam-814380.log

Aaeikum 2019-08-01 github

@Oschowa I found a bug that seems unrelated, but I can't find any other difference between your good and bad logs. Can you try out this diff (without the freq=60 change)?

diff --git a/dlls/winex11.drv/settings.c b/dlls/winex11.drv/settings.c
index df8ad17d255..973711574d8 100644
--- a/dlls/winex11.drv/settings.c
+++ b/dlls/winex11.drv/settings.c
@@ -191,6 +191,7 @@ void X11DRV_Settings_AddDepthModes(void)
 
     qsort(dd_modes, dd_mode_count, sizeof(*dd_modes), sort_display_modes);
 
+    existing_modes = dd_mode_count;
     for (j=0; j<3; j++)
     {
         if (depths[j] != dwBpp)
OOschowa 2019-08-01 github

This seems to have fixed it, thank you very much!

Aaeikum 2019-08-01 github

Wow, neat. Thanks again for reporting and testing. The fix will be in the next Proton release. In the meantime you can of course use 4.2-9. Edit: Or your custom build! Haha! Carry on.

OOschowa 2019-08-01 github

@aeikum Turns out, i'm an idiot and still had 4.2-9 enabled when trying out the patch, and it does not fix the issue after all... Sorry for the confusion.

edit: I made 100% sure reverting 6bf75252 actually fixes it though.

Jjarrard 2019-08-01 github

aww...

(excitement deflated)

OOschowa 2019-08-02 github

Did some more digging and discovered, that the sorting of modes is what actually is causing the problem. The following hack ontop of 4.11-1 fixes it for me:

diff --git a/dlls/winex11.drv/settings.c b/dlls/winex11.drv/settings.c
index df8ad17d25..57863cfe02 100644
--- a/dlls/winex11.drv/settings.c
+++ b/dlls/winex11.drv/settings.c
@@ -189,7 +189,7 @@ void X11DRV_Settings_AddDepthModes(void)
             X11DRV_Settings_AddOneMode(fs_modes[i].w, fs_modes[i].h, 0, dd_modes[realMode].refresh_rate);
     }
 
-    qsort(dd_modes, dd_mode_count, sizeof(*dd_modes), sort_display_modes);
+    //qsort(dd_modes, dd_mode_count, sizeof(*dd_modes), sort_display_modes);
 
     for (j=0; j<3; j++)
     {

I also printed out the modes before and after sort and this is the result:

0028:trace:x11settings:trace_modes trace modes after sort? 0
0028:trace:x11settings:trace_modes trace modes 0: 3840x2160@60
0028:trace:x11settings:trace_modes trace modes 1: 4096x2160@60
0028:trace:x11settings:trace_modes trace modes 2: 1920x1200@60
0028:trace:x11settings:trace_modes trace modes 3: 1920x1080@60
0028:trace:x11settings:trace_modes trace modes 4: 1600x1200@60
0028:trace:x11settings:trace_modes trace modes 5: 1680x1050@60
0028:trace:x11settings:trace_modes trace modes 6: 1280x1024@60
0028:trace:x11settings:trace_modes trace modes 7: 1440x900@60
0028:trace:x11settings:trace_modes trace modes 8: 1280x960@60
0028:trace:x11settings:trace_modes trace modes 9: 1280x800@60
0028:trace:x11settings:trace_modes trace modes 10: 1280x720@60
0028:trace:x11settings:trace_modes trace modes 11: 1024x768@60
0028:trace:x11settings:trace_modes trace modes 12: 800x600@60
0028:trace:x11settings:trace_modes trace modes 13: 720x576@60
0028:trace:x11settings:trace_modes trace modes 14: 720x480@60
0028:trace:x11settings:trace_modes trace modes 15: 640x480@60
0028:trace:x11settings:trace_modes trace modes 16: 960x540@60
0028:trace:x11settings:trace_modes trace modes 17: 1600x900@60
0028:trace:x11settings:trace_modes trace modes 18: 2560x1440@60
0028:trace:x11settings:trace_modes trace modes 19: 2560x1600@60
0028:trace:x11settings:trace_modes trace modes 20: 1440x960@60
0028:trace:x11settings:trace_modes trace modes 21: 1920x1280@60
0028:trace:x11settings:trace_modes trace modes 22: 2560x1080@60
0028:trace:x11settings:trace_modes trace modes 23: 1920x800@60
0028:trace:x11settings:trace_modes trace modes 24: 3840x1600@60

0028:trace:x11settings:trace_modes trace modes after sort? 1
0028:trace:x11settings:trace_modes trace modes 0: 4096x2160@60
0028:trace:x11settings:trace_modes trace modes 1: 3840x2160@60
0028:trace:x11settings:trace_modes trace modes 2: 3840x1600@60
0028:trace:x11settings:trace_modes trace modes 3: 2560x1600@60
0028:trace:x11settings:trace_modes trace modes 4: 2560x1440@60
0028:trace:x11settings:trace_modes trace modes 5: 2560x1080@60
0028:trace:x11settings:trace_modes trace modes 6: 1920x1280@60
0028:trace:x11settings:trace_modes trace modes 7: 1920x1200@60
0028:trace:x11settings:trace_modes trace modes 8: 1920x1080@60
0028:trace:x11settings:trace_modes trace modes 9: 1920x800@60
0028:trace:x11settings:trace_modes trace modes 10: 1680x1050@60
0028:trace:x11settings:trace_modes trace modes 11: 1600x1200@60
0028:trace:x11settings:trace_modes trace modes 12: 1600x900@60
0028:trace:x11settings:trace_modes trace modes 13: 1440x960@60
0028:trace:x11settings:trace_modes trace modes 14: 1440x900@60
0028:trace:x11settings:trace_modes trace modes 15: 1280x1024@60
0028:trace:x11settings:trace_modes trace modes 16: 1280x960@60
0028:trace:x11settings:trace_modes trace modes 17: 1280x800@60
0028:trace:x11settings:trace_modes trace modes 18: 1280x720@60
0028:trace:x11settings:trace_modes trace modes 19: 1024x768@60
0028:trace:x11settings:trace_modes trace modes 20: 960x540@60
0028:trace:x11settings:trace_modes trace modes 21: 800x600@60
0028:trace:x11settings:trace_modes trace modes 22: 720x576@60
0028:trace:x11settings:trace_modes trace modes 23: 720x480@60
0028:trace:x11settings:trace_modes trace modes 24: 640x480@60

So it seems like the somewhat bogus 4096x2160@60 mode my screen claims to support getting enumerated before the primary 3840x2160@60 modes is causing the issue.

I wrote a PoC patch which always enumerates the primary mode first, which also solves the issue:
fshack_primary_mode_first.txt

Jjarrard 2019-08-02 · hidden on GitHub github

Can someone add in 3200x1800@60 mode for us 4k users, sometimes comes in handy and it frustrates me to all hell that nobody has added it in yet (has been requested).

Aaeikum 2019-08-02 github

@Oschowa That's really great work. I'll go run a quick test on Windows to see what happens there. I thought it sorted as I implemented, but I guess there's something else going on.

@jarrard As of 4.11-1, Proton should report both all of the native display resolutions as well as a list of common "backup" resolutions that your display might not support directly. If your display reports that resolution (e.g. it's in the output of xrandr), I'd expect it to be reported in Proton. It's possible your game is filtering that mode out, or, maybe you're hitting one of these bugs we're working on. I'd suggest trying again in 4.11-2 after we've stamped these bugs out.

Aaeikum 2019-08-02 github

@Oschowa On Windows, it appears to be enumerated in the reverse order of how I implemented it. In other words, first sort order is width smallest to biggest, then height smallest to biggest. There did not seem to be any sorting by frequency, and it did not report any bit depths other than 32. Changing the current mode made no difference to the sort order (although the current mode is not the same as the "preferred mode", which is also the largest and so listed last). This was on an integrated Intel GPU.

Can you try this diff on top of 4.11-1? It reverses the sort order, and fixes the mode count bug.

diff --git a/dlls/winex11.drv/settings.c b/dlls/winex11.drv/settings.c
index df8ad17d255..91e884fe1d7 100644
--- a/dlls/winex11.drv/settings.c
+++ b/dlls/winex11.drv/settings.c
@@ -150,17 +150,16 @@ static int sort_display_modes(const void *l, const void *r)
 {
     const struct x11drv_mode_info *left = l, *right = r;
 
-    /* largest first */
-    if(left->width < right->width)
+    if(left->width > right->width)
         return 1;
 
-    if(left->width > right->width)
+    if(left->width < right->width)
         return -1;
 
-    if(left->height < right->height)
+    if(left->height > right->height)
         return 1;
 
-    if(left->height > right->height)
+    if(left->height < right->height)
         return -1;
 
     return 0;
@@ -191,6 +190,7 @@ void X11DRV_Settings_AddDepthModes(void)
 
     qsort(dd_modes, dd_mode_count, sizeof(*dd_modes), sort_display_modes);
 
+    existing_modes = dd_mode_count;
     for (j=0; j<3; j++)
     {
         if (depths[j] != dwBpp)
Jjarrard 2019-08-02 github

As of 4.11-1, Proton should report both all of the native display

Yes this is probably true, however it requires me to make a custom EDID since nvidia drivers have no way of inserting custom resolutions under linux as they do under Windows.
Huge bucket loads of features missing for NVIDIA Linux drivers which is real unfortunate, hopefully AMD can make top end cards again soon.

OOschowa 2019-08-02 github

@aeikum Sadly, the new sorting order breaks the fshack completely for me. I get a window which looks like this (the game eventually renders something distored in the black square):

Screenshot from 2019-08-02 18-46-49

The resulting mode order is

0028:trace:x11settings:trace_modes trace modes 0: 640x480@60
0028:trace:x11settings:trace_modes trace modes 1: 720x480@60
0028:trace:x11settings:trace_modes trace modes 2: 720x576@60
0028:trace:x11settings:trace_modes trace modes 3: 800x600@60
0028:trace:x11settings:trace_modes trace modes 4: 960x540@60
0028:trace:x11settings:trace_modes trace modes 5: 1024x768@60
0028:trace:x11settings:trace_modes trace modes 6: 1280x720@60
0028:trace:x11settings:trace_modes trace modes 7: 1280x800@60
0028:trace:x11settings:trace_modes trace modes 8: 1280x960@60
0028:trace:x11settings:trace_modes trace modes 9: 1280x1024@60
0028:trace:x11settings:trace_modes trace modes 10: 1440x900@60
0028:trace:x11settings:trace_modes trace modes 11: 1440x960@60
0028:trace:x11settings:trace_modes trace modes 12: 1600x900@60
0028:trace:x11settings:trace_modes trace modes 13: 1600x1200@60
0028:trace:x11settings:trace_modes trace modes 14: 1680x1050@60
0028:trace:x11settings:trace_modes trace modes 15: 1920x800@60
0028:trace:x11settings:trace_modes trace modes 16: 1920x1080@60
0028:trace:x11settings:trace_modes trace modes 17: 1920x1200@60
0028:trace:x11settings:trace_modes trace modes 18: 1920x1280@60
0028:trace:x11settings:trace_modes trace modes 19: 2560x1080@60
0028:trace:x11settings:trace_modes trace modes 20: 2560x1440@60
0028:trace:x11settings:trace_modes trace modes 21: 2560x1600@60
0028:trace:x11settings:trace_modes trace modes 22: 3840x1600@60
0028:trace:x11settings:trace_modes trace modes 23: 3840x2160@60
0028:trace:x11settings:trace_modes trace modes 24: 4096x2160@60

Probably not useful but a log of this run with +x11settings
steam-814380.log

Aaeikum 2019-08-02 github

Oh shoot, I see the problem. It also explains why moving your real mode to index 0 helped. Try this diff. I suspect it will fix your problem with or without the sorting method change.

@@ -419,8 +419,8 @@ static LONG X11DRV_nores_SetCurrentMode(int mode)
         fs_hack_real_to_user_h = dd_modes[currentMode].height / (double)h;
 
         X11DRV_resize_desktop(
-                DisplayWidth(gdi_display, default_visual.screen) - (dd_modes[0].width - w),
-                DisplayHeight(gdi_display, default_visual.screen) - (dd_modes[0].height - h));
+                DisplayWidth(gdi_display, default_visual.screen) - (dd_modes[realMode].width - w),
+                DisplayHeight(gdi_display, default_visual.screen) - (dd_modes[realMode].height - h));
     }
 
     return DISP_CHANGE_SUCCESSFUL;
@@ -435,8 +435,8 @@ POINT fs_hack_current_mode(void)
 
 POINT fs_hack_real_mode(void)
 {
-    POINT ret = { dd_modes[0].width,
-        dd_modes[0].height };
+    POINT ret = { dd_modes[realMode].width,
+        dd_modes[realMode].height };
     return ret;
 }
OOschowa 2019-08-02 github

Indeed, with or without the sorting changes, the latest patch fixes the issue.
Thanks agian, I very much appreciate the fshack and all the Proton/Wine work in general.

Aaeikum 2019-08-02 github

Sure, and thanks to you for all the diagnosis and testing you did. Glad we got it fixed! Will be in the next build.

Ttannisroot 2019-08-04 github

@aeikum I'm not sure why but that diff that is supposed to fix refreshrate sorting order doesn't actually fix it.

Aaeikum 2019-08-08 github

The fix for screen tearing is included in 4.11-2. Please retest and confirm it's fixed!

OOschowa 2019-08-08 github

I can confirm that 4.11-2 fixes the tearing.

Proton versions

Launch options