glx: Fix indirect fallback when a non-Mesa GLX extension is present.
authorAaron Plattner <aplattner@nvidia.com>
Tue, 6 Dec 2011 18:20:30 +0000 (10:20 -0800)
committerBrian Paul <brianp@vmware.com>
Thu, 8 Dec 2011 00:20:10 +0000 (17:20 -0700)
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@nvidia.com>
Reviewed-and-tested-by: Ian Romanick <ian.d.romanick@intel.com>
Signed-off-by: Brian Paul <brianp@vmware.com>
src/glx/dri2_glx.c
src/glx/dri_common.c
src/glx/dri_glx.c
src/glx/drisw_glx.c

index 940626c20204847a12c63b1b727e2312f60c692a..553869a53f92d13597d2fcaa366333506aaba9c8 100644 (file)
@@ -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);
index eb62c824f35c550410d59e40adc02a352468b25a..1482b88bd93d3f68acdf0bc02abc7696a510edc0 100644 (file)
@@ -340,8 +340,6 @@ driConvertConfigs(const __DRIcoreExtension * core,
       tail = tail->next;
    }
 
-   glx_config_destroy_list(configs);
-
    return head.next;
 }
 
index a52159c06571c5b40fa9f581a2736b451df5cd73..666423a7b1577ea6b08c9e5db9e8bbecfb9ac289 100644 (file)
@@ -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);
 
index a150c618b18df0ac886fa06462425d9ef64d7b1e..fbc6be272c0948c335e578a1d3531dc4f5cd3fac 100644 (file)
@@ -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);