X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglx%2Fdri_glx.c;h=04a0847a4b61f938c7388b9fd8f75b120b9de33b;hb=76ae25d7e8de02cf05d2aa848028864fd2737058;hp=fd14285a481ec20f79b6866197318fef447c5135;hpb=bc34aa6128b9d509a25232d70dc826f1921fd221;p=mesa.git diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c index fd14285a481..04a0847a4b6 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,8 +78,7 @@ struct dri_screen struct dri_context { - __GLXcontext base; - __GLXDRIcontext dri_vtable; + struct glx_context base; __DRIcontext *driContext; XID hwContextID; }; @@ -91,11 +90,9 @@ struct dri_drawable __DRIdrawable *driDrawable; }; -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 @@ -137,7 +134,7 @@ driGetDriverName(Display * dpy, int scrNum, char **driverName) Bool ret = DRI2Connect(dpy, RootWindow(dpy, scrNum), driverName, &dev); if (ret) - Xfree(dev); + free(dev); return ret; } @@ -151,7 +148,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]; @@ -164,7 +161,7 @@ glXGetScreenDriver(Display * dpy, int scrNum) if (len >= 31) return NULL; memcpy(ret, driverName, len + 1); - Xfree(driverName); + free(driverName); return ret; } return NULL; @@ -181,14 +178,25 @@ 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); - if (handle) - return dlsym(handle, "__driConfigOptions"); - else + const __DRIextension **extensions; + + if (!handle) return NULL; + + extensions = driGetDriverExtensions(handle, driverName); + if (extensions) { + for (int i = 0; extensions[i]; i++) { + if (strcmp(extensions[i]->name, __DRI_CONFIG_OPTIONS) == 0) + return ((__DRIconfigOptionsExtension *)extensions[i])->xml; + } + } + + /* Fall back to the old method */ + return dlsym(handle, "__driConfigOptions"); } #ifdef XDAMAGE_1_1_INTERFACE @@ -226,7 +234,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; @@ -261,8 +269,9 @@ __glXReportDamage(__DRIdrawable * driDraw, } static const __DRIdamageExtension damageExtension = { - {__DRI_DAMAGE, __DRI_DAMAGE_VERSION}, - __glXReportDamage, + .base = {__DRI_DAMAGE, 1 }, + + .reportDamage = __glXReportDamage, }; #endif @@ -278,7 +287,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, @@ -289,8 +298,9 @@ __glXDRIGetDrawableInfo(__DRIdrawable * drawable, } static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = { - {__DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION}, - __glXDRIGetDrawableInfo + .base = {__DRI_GET_DRAWABLE_INFO, 1 }, + + .getDrawableInfo = __glXDRIGetDrawableInfo }; static const __DRIextension *loader_extensions[] = { @@ -337,7 +347,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; @@ -355,7 +365,7 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc, fd = drmOpenOnce(NULL, BusID, &newlyopened); - Xfree(BusID); /* No longer needed */ + free(BusID); /* No longer needed */ if (fd < 0) { ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd)); @@ -385,7 +395,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, @@ -396,7 +406,7 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc, goto handle_error; } - Xfree(driverName); /* No longer needed. */ + free(driverName); /* No longer needed. */ /* * Get device-specific info. pDevPriv will point to a struct @@ -408,7 +418,7 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc, &framebuffer.size, &framebuffer.stride, &framebuffer.dev_priv_size, &framebuffer.dev_priv)) { - ErrorMessageF("XF86DRIGetDeviceInfo failed"); + ErrorMessageF("XF86DRIGetDeviceInfo failed\n"); goto handle_error; } @@ -419,7 +429,7 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc, status = drmMap(fd, hFB, framebuffer.size, (drmAddressPtr) & framebuffer.base); if (status != 0) { - ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status)); + ErrorMessageF("drmMap of framebuffer failed (%s)\n", strerror(-status)); goto handle_error; } @@ -428,7 +438,7 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc, */ status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA); if (status != 0) { - ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status)); + ErrorMessageF("drmMap of SAREA failed (%s)\n", strerror(-status)); goto handle_error; } @@ -443,14 +453,20 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc, &driver_configs, psc); if (psp == NULL) { - ErrorMessageF("Calling driver entry point failed"); + ErrorMessageF("Calling driver entry point failed\n"); 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; @@ -472,21 +488,25 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc, if (num_visuals > 0 && visuals->depth != DefaultDepth(dpy, scrn)) visual->visualRating = GLX_NON_CONFORMANT_CONFIG; - XFree(visuals); + free(visuals); } } 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); if (framebuffer.base != MAP_FAILED) drmUnmap((drmAddress) framebuffer.base, framebuffer.size); - if (framebuffer.dev_priv != NULL) - Xfree(framebuffer.dev_priv); + free(framebuffer.dev_priv); if (fd >= 0) drmCloseOnce(fd); @@ -499,40 +519,46 @@ 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; - if (context->xid) - glx_send_destroy_context(psc->base.dpy, context->xid); - - if (context->extensions) - XFree((char *) context->extensions); + driReleaseDrawables(&pcp->base); - GarbageCollectDRIDrawables(context->psc); + free((char *) context->extensions); (*psc->core->destroyContext) (pcp->driContext); XF86DRIDestroyContext(psc->base.dpy, psc->base.scr, pcp->hwContextID); - Xfree(pcp); + free(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->base.psc; - struct dri_drawable *pdr = (struct dri_drawable *) draw; - struct dri_drawable *prd = (struct dri_drawable *) read; + struct dri_drawable *pdraw, *pread; + + pdraw = (struct dri_drawable *) driFetchDrawable(context, draw); + pread = (struct dri_drawable *) driFetchDrawable(context, read); + + driReleaseDrawables(&pcp->base); - return (*psc->core->bindContext) (pcp->driContext, - pdr->driDrawable, prd->driDrawable); + 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->base.psc; @@ -541,47 +567,62 @@ driUnbindContext(__GLXcontext * context) } static const struct glx_context_vtable dri_context_vtable = { - dri_destroy_context, - NULL, - NULL, - DRI_glXUseXFont, - NULL, - NULL, + .destroy = dri_destroy_context, + .bind = dri_bind_context, + .unbind = dri_unbind_context, + .wait_gl = NULL, + .wait_x = NULL, + .use_x_font = DRI_glXUseXFont, + .bind_tex_image = NULL, + .release_tex_image = NULL, + .get_proc_address = NULL, }; -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; + /* Check the renderType value */ + if (!validate_renderType_against_config(config_base, renderType)) + 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; } - pcp = Xmalloc(sizeof *pcp); + pcp = calloc(1, sizeof *pcp); if (pcp == NULL) return NULL; - memset(pcp, 0, sizeof *pcp); - if (!glx_context_init(&pcp->base, &psc->base, mode)) { - Xfree(pcp); + if (!glx_context_init(&pcp->base, &psc->base, &config->base)) { + free(pcp); return NULL; } + pcp->base.renderType = renderType; + if (!XF86DRICreateContextWithConfig(psc->base.dpy, psc->base.scr, - mode->visualID, + config->base.visualID, &pcp->hwContextID, &hwContext)) { - Xfree(pcp); + free(pcp); return NULL; } @@ -591,14 +632,11 @@ dri_create_context(__GLXscreenConfigs *base, renderType, shared, hwContext, pcp); if (pcp->driContext == NULL) { XF86DRIDestroyContext(psc->base.dpy, psc->base.scr, pcp->hwContextID); - Xfree(pcp); + free(pcp); return NULL; } 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; } @@ -611,17 +649,17 @@ driDestroyDrawable(__GLXDRIdrawable * pdraw) (*psc->core->destroyDrawable) (pdp->driDrawable); XF86DRIDestroyDrawable(psc->base.dpy, psc->base.scr, pdraw->drawable); - Xfree(pdraw); + free(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; @@ -629,17 +667,16 @@ driCreateDrawable(__GLXscreenConfigs *base, if (xDrawable != drawable) return NULL; - pdp = Xmalloc(sizeof *pdp); + pdp = calloc(1, sizeof *pdp); if (!pdp) return NULL; - memset(pdp, 0, sizeof *pdp); pdp->base.drawable = drawable; pdp->base.psc = &psc->base; if (!XF86DRICreateDrawable(psc->base.dpy, psc->base.scr, drawable, &hwDrawable)) { - Xfree(pdp); + free(pdp); return NULL; } @@ -653,7 +690,7 @@ driCreateDrawable(__GLXscreenConfigs *base, if (!pdp->driDrawable) { XF86DRIDestroyDrawable(psc->base.dpy, psc->base.scr, drawable); - Xfree(pdp); + free(pdp); return NULL; } @@ -664,28 +701,36 @@ driCreateDrawable(__GLXscreenConfigs *base, static int64_t driSwapBuffers(__GLXDRIdrawable * pdraw, int64_t unused1, int64_t unused2, - int64_t unused3) + int64_t unused3, Bool flush) { struct dri_screen *psc = (struct dri_screen *) pdraw->psc; struct dri_drawable *pdp = (struct dri_drawable *) pdraw; + if (flush) { + glFlush(); + } + (*psc->core->swapBuffers) (pdp->driDrawable); return 0; } static void driCopySubBuffer(__GLXDRIdrawable * pdraw, - int x, int y, int width, int height) + int x, int y, int width, int height, Bool flush) { struct dri_drawable *pdp = (struct dri_drawable *) pdraw; struct dri_screen *psc = (struct dri_screen *) pdp->base.psc; + if (flush) { + glFlush(); + } + (*psc->driCopySubBuffer->copySubBuffer) (pdp->driDrawable, x, y, width, height); } static void -driDestroyScreen(__GLXscreenConfigs *base) +driDestroyScreen(struct glx_screen *base) { struct dri_screen *psc = (struct dri_screen *) base; @@ -698,95 +743,33 @@ driDestroyScreen(__GLXscreenConfigs *base) dlclose(psc->driver); } -#ifdef __DRI_SWAP_BUFFER_COUNTER - -static int -driDrawableGetMSC(__GLXscreenConfigs *base, __GLXDRIdrawable *pdraw, - int64_t *ust, int64_t *msc, int64_t *sbc) -{ - struct dri_screen *psc = (struct dri_screen *) base; - struct dri_drawable *pdp = (struct dri_drawable *) pdraw; - - if (pdp && psc->sbc && psc->msc) - return ( (*psc->msc->getMSC)(psc->driScreen, msc) == 0 && - (*psc->sbc->getSBC)(pdp->driDrawable, sbc) == 0 && - __glXGetUST(ust) == 0 ); -} - -static int -driWaitForMSC(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, - int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc) -{ - struct dri_screen *psc = (struct dri_screen *) pdraw->psc; - struct dri_drawable *pdp = (struct dri_drawable *) pdraw; - - if (pdp != NULL && psc->msc != NULL) { - ret = (*psc->msc->waitForMSC) (pdp->driDrawable, target_msc, - divisor, remainder, msc, sbc); - - /* __glXGetUST returns zero on success and non-zero on failure. - * This function returns True on success and False on failure. - */ - return ret == 0 && __glXGetUST(ust) == 0; - } -} - -static int -driWaitForSBC(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust, - int64_t *msc, int64_t *sbc) -{ - struct dri_drawable *pdp = (struct dri_drawable *) pdraw; - - if (pdp != NULL && psc->sbc != NULL) { - ret = - (*psc->sbc->waitForSBC) (pdp->driDrawable, target_sbc, msc, sbc); - - /* __glXGetUST returns zero on success and non-zero on failure. - * This function returns True on success and False on failure. - */ - return ((ret == 0) && (__glXGetUST(ust) == 0)); - } - - return DRI2WaitSBC(pdp->base.psc->dpy, - pdp->base.xDrawable, target_sbc, ust, msc, sbc); -} - -#endif - 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; + if (pdraw != NULL) { + 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) { + psc->swapControl->setSwapInterval(pdp->driDrawable, interval); + return 0; } } - return GLX_BAD_CONTEXT; } static int driGetSwapInterval(__GLXDRIdrawable *pdraw) { - GLXContext gc = __glXGetCurrentContext(); struct dri_drawable *pdp = (struct dri_drawable *) pdraw; - struct dri_screen *psc; - if (gc != NULL && gc->driContext) { - psc = (struct dri_screen *) pdraw->psc; + if (pdraw != NULL) { + struct dri_screen *psc = (struct dri_screen *) pdraw->psc; - if (psc->swapControl != NULL && pdraw != NULL) { - return psc->swapControl->getSwapInterval(pdp->driDrawable); - } + if (psc->swapControl != NULL) + return psc->swapControl->getSwapInterval(pdp->driDrawable); } - return 0; } @@ -823,11 +806,14 @@ driBindExtensions(struct dri_screen *psc, const __DRIextension **extensions) } static const struct glx_screen_vtable dri_screen_vtable = { - dri_create_context + .create_context = dri_create_context, + .create_context_attribs = NULL, + .query_renderer_integer = NULL, + .query_renderer_string = 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; @@ -836,31 +822,27 @@ driCreateScreen(int screen, __GLXdisplayPrivate *priv) char *driverName; int i; - psc = Xcalloc(1, sizeof *psc); + psc = calloc(1, sizeof *psc); if (psc == NULL) return NULL; - memset(psc, 0, sizeof *psc); - if (!glx_screen_init(&psc->base, screen, priv)) - return NULL; + if (!glx_screen_init(&psc->base, screen, priv)) { + free(psc); + return NULL; + } if (!driGetDriverName(priv->dpy, screen, &driverName)) { - Xfree(psc); - return NULL; + 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++) { @@ -870,19 +852,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); @@ -897,16 +874,24 @@ driCreateScreen(int screen, __GLXdisplayPrivate *priv) psp->createDrawable = driCreateDrawable; psp->swapBuffers = driSwapBuffers; -#ifdef __DRI_SWAP_BUFFER_COUNTER - psp->getDrawableMSC = driDrawableGetMSC; - psp->waitForMSC = driWaitForMSC; - psp->waitForSBC = driWaitForSBC; -#endif - psp->setSwapInterval = driSetSwapInterval; psp->getSwapInterval = driGetSwapInterval; + free(driverName); + return &psc->base; + +cleanup: + CriticalErrorMessageF("failed to load driver: %s\n", driverName); + + free(driverName); + + if (psc->driver) + dlclose(psc->driver); + glx_screen_cleanup(&psc->base); + free(psc); + + return NULL; } /* Called from __glXFreeDisplayPrivate. @@ -914,7 +899,7 @@ driCreateScreen(int screen, __GLXdisplayPrivate *priv) static void driDestroyDisplay(__GLXDRIdisplay * dpy) { - Xfree(dpy); + free(dpy); } /* @@ -937,7 +922,7 @@ driCreateDisplay(Display * dpy) return NULL; } - pdpyp = Xmalloc(sizeof *pdpyp); + pdpyp = malloc(sizeof *pdpyp); if (!pdpyp) { return NULL; }