X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglx%2Fdri_glx.c;h=9bfcb0c082a32869a58ab3c97d875397bd78e7ca;hb=3917503b9a48275f389ec1e563fdb53415b87171;hp=95cded792d916417cef047e11010e22c35360583;hpb=6ec39db726beead21d97bf64ddbe1f0b2d2d6ca1;p=mesa.git diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c index 95cded792d9..9bfcb0c082a 100644 --- a/src/glx/dri_glx.c +++ b/src/glx/dri_glx.c @@ -61,7 +61,7 @@ struct dri_display struct dri_screen { - __GLXscreenConfigs base; + struct glx_screen base; __DRIscreen *driScreen; __GLXDRIscreen vtable; @@ -78,11 +78,9 @@ struct dri_screen struct dri_context { - __GLXcontext base; - __GLXDRIcontext dri_vtable; + struct glx_context base; __DRIcontext *driContext; XID hwContextID; - __GLXscreenConfigs *psc; }; struct dri_drawable @@ -96,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 @@ -152,7 +150,7 @@ driGetDriverName(Display * dpy, int scrNum, char **driverName) * The returned char pointer points to a static array that will be * overwritten by subsequent calls. */ -PUBLIC const char * +_X_EXPORT const char * glXGetScreenDriver(Display * dpy, int scrNum) { static char ret[32]; @@ -182,7 +180,7 @@ glXGetScreenDriver(Display * dpy, int scrNum) * * Note: The driver remains opened after this function returns. */ -PUBLIC const char * +_X_EXPORT const char * glXGetDriverConfig(const char *driverName) { void *handle = driOpenDriver(driverName); @@ -227,7 +225,7 @@ __glXReportDamage(__DRIdrawable * driDraw, int i; int x_off, y_off; __GLXDRIdrawable *glxDraw = loaderPrivate; - __GLXscreenConfigs *psc = glxDraw->psc; + struct glx_screen *psc = glxDraw->psc; Display *dpy = psc->dpy; Drawable drawable; @@ -279,7 +277,7 @@ __glXDRIGetDrawableInfo(__DRIdrawable * drawable, void *loaderPrivate) { __GLXDRIdrawable *glxDraw = loaderPrivate; - __GLXscreenConfigs *psc = glxDraw->psc; + struct glx_screen *psc = glxDraw->psc; Display *dpy = psc->dpy; return XF86DRIGetDrawableInfo(dpy, psc->scr, glxDraw->drawable, @@ -338,7 +336,7 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc, drm_handle_t hFB; int junk; const __DRIconfig **driver_configs; - __GLcontextModes *visual; + struct glx_config *visual, *configs = NULL, *visuals = NULL; /* DRI protocol version. */ dri_version.major = driDpy->driMajor; @@ -386,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, @@ -448,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; @@ -480,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); @@ -500,71 +509,89 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc, } static void -dri_destroy_context(__GLXcontext * context) +dri_destroy_context(struct glx_context * context) { struct dri_context *pcp = (struct dri_context *) context; struct dri_screen *psc = (struct dri_screen *) context->psc; - glx_send_destroy_context(psc->base.dpy, context->xid); + driReleaseDrawables(&pcp->base); if (context->extensions) XFree((char *) context->extensions); - GarbageCollectDRIDrawables(context->psc); - (*psc->core->destroyContext) (pcp->driContext); XF86DRIDestroyContext(psc->base.dpy, psc->base.scr, pcp->hwContextID); Xfree(pcp); } -static Bool -driBindContext(__GLXcontext *context, - __GLXDRIdrawable *draw, __GLXDRIdrawable *read) +static int +dri_bind_context(struct glx_context *context, struct glx_context *old, + GLXDrawable draw, GLXDrawable read) { struct dri_context *pcp = (struct dri_context *) context; - struct dri_screen *psc = (struct dri_screen *) pcp->psc; - struct dri_drawable *pdr = (struct dri_drawable *) draw; - struct dri_drawable *prd = (struct dri_drawable *) read; + struct dri_screen *psc = (struct dri_screen *) pcp->base.psc; + struct dri_drawable *pdraw, *pread; - return (*psc->core->bindContext) (pcp->driContext, - pdr->driDrawable, prd->driDrawable); + pdraw = (struct dri_drawable *) driFetchDrawable(context, draw); + pread = (struct dri_drawable *) driFetchDrawable(context, read); + + driReleaseDrawables(&pcp->base); + + if (pdraw == NULL || pread == NULL) + return GLXBadDrawable; + + if ((*psc->core->bindContext) (pcp->driContext, + pdraw->driDrawable, pread->driDrawable)) + return Success; + + return GLXBadContext; } static void -driUnbindContext(__GLXcontext * context) +dri_unbind_context(struct glx_context *context, struct glx_context *new) { struct dri_context *pcp = (struct dri_context *) context; - struct dri_screen *psc = (struct dri_screen *) pcp->psc; + struct dri_screen *psc = (struct dri_screen *) pcp->base.psc; (*psc->core->unbindContext) (pcp->driContext); } static const struct glx_context_vtable dri_context_vtable = { dri_destroy_context, + dri_bind_context, + dri_unbind_context, NULL, NULL, DRI_glXUseXFont, NULL, NULL, + NULL, /* get_proc_address */ }; -static __GLXcontext * -dri_create_context(__GLXscreenConfigs *base, - const __GLcontextModes *mode, - GLXContext shareList, int renderType) +static struct glx_context * +dri_create_context(struct glx_screen *base, + struct glx_config *config_base, + struct glx_context *shareList, int renderType) { struct dri_context *pcp, *pcp_shared; struct dri_screen *psc = (struct dri_screen *) base; drm_context_t hwContext; __DRIcontext *shared = NULL; - __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode; + __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base; if (!psc->base.driScreen) return NULL; if (shareList) { - pcp_shared = (struct dri_context *) shareList->driContext; + /* 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; } @@ -573,13 +600,13 @@ dri_create_context(__GLXscreenConfigs *base, return NULL; memset(pcp, 0, sizeof *pcp); - if (!glx_context_init(&pcp->base, &psc->base, mode)) { + if (!glx_context_init(&pcp->base, &psc->base, &config->base)) { Xfree(pcp); return NULL; } if (!XF86DRICreateContextWithConfig(psc->base.dpy, psc->base.scr, - mode->visualID, + config->base.visualID, &pcp->hwContextID, &hwContext)) { Xfree(pcp); return NULL; @@ -596,9 +623,6 @@ dri_create_context(__GLXscreenConfigs *base, } pcp->base.vtable = &dri_context_vtable; - pcp->base.driContext = &pcp->dri_vtable; - pcp->dri_vtable.bindContext = driBindContext; - pcp->dri_vtable.unbindContext = driUnbindContext; return &pcp->base; } @@ -615,13 +639,13 @@ driDestroyDrawable(__GLXDRIdrawable * pdraw) } static __GLXDRIdrawable * -driCreateDrawable(__GLXscreenConfigs *base, +driCreateDrawable(struct glx_screen *base, XID xDrawable, - GLXDrawable drawable, const __GLcontextModes * modes) + GLXDrawable drawable, struct glx_config *config_base) { drm_drawable_t hwDrawable; void *empty_attribute_list = NULL; - __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes; + __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base; struct dri_screen *psc = (struct dri_screen *) base; struct dri_drawable *pdp; @@ -633,6 +657,7 @@ driCreateDrawable(__GLXscreenConfigs *base, if (!pdp) return NULL; + memset(pdp, 0, sizeof *pdp); pdp->base.drawable = drawable; pdp->base.psc = &psc->base; @@ -684,7 +709,7 @@ driCopySubBuffer(__GLXDRIdrawable * pdraw, } static void -driDestroyScreen(__GLXscreenConfigs *base) +driDestroyScreen(struct glx_screen *base) { struct dri_screen *psc = (struct dri_screen *) base; @@ -700,7 +725,7 @@ driDestroyScreen(__GLXscreenConfigs *base) #ifdef __DRI_SWAP_BUFFER_COUNTER static int -driDrawableGetMSC(__GLXscreenConfigs *base, __GLXDRIdrawable *pdraw, +driDrawableGetMSC(struct glx_screen *base, __GLXDRIdrawable *pdraw, int64_t *ust, int64_t *msc, int64_t *sbc) { struct dri_screen *psc = (struct dri_screen *) base; @@ -755,17 +780,12 @@ driWaitForSBC(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust, static int driSetSwapInterval(__GLXDRIdrawable *pdraw, int interval) { - GLXContext gc = __glXGetCurrentContext(); struct dri_drawable *pdp = (struct dri_drawable *) pdraw; - struct dri_screen *psc; - - if (gc->driContext) { - psc = (struct dri_screen *) pdraw->psc; + struct dri_screen *psc = (struct dri_screen *) pdraw->psc; - if (psc->swapControl != NULL && pdraw != NULL) { - psc->swapControl->setSwapInterval(pdp->driDrawable, interval); - return 0; - } + if (psc->swapControl != NULL && pdraw != NULL) { + psc->swapControl->setSwapInterval(pdp->driDrawable, interval); + return 0; } return GLX_BAD_CONTEXT; @@ -774,17 +794,11 @@ driSetSwapInterval(__GLXDRIdrawable *pdraw, int interval) static int driGetSwapInterval(__GLXDRIdrawable *pdraw) { - GLXContext gc = __glXGetCurrentContext(); struct dri_drawable *pdp = (struct dri_drawable *) pdraw; - struct dri_screen *psc; + struct dri_screen *psc = (struct dri_screen *) pdraw->psc; - if (gc != NULL && gc->driContext) { - psc = (struct dri_screen *) pdraw->psc; - - if (psc->swapControl != NULL && pdraw != NULL) { - return psc->swapControl->getSwapInterval(pdp->driDrawable); - } - } + if (psc->swapControl != NULL && pdraw != NULL) + return psc->swapControl->getSwapInterval(pdp->driDrawable); return 0; } @@ -822,11 +836,12 @@ 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 __GLXscreenConfigs * -driCreateScreen(int screen, __GLXdisplayPrivate *priv) +static struct glx_screen * +driCreateScreen(int screen, struct glx_display *priv) { struct dri_display *pdp; __GLXDRIscreen *psp; @@ -840,26 +855,24 @@ driCreateScreen(int screen, __GLXdisplayPrivate *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++) { @@ -869,19 +882,14 @@ driCreateScreen(int screen, __GLXdisplayPrivate *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); @@ -906,6 +914,16 @@ driCreateScreen(int screen, __GLXdisplayPrivate *priv) psp->getSwapInterval = driGetSwapInterval; return &psc->base; + +cleanup: + CriticalErrorMessageF("failed to load driver: %s\n", driverName); + + if (psc->driver) + dlclose(psc->driver); + glx_screen_cleanup(&psc->base); + Xfree(psc); + + return NULL; } /* Called from __glXFreeDisplayPrivate.