r600g: set full register mask for CB_COLOR_CONTROL on evergreen
[mesa.git] / src / glx / dri_glx.c
index 42b263c6377b090ff7fac055195fe93fecc6f868..0cd7cca74fb108a27e363c55cd09251605ef33e3 100644 (file)
@@ -94,7 +94,7 @@ static const struct glx_context_vtable dri_context_vtable;
 
 /*
  * Given a display pointer and screen number, determine the name of
- * the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
+ * the DRI driver for the screen (i.e., "i965", "radeon", "nouveau", etc).
  * Return True for success, False for failure.
  */
 static Bool
@@ -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;
@@ -384,7 +384,7 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc,
       goto handle_error;
    }
 
-   /* Get device name (like "tdfx") and the ddx version numbers.
+   /* Get device name (like "radeon") and the ddx version numbers.
     * We'll check the version in each DRI driver's "createNewScreen"
     * function. */
    if (!XF86DRIGetClientDriverName(dpy, scrn,
@@ -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);
 
@@ -503,8 +514,7 @@ dri_destroy_context(struct glx_context * context)
    struct dri_context *pcp = (struct dri_context *) context;
    struct dri_screen *psc = (struct dri_screen *) context->psc;
 
-   if (context->xid)
-      glx_send_destroy_context(psc->base.dpy, context->xid);
+   driReleaseDrawables(&pcp->base);
 
    if (context->extensions)
       XFree((char *) context->extensions);
@@ -526,6 +536,8 @@ dri_bind_context(struct glx_context *context, struct glx_context *old,
    pdraw = (struct dri_drawable *) driFetchDrawable(context, draw);
    pread = (struct dri_drawable *) driFetchDrawable(context, read);
 
+   driReleaseDrawables(&pcp->base);
+
    if (pdraw == NULL || pread == NULL)
       return GLXBadDrawable;
 
@@ -543,8 +555,6 @@ dri_unbind_context(struct glx_context *context, struct glx_context *new)
    struct dri_screen *psc = (struct dri_screen *) pcp->base.psc;
 
    (*psc->core->unbindContext) (pcp->driContext);
-
-   driReleaseDrawables(&pcp->base);
 }
 
 static const struct glx_context_vtable dri_context_vtable = {
@@ -556,6 +566,7 @@ static const struct glx_context_vtable dri_context_vtable = {
    DRI_glXUseXFont,
    NULL,
    NULL,
+   NULL, /* get_proc_address */
 };
 
 static struct glx_context *
@@ -573,6 +584,13 @@ dri_create_context(struct glx_screen *base,
       return NULL;
 
    if (shareList) {
+      /* If the shareList context is not a DRI context, we cannot possibly
+       * create a DRI context that shares it.
+       */
+      if (shareList->vtable->destroy != dri_destroy_context) {
+        return NULL;
+      }
+
       pcp_shared = (struct dri_context *) shareList;
       shared = pcp_shared->driContext;
    }
@@ -818,7 +836,8 @@ driBindExtensions(struct dri_screen *psc, const __DRIextension **extensions)
 }
 
 static const struct glx_screen_vtable dri_screen_vtable = {
-   dri_create_context
+   dri_create_context,
+   NULL
 };
 
 static struct glx_screen *
@@ -836,26 +855,24 @@ driCreateScreen(int screen, struct glx_display *priv)
       return NULL;
 
    memset(psc, 0, sizeof *psc);
-   if (!glx_screen_init(&psc->base, screen, priv))
-       return NULL;
-
-   if (!driGetDriverName(priv->dpy, screen, &driverName)) {
+   if (!glx_screen_init(&psc->base, screen, priv)) {
       Xfree(psc);
       return NULL;
    }
 
+   if (!driGetDriverName(priv->dpy, screen, &driverName)) {
+      goto cleanup;
+   }
+
    psc->driver = driOpenDriver(driverName);
    Xfree(driverName);
-   if (psc->driver == NULL) {
-      Xfree(psc);
-      return NULL;
-   }
+   if (psc->driver == NULL)
+      goto cleanup;
 
    extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
    if (extensions == NULL) {
       ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
-      Xfree(psc);
-      return NULL;
+      goto cleanup;
    }
 
    for (i = 0; extensions[i]; i++) {
@@ -865,19 +882,14 @@ driCreateScreen(int screen, struct glx_display *priv)
         psc->legacy = (__DRIlegacyExtension *) extensions[i];
    }
 
-   if (psc->core == NULL || psc->legacy == NULL) {
-      Xfree(psc);
-      return NULL;
-   }
+   if (psc->core == NULL || psc->legacy == NULL)
+      goto cleanup;
 
    pdp = (struct dri_display *) priv->driDisplay;
    psc->driScreen =
       CallCreateNewScreen(psc->base.dpy, screen, psc, pdp);
-   if (psc->driScreen == NULL) {
-      dlclose(psc->driver);
-      Xfree(psc);
-      return NULL;
-   }
+   if (psc->driScreen == NULL)
+      goto cleanup;
 
    extensions = psc->core->getExtensions(psc->driScreen);
    driBindExtensions(psc, extensions);
@@ -902,6 +914,14 @@ driCreateScreen(int screen, struct glx_display *priv)
    psp->getSwapInterval = driGetSwapInterval;
 
    return &psc->base;
+
+cleanup:
+   if (psc->driver)
+      dlclose(psc->driver);
+   glx_screen_cleanup(&psc->base);
+   Xfree(psc);
+
+   return NULL;
 }
 
 /* Called from __glXFreeDisplayPrivate.