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;
}
struct glx_screen *
static struct glx_screen *
driswCreateScreenDriver(int screen, struct glx_display *priv,
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_KOPPER_DRI2", false)) {
/* 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");
goto handle_error;
}
@@ -1049,7 +1049,7 @@ driswCreateScreenDriver(int screen, struct glx_display *priv,
glx_screen_cleanup(&psc->base);
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);
return NULL;
@@ -1080,7 +1080,7 @@ driswDestroyDisplay(__GLXDRIdisplay * dpy)
* display pointer.
*/
_X_HIDDEN __GLXDRIdisplay *
driswCreateDisplay(Display * dpy, enum try_zink zink)
driswCreateDisplay(Display * dpy, enum glx_driver glx_driver)
{
struct drisw_display *pdpyp;
@@ -1088,7 +1088,7 @@ driswCreateDisplay(Display * dpy, enum try_zink zink)
if (pdpyp == NULL)
return NULL;
pdpyp->zink = zink;
pdpyp->zink = glx_driver & (GLX_DRIVER_ZINK_INFER | GLX_DRIVER_ZINK_YES);
return (void*)pdpyp;
}

View File

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

View File

@@ -123,17 +123,22 @@ struct __GLXDRIdrawableRec
int refcount;
};
enum try_zink {
TRY_ZINK_NO,
TRY_ZINK_INFER,
TRY_ZINK_YES,
/* bits */
enum glx_driver {
GLX_DRIVER_NONE = 0,
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
** 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 *dri3_create_display(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);
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);
#endif

View File

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