glx: rework __glXInitialize

* add an enum of bits for determining which display connections to try
* collect bits and then do all setup in AllocAndFetchScreenConfigs()

in theory no functional changes

Reviewed-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30375>
This commit is contained in:
Mike Blumenkrantz
2024-07-19 08:36:51 -04:00
committed by Marge Bot
parent 8078a938f5
commit 4e8740370a
4 changed files with 63 additions and 45 deletions

View File

@@ -929,7 +929,7 @@ kopperGetSwapInterval(__GLXDRIdrawable *pdraw)
return pdp->swapInterval; return pdp->swapInterval;
} }
struct glx_screen * static struct glx_screen *
driswCreateScreenDriver(int screen, struct glx_display *priv, driswCreateScreenDriver(int screen, struct glx_display *priv,
const char *driver, bool driver_name_is_inferred) const char *driver, bool driver_name_is_inferred)
{ {
@@ -1001,7 +1001,7 @@ driswCreateScreenDriver(int screen, struct glx_display *priv,
!debug_get_bool_option("LIBGL_ALWAYS_SOFTWARE", false) && !debug_get_bool_option("LIBGL_ALWAYS_SOFTWARE", false) &&
!debug_get_bool_option("LIBGL_KOPPER_DRI2", false)) { !debug_get_bool_option("LIBGL_KOPPER_DRI2", false)) {
/* only print error if zink was explicitly requested */ /* only print error if zink was explicitly requested */
if (pdpyp->zink == TRY_ZINK_YES) if (pdpyp->zink & GLX_DRIVER_ZINK_YES)
CriticalErrorMessageF("DRI3 not available\n"); CriticalErrorMessageF("DRI3 not available\n");
goto handle_error; goto handle_error;
} }
@@ -1049,7 +1049,7 @@ driswCreateScreenDriver(int screen, struct glx_display *priv,
glx_screen_cleanup(&psc->base); glx_screen_cleanup(&psc->base);
free(psc); free(psc);
if (pdpyp->zink == TRY_ZINK_YES && !driver_name_is_inferred) if (pdpyp->zink & GLX_DRIVER_ZINK_YES && !driver_name_is_inferred)
CriticalErrorMessageF("failed to load driver: %s\n", driver); CriticalErrorMessageF("failed to load driver: %s\n", driver);
return NULL; return NULL;
@@ -1080,7 +1080,7 @@ driswDestroyDisplay(__GLXDRIdisplay * dpy)
* display pointer. * display pointer.
*/ */
_X_HIDDEN __GLXDRIdisplay * _X_HIDDEN __GLXDRIdisplay *
driswCreateDisplay(Display * dpy, enum try_zink zink) driswCreateDisplay(Display * dpy, enum glx_driver glx_driver)
{ {
struct drisw_display *pdpyp; struct drisw_display *pdpyp;
@@ -1088,7 +1088,7 @@ driswCreateDisplay(Display * dpy, enum try_zink zink)
if (pdpyp == NULL) if (pdpyp == NULL)
return NULL; return NULL;
pdpyp->zink = zink; pdpyp->zink = glx_driver & (GLX_DRIVER_ZINK_INFER | GLX_DRIVER_ZINK_YES);
return (void*)pdpyp; return (void*)pdpyp;
} }

View File

@@ -31,7 +31,7 @@
struct drisw_display struct drisw_display
{ {
enum try_zink zink; enum glx_driver zink;
}; };
struct drisw_screen struct drisw_screen

View File

@@ -123,17 +123,22 @@ struct __GLXDRIdrawableRec
int refcount; int refcount;
}; };
enum try_zink { /* bits */
TRY_ZINK_NO, enum glx_driver {
TRY_ZINK_INFER, GLX_DRIVER_NONE = 0,
TRY_ZINK_YES, GLX_DRIVER_ZINK_INFER = (1<<0),
GLX_DRIVER_SW = (1<<1),
GLX_DRIVER_DRI2 = (1<<2),
GLX_DRIVER_DRI3 = (1<<3),
GLX_DRIVER_WINDOWS = (1<<4),
GLX_DRIVER_ZINK_YES = (1<<5),
}; };
/* /*
** Function to create and DRI display data and initialize the display ** Function to create and DRI display data and initialize the display
** dependent methods. ** dependent methods.
*/ */
extern __GLXDRIdisplay *driswCreateDisplay(Display * dpy, enum try_zink zink); extern __GLXDRIdisplay *driswCreateDisplay(Display * dpy, enum glx_driver glx_driver);
extern __GLXDRIdisplay *dri2CreateDisplay(Display * dpy); extern __GLXDRIdisplay *dri2CreateDisplay(Display * dpy);
extern __GLXDRIdisplay *dri3_create_display(Display * dpy); extern __GLXDRIdisplay *dri3_create_display(Display * dpy);
extern __GLXDRIdisplay *driwindowsCreateDisplay(Display * dpy); extern __GLXDRIdisplay *driwindowsCreateDisplay(Display * dpy);
@@ -148,7 +153,7 @@ void dri3_destroy_display(__GLXDRIdisplay * dpy);
struct glx_screen *dri2CreateScreen(int screen, struct glx_display * priv, bool driver_name_is_inferred); struct glx_screen *dri2CreateScreen(int screen, struct glx_display * priv, bool driver_name_is_inferred);
void dri2DestroyDisplay(__GLXDRIdisplay * dpy); void dri2DestroyDisplay(__GLXDRIdisplay * dpy);
struct glx_screen * driswCreateScreenDriver(int screen, struct glx_display *priv, const char *driver, bool driver_name_is_inferred); struct glx_screen *driswCreateScreen(int screen, struct glx_display *priv, bool driver_name_is_inferred);
void driswDestroyDisplay(__GLXDRIdisplay * dpy); void driswDestroyDisplay(__GLXDRIdisplay * dpy);
#endif #endif

View File

@@ -32,6 +32,10 @@
#include "dri_common.h" #include "dri_common.h"
#endif #endif
#ifdef HAVE_DRI3
#include "loader_dri3_helper.h"
#endif
#include <X11/Xlib-xcb.h> #include <X11/Xlib-xcb.h>
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <xcb/glx.h> #include <xcb/glx.h>
@@ -286,8 +290,10 @@ glx_display_free(struct glx_display *priv)
priv->driswDisplay = NULL; priv->driswDisplay = NULL;
#if defined (GLX_USE_DRM) #if defined (GLX_USE_DRM)
#if defined(HAVE_X11_DRI2)
if (priv->dri2Display) if (priv->dri2Display)
dri2DestroyDisplay(priv->dri2Display); dri2DestroyDisplay(priv->dri2Display);
#endif
priv->dri2Display = NULL; priv->dri2Display = NULL;
if (priv->dri3Display) if (priv->dri3Display)
@@ -763,11 +769,12 @@ glx_screen_cleanup(struct glx_screen *psc)
** If that works then fetch the per screen configs data. ** If that works then fetch the per screen configs data.
*/ */
static Bool static Bool
AllocAndFetchScreenConfigs(Display * dpy, struct glx_display * priv, Bool zink, Bool driver_name_is_inferred) AllocAndFetchScreenConfigs(Display * dpy, struct glx_display * priv, enum glx_driver glx_driver, Bool driver_name_is_inferred)
{ {
struct glx_screen *psc; struct glx_screen *psc;
GLint i, screens; GLint i, screens;
unsigned screen_count = 0; unsigned screen_count = 0;
bool zink = (glx_driver & (GLX_DRIVER_ZINK_INFER | GLX_DRIVER_ZINK_YES)) > 0;
/* /*
** First allocate memory for the array of per screen configs. ** First allocate memory for the array of per screen configs.
@@ -782,26 +789,32 @@ AllocAndFetchScreenConfigs(Display * dpy, struct glx_display * priv, Bool zink,
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
#if defined(GLX_USE_DRM) #if defined(GLX_USE_DRM)
#if defined(HAVE_DRI3) #if defined(HAVE_DRI3)
if (priv->dri3Display) if (glx_driver & GLX_DRIVER_DRI3) {
priv->dri3Display = dri3_create_display(dpy);
psc = dri3_create_screen(i, priv, driver_name_is_inferred); psc = dri3_create_screen(i, priv, driver_name_is_inferred);
}
#endif /* HAVE_DRI3 */ #endif /* HAVE_DRI3 */
#if defined(HAVE_X11_DRI2) #if defined(HAVE_X11_DRI2)
if (psc == NULL && priv->dri2Display) if (psc == NULL && glx_driver & GLX_DRIVER_DRI2) {
priv->dri2Display = dri2CreateDisplay(dpy);
psc = dri2CreateScreen(i, priv, driver_name_is_inferred); psc = dri2CreateScreen(i, priv, driver_name_is_inferred);
}
#endif
#endif /* GLX_USE_DRM */ #endif /* GLX_USE_DRM */
#ifdef GLX_USE_WINDOWSGL #ifdef GLX_USE_WINDOWSGL
if (psc == NULL && priv->windowsdriDisplay) if (psc == NULL && glx_driver & GLX_DRIVER_WINDOWS) {
priv->windowsdriDisplay = driwindowsCreateDisplay(dpy);
psc = driwindowsCreateScreen(i, priv, driver_name_is_inferred); psc = driwindowsCreateScreen(i, priv, driver_name_is_inferred);
}
#endif #endif
if ((psc == GLX_LOADER_USE_ZINK || psc == NULL) && priv->driswDisplay)
psc = driswCreateScreen(i, priv, psc == GLX_LOADER_USE_ZINK ? false : driver_name_is_inferred);
#endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */ #endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */
#if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE))
#if defined(GLX_USE_APPLE) if ((psc == GLX_LOADER_USE_ZINK || psc == NULL) &&
if (psc == NULL && priv->driswDisplay) { (glx_driver & GLX_DRIVER_SW || zink)) {
psc = driswCreateScreen(i, priv); priv->driswDisplay = driswCreateDisplay(dpy, glx_driver);
psc = driswCreateScreen(i, priv, psc == GLX_LOADER_USE_ZINK ? false : driver_name_is_inferred);
} }
#endif #endif
@@ -884,15 +897,15 @@ __glXInitialize(Display * dpy)
dpyPriv->glXDrawHash = __glxHashCreate(); dpyPriv->glXDrawHash = __glxHashCreate();
Bool zink = False; enum glx_driver glx_driver = 0;
enum try_zink try_zink = TRY_ZINK_NO;
const char *env = getenv("MESA_LOADER_DRIVER_OVERRIDE"); const char *env = getenv("MESA_LOADER_DRIVER_OVERRIDE");
#if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE)) #if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE))
Bool glx_direct = !debug_get_bool_option("LIBGL_ALWAYS_INDIRECT", false); Bool glx_direct = !debug_get_bool_option("LIBGL_ALWAYS_INDIRECT", false);
Bool glx_accel = !debug_get_bool_option("LIBGL_ALWAYS_SOFTWARE", false); Bool glx_accel = !debug_get_bool_option("LIBGL_ALWAYS_SOFTWARE", false);
zink = env && !strcmp(env, "zink"); if (env && !strcmp(env, "zink"))
glx_driver |= GLX_DRIVER_ZINK_YES;
dpyPriv->drawHash = __glxHashCreate(); dpyPriv->drawHash = __glxHashCreate();
@@ -908,50 +921,50 @@ __glXInitialize(Display * dpy)
*/ */
#if defined(GLX_USE_DRM) #if defined(GLX_USE_DRM)
if (glx_direct && glx_accel && if (glx_direct && glx_accel &&
(!zink || debug_get_bool_option("LIBGL_KOPPER_DISABLE", false))) { (!(glx_driver & GLX_DRIVER_ZINK_YES) || debug_get_bool_option("LIBGL_KOPPER_DISABLE", false))) {
#if defined(HAVE_DRI3) #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); bool err = false;
/* nouveau wants to fallback to zink so if we get a screen enable try_zink */ loader_dri3_check_multibuffer(XGetXCBConnection(dpy), &err);
if (dpyPriv->dri3Display) /* dri3 is tried as long as this doesn't error; whether modifiers work is not relevant */
try_zink = !debug_get_bool_option("LIBGL_KOPPER_DISABLE", false) ? TRY_ZINK_INFER : TRY_ZINK_NO; if (!err) {
glx_driver |= GLX_DRIVER_DRI3;
/* nouveau wants to fallback to zink so if we get a screen enable try_zink */
if (!debug_get_bool_option("LIBGL_KOPPER_DISABLE", false))
glx_driver |= GLX_DRIVER_ZINK_INFER;
}
} }
#endif /* HAVE_DRI3 */ #endif /* HAVE_DRI3 */
#if defined(HAVE_X11_DRI2) #if defined(HAVE_X11_DRI2)
if (!debug_get_bool_option("LIBGL_DRI2_DISABLE", false)) if (!debug_get_bool_option("LIBGL_DRI2_DISABLE", false))
dpyPriv->dri2Display = dri2CreateDisplay(dpy); glx_driver |= GLX_DRIVER_DRI2;
#endif #endif
#if defined(HAVE_ZINK) #if defined(HAVE_ZINK)
if (!dpyPriv->dri3Display && !dpyPriv->dri2Display) if (!(glx_driver & (GLX_DRIVER_DRI2 | GLX_DRIVER_DRI3)))
try_zink = !debug_get_bool_option("LIBGL_KOPPER_DISABLE", false) && if (!debug_get_bool_option("LIBGL_KOPPER_DISABLE", false) && !getenv("GALLIUM_DRIVER"))
!getenv("GALLIUM_DRIVER") ? TRY_ZINK_INFER : TRY_ZINK_NO; glx_driver |= GLX_DRIVER_ZINK_INFER;
#endif /* HAVE_ZINK */ #endif /* HAVE_ZINK */
} }
#endif /* GLX_USE_DRM */ #endif /* GLX_USE_DRM */
if (glx_direct) if (glx_direct)
dpyPriv->driswDisplay = driswCreateDisplay(dpy, zink ? TRY_ZINK_YES : try_zink); glx_driver |= GLX_DRIVER_SW;
#ifdef GLX_USE_WINDOWSGL #ifdef GLX_USE_WINDOWSGL
if (glx_direct && glx_accel) if (glx_direct && glx_accel)
dpyPriv->windowsdriDisplay = driwindowsCreateDisplay(dpy); glx_driver |= GLX_DRIVER_WINDOWS;
#endif #endif
#endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */ #endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */
#if defined(GLX_USE_APPLEGL) && !defined(GLX_USE_APPLE) #if defined(GLX_USE_APPLEGL) && !defined(GLX_USE_APPLE)
if (!applegl_create_display(dpyPriv)) { glx_driver |= GLX_DRIVER_SW;
free(dpyPriv);
return NULL;
}
#endif #endif
if (!AllocAndFetchScreenConfigs(dpy, dpyPriv, zink || try_zink, !env)) { if (!AllocAndFetchScreenConfigs(dpy, dpyPriv, glx_driver, !env)) {
Bool fail = True; Bool fail = True;
#if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE)) #if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE))
if (try_zink) { if (glx_driver & GLX_DRIVER_ZINK_INFER) {
free(dpyPriv->screens);
driswDestroyDisplay(dpyPriv->driswDisplay); driswDestroyDisplay(dpyPriv->driswDisplay);
dpyPriv->driswDisplay = driswCreateDisplay(dpy, TRY_ZINK_NO); fail = !AllocAndFetchScreenConfigs(dpy, dpyPriv, GLX_DRIVER_SW, true);
fail = !AllocAndFetchScreenConfigs(dpy, dpyPriv, False, true);
} }
#endif #endif
if (fail) { if (fail) {