From caf99133ece234607a180dc4191ff68f30a8baf1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 20 Feb 2024 13:10:29 +1000 Subject: [PATCH] glx/dri3: handle zink fallback if loader picks it. if we get a zink driver selected for the fd then don't bind it to dri3 return a special error and this should stop dri2 binding it. Reviewed-by: Adam Jackson Part-of: --- src/glx/dri3_glx.c | 11 +++++++++-- src/glx/glxclient.h | 2 ++ src/glx/glxext.c | 8 ++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c index a1c9fb56696..12a05246af1 100644 --- a/src/glx/dri3_glx.c +++ b/src/glx/dri3_glx.c @@ -800,6 +800,7 @@ dri3_create_screen(int screen, struct glx_display * priv) __GLXDRIscreen *psp; struct glx_config *configs = NULL, *visuals = NULL; char *driverName, *driverNameDisplayGPU, *tmp; + bool return_zink = false; psc = calloc(1, sizeof *psc); if (psc == NULL) @@ -835,6 +836,11 @@ dri3_create_screen(int screen, struct glx_display * priv) goto handle_error; } + if (!strcmp(driverName, "zink")) { + return_zink = true; + goto handle_error; + } + extensions = driOpenDriver(driverName, &psc->driver); if (extensions == NULL) goto handle_error; @@ -1009,7 +1015,8 @@ dri3_create_screen(int screen, struct glx_display * priv) return &psc->base; handle_error: - CriticalErrorMessageF("failed to load driver: %s\n", driverName ? driverName : "(null)"); + if (!return_zink) + CriticalErrorMessageF("failed to load driver: %s\n", driverName ? driverName : "(null)"); if (configs) glx_config_destroy_list(configs); @@ -1032,7 +1039,7 @@ handle_error: glx_screen_cleanup(&psc->base); free(psc); - return NULL; + return return_zink ? GLX_LOADER_USE_ZINK : NULL; } /** dri_destroy_display diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h index 38980d76ddf..e262b4a80fa 100644 --- a/src/glx/glxclient.h +++ b/src/glx/glxclient.h @@ -78,6 +78,8 @@ typedef struct __GLXDRIdisplayRec __GLXDRIdisplay; typedef struct __GLXDRIscreenRec __GLXDRIscreen; typedef struct __GLXDRIdrawableRec __GLXDRIdrawable; +#define GLX_LOADER_USE_ZINK ((struct glx_screen *)(uintptr_t)-1) + struct __GLXDRIdisplayRec { /** diff --git a/src/glx/glxext.c b/src/glx/glxext.c index 05c825a2b07..6cf04d1b745 100644 --- a/src/glx/glxext.c +++ b/src/glx/glxext.c @@ -794,7 +794,7 @@ AllocAndFetchScreenConfigs(Display * dpy, struct glx_display * priv, Bool zink) psc = priv->windowsdriDisplay->createScreen(i, priv); #endif - if (psc == NULL && priv->driswDisplay) + if ((psc == GLX_LOADER_USE_ZINK || psc == NULL) && priv->driswDisplay) psc = priv->driswDisplay->createScreen(i, priv); #endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */ @@ -903,8 +903,12 @@ __glXInitialize(Display * dpy) #if defined(GLX_USE_DRM) if (glx_direct && glx_accel && !zink) { #if defined(HAVE_DRI3) - if (!debug_get_bool_option("LIBGL_DRI3_DISABLE", false)) + if (!debug_get_bool_option("LIBGL_DRI3_DISABLE", false)) { dpyPriv->dri3Display = dri3_create_display(dpy); + /* nouveau wants to fallback to zink so if we get a screen enable try_zink */ + if (dpyPriv->dri3Display) + try_zink = !debug_get_bool_option("LIBGL_KOPPER_DISABLE", false); + } #endif /* HAVE_DRI3 */ if (!debug_get_bool_option("LIBGL_DRI2_DISABLE", false)) dpyPriv->dri2Display = dri2CreateDisplay(dpy);