Zhiyi Zhang : winex11.drv: Move broken NVIDIA driver detection into a function.

Alexandre Julliard julliard at winehq.org
Fri Jul 24 17:05:10 CDT 2020


Module: wine
Branch: master
Commit: f5e6c086f91749e9e302c1abf858807535bc9775
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=f5e6c086f91749e9e302c1abf858807535bc9775

Author: Zhiyi Zhang <zzhang at codeweavers.com>
Date:   Fri Jul 24 17:22:55 2020 +0800

winex11.drv: Move broken NVIDIA driver detection into a function.

Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winex11.drv/xrandr.c | 106 ++++++++++++++++++++++++++++++++++------------
 1 file changed, 78 insertions(+), 28 deletions(-)

diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c
index 141c2ca17f..cc88188943 100644
--- a/dlls/winex11.drv/xrandr.c
+++ b/dlls/winex11.drv/xrandr.c
@@ -316,6 +316,83 @@ static XRRScreenResources *xrandr_get_screen_resources(void)
     return resources;
 }
 
+/* Some (304.64, possibly earlier) versions of the NVIDIA driver only
+ * report a DFP's native mode through RandR 1.2 / 1.3. Standard DMT modes
+ * are only listed through RandR 1.0 / 1.1. This is completely useless,
+ * but NVIDIA considers this a feature, so it's unlikely to change. The
+ * best we can do is to fall back to RandR 1.0 and encourage users to
+ * consider more cooperative driver vendors when we detect such a
+ * configuration. */
+static BOOL is_broken_driver(void)
+{
+    XRRScreenResources *screen_resources;
+    XRROutputInfo *output_info;
+    XRRModeInfo *first_mode;
+    INT major, event, error;
+    INT output_idx, i, j;
+    BOOL only_one_mode;
+
+    screen_resources = xrandr_get_screen_resources();
+    if (!screen_resources)
+        return TRUE;
+
+    /* Check if any output only has one native mode */
+    for (output_idx = 0; output_idx < screen_resources->noutput; ++output_idx)
+    {
+        output_info = pXRRGetOutputInfo( gdi_display, screen_resources,
+                                         screen_resources->outputs[output_idx] );
+        if (!output_info)
+            continue;
+
+        if (output_info->connection != RR_Connected)
+        {
+            pXRRFreeOutputInfo( output_info );
+            continue;
+        }
+
+        first_mode = NULL;
+        only_one_mode = TRUE;
+        for (i = 0; i < output_info->nmode; ++i)
+        {
+            for (j = 0; j < screen_resources->nmode; ++j)
+            {
+                if (output_info->modes[i] != screen_resources->modes[j].id)
+                    continue;
+
+                if (!first_mode)
+                {
+                    first_mode = &screen_resources->modes[j];
+                    break;
+                }
+
+                if (first_mode->width != screen_resources->modes[j].width ||
+                    first_mode->height != screen_resources->modes[j].height)
+                    only_one_mode = FALSE;
+
+                break;
+            }
+
+            if (!only_one_mode)
+                break;
+        }
+        pXRRFreeOutputInfo( output_info );
+
+        if (!only_one_mode)
+            continue;
+
+        /* Check if it is NVIDIA proprietary driver */
+        if (XQueryExtension( gdi_display, "NV-CONTROL", &major, &event, &error ))
+        {
+            ERR_(winediag)("Broken NVIDIA RandR detected, falling back to RandR 1.0. "
+                           "Please consider using the Nouveau driver instead.\n");
+            pXRRFreeScreenResources( screen_resources );
+            return TRUE;
+        }
+    }
+    pXRRFreeScreenResources( screen_resources );
+    return FALSE;
+}
+
 static int xrandr12_get_current_mode(void)
 {
     XRRScreenResources *resources;
@@ -504,7 +581,6 @@ static unsigned int get_frequency( const XRRModeInfo *mode )
 
 static int xrandr12_init_modes(void)
 {
-    unsigned int only_one_resolution = 1, mode_count;
     XRRScreenResources *resources;
     XRROutputInfo *output_info;
     XRRCrtcInfo *crtc_info;
@@ -570,32 +646,6 @@ static int xrandr12_init_modes(void)
         }
     }
 
-    mode_count = X11DRV_Settings_GetModeCount();
-    for (i = 1; i < mode_count; ++i)
-    {
-        if (dd_modes[i].width != dd_modes[0].width || dd_modes[i].height != dd_modes[0].height)
-        {
-            only_one_resolution = 0;
-            break;
-        }
-    }
-
-    /* Recent (304.64, possibly earlier) versions of the nvidia driver only
-     * report a DFP's native mode through RandR 1.2 / 1.3. Standard DMT modes
-     * are only listed through RandR 1.0 / 1.1. This is completely useless,
-     * but NVIDIA considers this a feature, so it's unlikely to change. The
-     * best we can do is to fall back to RandR 1.0 and encourage users to
-     * consider more cooperative driver vendors when we detect such a
-     * configuration. */
-    if (only_one_resolution && XQueryExtension( gdi_display, "NV-CONTROL", &i, &j, &ret ))
-    {
-        ERR_(winediag)("Broken NVIDIA RandR detected, falling back to RandR 1.0. "
-                       "Please consider using the Nouveau driver instead.\n");
-        ret = -1;
-        HeapFree( GetProcessHeap(), 0, xrandr12_modes );
-        goto done;
-    }
-
     X11DRV_Settings_AddDepthModes();
     ret = 0;
 
@@ -1260,7 +1310,7 @@ void X11DRV_XRandR_Init(void)
             pXRRGetScreenResourcesCurrent = pXRRGetScreenResources;
     }
 
-    if (!pXRRGetScreenResourcesCurrent || xrandr12_init_modes() < 0)
+    if (!pXRRGetScreenResourcesCurrent || is_broken_driver() || xrandr12_init_modes() < 0)
 #endif
         xrandr10_init_modes();
 




More information about the wine-cvs mailing list