Mesa (master): glx: Fix indirect fallback when a non-Mesa GLX extension is present.

Brian Paul brianp at kemper.freedesktop.org
Thu Dec 8 00:21:15 UTC 2011


Module: Mesa
Branch: master
Commit: 63a6fd6603574c1c01324fbeb0863e39d3864c16
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=63a6fd6603574c1c01324fbeb0863e39d3864c16

Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Tue Dec  6 10:20:30 2011 -0800

glx: Fix indirect fallback when a non-Mesa GLX extension is present.

When driCreateScreen calls driConvertConfigs to try to convert the
configs for swrast, it fails and returns NULL.  Instead of checking,
it just clobbers psc->base.configs.  Then, when the application asks
for the FBconfigs, there aren't any.

Instead, make the caller responsible for freeing the old modes lists
if both calls to driConvertConfigs succeed.

Without the second fix, glxinfo fails unless you run it with
LIBGL_ALWAYS_INDIRECT:

    $ glxinfo
    name of display: :0.0
    Error: couldn't find RGB GLX visual or fbconfig

    $ LIBGL_ALWAYS_INDIRECT=1 glxinfo
    name of display: :0.0
    display: :0  screen: 0
    direct rendering: No (LIBGL_ALWAYS_INDIRECT set)
    server glx vendor string: NVIDIA Corporation
    server glx version string: 1.4
    [...]

Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
Reviewed-and-tested-by: Ian Romanick <ian.d.romanick at intel.com>
Signed-off-by: Brian Paul <brianp at vmware.com>

---

 src/glx/dri2_glx.c   |   23 +++++++++++++++++++----
 src/glx/dri_common.c |    2 --
 src/glx/dri_glx.c    |   21 ++++++++++++++++-----
 src/glx/drisw_glx.c  |   23 +++++++++++++++++++----
 4 files changed, 54 insertions(+), 15 deletions(-)

diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 940626c..553869a 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -865,6 +865,7 @@ dri2CreateScreen(int screen, struct glx_display * priv)
       priv->dri2Display;
    struct dri2_screen *psc;
    __GLXDRIscreen *psp;
+   struct glx_config *configs = NULL, *visuals = NULL;
    char *driverName, *deviceName;
    drm_magic_t magic;
    int i;
@@ -947,10 +948,16 @@ dri2CreateScreen(int screen, struct glx_display * priv)
    extensions = psc->core->getExtensions(psc->driScreen);
    dri2BindExtensions(psc, extensions);
 
-   psc->base.configs =
-      driConvertConfigs(psc->core, psc->base.configs, driver_configs);
-   psc->base.visuals =
-      driConvertConfigs(psc->core, psc->base.visuals, driver_configs);
+   configs = driConvertConfigs(psc->core, psc->base.configs, driver_configs);
+   visuals = driConvertConfigs(psc->core, psc->base.visuals, driver_configs);
+
+   if (!configs || !visuals)
+       goto handle_error;
+
+   glx_config_destroy_list(psc->base.configs);
+   psc->base.configs = configs;
+   glx_config_destroy_list(psc->base.visuals);
+   psc->base.visuals = visuals;
 
    psc->driver_configs = driver_configs;
 
@@ -994,10 +1001,18 @@ dri2CreateScreen(int screen, struct glx_display * priv)
    return &psc->base;
 
 handle_error:
+   if (configs)
+       glx_config_destroy_list(configs);
+   if (visuals)
+       glx_config_destroy_list(visuals);
+   if (psc->driScreen)
+       psc->core->destroyScreen(psc->driScreen);
+   psc->driScreen = NULL;
    if (psc->fd >= 0)
       close(psc->fd);
    if (psc->driver)
       dlclose(psc->driver);
+
    Xfree(driverName);
    Xfree(deviceName);
    glx_screen_cleanup(&psc->base);
diff --git a/src/glx/dri_common.c b/src/glx/dri_common.c
index eb62c82..1482b88 100644
--- a/src/glx/dri_common.c
+++ b/src/glx/dri_common.c
@@ -340,8 +340,6 @@ driConvertConfigs(const __DRIcoreExtension * core,
       tail = tail->next;
    }
 
-   glx_config_destroy_list(configs);
-
    return head.next;
 }
 
diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c
index a52159c..666423a 100644
--- a/src/glx/dri_glx.c
+++ b/src/glx/dri_glx.c
@@ -336,7 +336,7 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc,
    drm_handle_t hFB;
    int junk;
    const __DRIconfig **driver_configs;
-   struct glx_config *visual;
+   struct glx_config *visual, *configs = NULL, *visuals = NULL;
 
    /* DRI protocol version. */
    dri_version.major = driDpy->driMajor;
@@ -446,10 +446,16 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc,
       goto handle_error;
    }
 
-   psc->base.configs =
-      driConvertConfigs(psc->core, psc->base.configs, driver_configs);
-   psc->base.visuals =
-      driConvertConfigs(psc->core, psc->base.visuals, driver_configs);
+   configs = driConvertConfigs(psc->core, psc->base.configs, driver_configs);
+   visuals = driConvertConfigs(psc->core, psc->base.visuals, driver_configs);
+
+   if (!configs || !visuals)
+       goto handle_error;
+
+   glx_config_destroy_list(psc->base.configs);
+   psc->base.configs = configs;
+   glx_config_destroy_list(psc->base.visuals);
+   psc->base.visuals = visuals;
 
    psc->driver_configs = driver_configs;
 
@@ -478,6 +484,11 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc,
    return psp;
 
  handle_error:
+   if (configs)
+       glx_config_destroy_list(configs);
+   if (visuals)
+       glx_config_destroy_list(visuals);
+
    if (pSAREA != MAP_FAILED)
       drmUnmap(pSAREA, SAREA_MAX);
 
diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c
index a150c61..fbc6be2 100644
--- a/src/glx/drisw_glx.c
+++ b/src/glx/drisw_glx.c
@@ -524,6 +524,7 @@ driswCreateScreen(int screen, struct glx_display *priv)
    const __DRIconfig **driver_configs;
    const __DRIextension **extensions;
    struct drisw_screen *psc;
+   struct glx_config *configs = NULL, *visuals = NULL;
    int i;
 
    psc = Xcalloc(1, sizeof *psc);
@@ -569,10 +570,16 @@ driswCreateScreen(int screen, struct glx_display *priv)
    extensions = psc->core->getExtensions(psc->driScreen);
    driswBindExtensions(psc, extensions);
 
-   psc->base.configs =
-      driConvertConfigs(psc->core, psc->base.configs, driver_configs);
-   psc->base.visuals =
-      driConvertConfigs(psc->core, psc->base.visuals, driver_configs);
+   configs = driConvertConfigs(psc->core, psc->base.configs, driver_configs);
+   visuals = driConvertConfigs(psc->core, psc->base.visuals, driver_configs);
+
+   if (!configs || !visuals)
+       goto handle_error;
+
+   glx_config_destroy_list(psc->base.configs);
+   psc->base.configs = configs;
+   glx_config_destroy_list(psc->base.visuals);
+   psc->base.visuals = visuals;
 
    psc->driver_configs = driver_configs;
 
@@ -586,6 +593,14 @@ driswCreateScreen(int screen, struct glx_display *priv)
    return &psc->base;
 
  handle_error:
+   if (configs)
+       glx_config_destroy_list(configs);
+   if (visuals)
+       glx_config_destroy_list(visuals);
+   if (psc->driScreen)
+       psc->core->destroyScreen(psc->driScreen);
+   psc->driScreen = NULL;
+
    if (psc->driver)
       dlclose(psc->driver);
    glx_screen_cleanup(&psc->base);




More information about the mesa-commit mailing list