diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 97cb4ec4482..c3b55919d49 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -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); + } } } diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c index 200156be2b8..5ab8b7a5273 100644 --- a/src/glx/drisw_glx.c +++ b/src/glx/drisw_glx.c @@ -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. diff --git a/src/glx/glxext.c b/src/glx/glxext.c index 678cc6eb24a..5e955fc9bbc 100644 --- a/src/glx/glxext.c +++ b/src/glx/glxext.c @@ -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);