egl/glx: add fallback for zink loading

if the driver attemping to load is not zink and not software, then
attempt a zink fallback on failure

this conservatively handles the case of "only zink is built", though it
is going to be noticeably slower at startup than loading zink directly

Reviewed-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16168>
This commit is contained in:
Mike Blumenkrantz 2022-04-26 11:37:15 -04:00 committed by Marge Bot
parent 112b8d7c4d
commit 2569215f43
3 changed files with 37 additions and 14 deletions

View file

@ -662,12 +662,26 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
* If the initialisation fails, try again using only software rendering.
*/
if (!_eglDriver.Initialize(disp)) {
if (disp->Options.ForceSoftware)
RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
else {
bool fail = true;
if (!disp->Options.ForceSoftware && !disp->Options.Zink &&
!env_var_as_boolean("LIBGL_KOPPER_DISABLE", false) && !getenv("GALLIUM_DRIVER")) {
/* zink fallback */
disp->Options.Zink = EGL_TRUE;
disp->Options.ForceSoftware = EGL_TRUE;
if (!_eglDriver.Initialize(disp))
fail = !_eglDriver.Initialize(disp);
if (fail) {
disp->Options.Zink = EGL_FALSE;
disp->Options.ForceSoftware = EGL_FALSE;
}
}
if (fail) {
if (disp->Options.ForceSoftware)
RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
else {
disp->Options.ForceSoftware = EGL_TRUE;
if (!_eglDriver.Initialize(disp))
RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
}
}
}

View file

@ -1055,11 +1055,8 @@ static struct glx_screen *
driswCreateScreen(int screen, struct glx_display *priv)
{
const struct drisw_display *pdpyp = (struct drisw_display *)priv->driswDisplay;
if (pdpyp->zink && !env_var_as_boolean("LIBGL_KOPPER_DISABLE", false)) {
return driswCreateScreenDriver(screen, priv, "zink");
}
return driswCreateScreenDriver(screen, priv, "swrast");
return driswCreateScreenDriver(screen, priv, pdpyp->zink ? "zink" : "swrast");
}
/* Called from __glXFreeDisplayPrivate.

View file

@ -926,9 +926,9 @@ __glXInitialize(Display * dpy)
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
glx_direct = !env_var_as_boolean("LIBGL_ALWAYS_INDIRECT", false);
glx_accel = !env_var_as_boolean("LIBGL_ALWAYS_SOFTWARE", false);
Bool zink;
const char *env = getenv("MESA_LOADER_DRIVER_OVERRIDE");
zink = env && !strcmp(env, "zink");
Bool explicit_zink = env && !strcmp(env, "zink");
Bool infer_zink = false;
dpyPriv->drawHash = __glxHashCreate();
@ -945,17 +945,20 @@ __glXInitialize(Display * dpy)
** (e.g., those called in AllocAndFetchScreenConfigs).
*/
#if defined(GLX_USE_DRM)
if (glx_direct && glx_accel && !zink) {
if (glx_direct && glx_accel && !explicit_zink) {
#if defined(HAVE_DRI3)
if (!env_var_as_boolean("LIBGL_DRI3_DISABLE", false))
dpyPriv->dri3Display = dri3_create_display(dpy);
#endif /* HAVE_DRI3 */
if (!env_var_as_boolean("LIBGL_DRI2_DISABLE", false))
dpyPriv->dri2Display = dri2CreateDisplay(dpy);
/* zink fallback */
if (!dpyPriv->dri3Display && !dpyPriv->dri2Display)
infer_zink = !env_var_as_boolean("LIBGL_KOPPER_DISABLE", false) && !getenv("GALLIUM_DRIVER");
}
#endif /* GLX_USE_DRM */
if (glx_direct)
dpyPriv->driswDisplay = driswCreateDisplay(dpy, zink);
dpyPriv->driswDisplay = driswCreateDisplay(dpy, explicit_zink | infer_zink);
#endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */
#ifdef GLX_USE_APPLEGL
@ -971,8 +974,17 @@ __glXInitialize(Display * dpy)
#endif
if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) {
free(dpyPriv);
return NULL;
Bool fail = true;
/* if zink was inferred, retry without zink */
if (infer_zink && !explicit_zink) {
free(dpyPriv->screens);
driswCreateDisplay(dpy, false);
fail = !AllocAndFetchScreenConfigs(dpy, dpyPriv);
}
if (fail) {
free(dpyPriv);
return NULL;
}
}
__glX_send_client_info(dpyPriv);