diff options
Diffstat (limited to 'src/glx')
-rw-r--r-- | src/glx/x11/Makefile | 5 | ||||
-rw-r--r-- | src/glx/x11/dri2.c | 252 | ||||
-rw-r--r-- | src/glx/x11/dri2.h | 53 | ||||
-rw-r--r-- | src/glx/x11/dri2_glx.c | 471 | ||||
-rw-r--r-- | src/glx/x11/dri_glx.c | 398 | ||||
-rw-r--r-- | src/glx/x11/glx_pbuffer.c | 70 | ||||
-rw-r--r-- | src/glx/x11/glxclient.h | 38 | ||||
-rw-r--r-- | src/glx/x11/glxcmds.c | 140 | ||||
-rw-r--r-- | src/glx/x11/glxext.c | 66 | ||||
-rw-r--r-- | src/glx/x11/glxextensions.c | 62 | ||||
-rw-r--r-- | src/glx/x11/glxextensions.h | 6 |
11 files changed, 1305 insertions, 256 deletions
diff --git a/src/glx/x11/Makefile b/src/glx/x11/Makefile index 8fa3700a04c..2d44e8df7a1 100644 --- a/src/glx/x11/Makefile +++ b/src/glx/x11/Makefile @@ -32,7 +32,9 @@ SOURCES = \ glx_texture_compression.c \ dri_glx.c \ XF86dri.c \ - glxhash.c + glxhash.c \ + dri2_glx.c \ + dri2.c include $(TOP)/src/mesa/sources @@ -48,6 +50,7 @@ INCLUDES = -I. \ -I$(TOP)/src/mesa/main \ -I$(TOP)/src/mesa/glapi \ $(LIBDRM_CFLAGS) \ + $(DRI2PROTO_CFLAGS) \ $(X11_INCLUDES) diff --git a/src/glx/x11/dri2.c b/src/glx/x11/dri2.c new file mode 100644 index 00000000000..c3012c4e5fb --- /dev/null +++ b/src/glx/x11/dri2.c @@ -0,0 +1,252 @@ +/* + * Copyright © 2008 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Soft- + * ware"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, provided that the above copyright + * notice(s) and this permission notice appear in all copies of the Soft- + * ware and that both the above copyright notice(s) and this permission + * notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- + * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY + * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN + * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- + * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- + * MANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization of + * the copyright holder. + * + * Authors: + * Kristian Høgsberg ([email protected]) + */ + + +#define NEED_REPLIES +#include <X11/Xlibint.h> +#include <X11/extensions/Xext.h> +#include <X11/extensions/extutil.h> +#include "glheader.h" +#include "xf86drm.h" +#include "dri2proto.h" +#include "dri2.h" + +static char dri2ExtensionName[] = DRI2_NAME; +static XExtensionInfo *dri2Info; +static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info) +static /* const */ XExtensionHooks dri2ExtensionHooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + DRI2CloseDisplay, /* close_display */ + NULL, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, dri2Info, + dri2ExtensionName, + &dri2ExtensionHooks, + 0, NULL) + +Bool DRI2QueryExtension(Display *dpy, int *eventBase, int *errorBase) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + + if (XextHasExtension(info)) { + *eventBase = info->codes->first_event; + *errorBase = info->codes->first_error; + return True; + } + + return False; +} + +Bool DRI2QueryVersion(Display *dpy, int *major, int *minor) +{ + XExtDisplayInfo *info = DRI2FindDisplay (dpy); + xDRI2QueryVersionReply rep; + xDRI2QueryVersionReq *req; + + XextCheckExtension (dpy, info, dri2ExtensionName, False); + + LockDisplay(dpy); + GetReq(DRI2QueryVersion, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2QueryVersion; + req->majorVersion = DRI2_MAJOR; + req->minorVersion = DRI2_MINOR; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + *major = rep.majorVersion; + *minor = rep.minorVersion; + UnlockDisplay(dpy); + SyncHandle(); + + return True; +} + +Bool DRI2Connect(Display *dpy, int screen, + char **driverName, char **busId, unsigned int *sareaHandle) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2ConnectReply rep; + xDRI2ConnectReq *req; + + XextCheckExtension (dpy, info, dri2ExtensionName, False); + + LockDisplay(dpy); + GetReq(DRI2Connect, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2Connect; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + *sareaHandle = rep.sareaHandle; + + *driverName = Xmalloc(rep.driverNameLength + 1); + if (*driverName == NULL) { + _XEatData(dpy, + ((rep.driverNameLength + 3) & ~3) + + ((rep.busIdLength + 3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + _XReadPad(dpy, *driverName, rep.driverNameLength); + (*driverName)[rep.driverNameLength] = '\0'; + + *busId = Xmalloc(rep.busIdLength + 1); + if (*busId == NULL) { + Xfree(*driverName); + _XEatData(dpy, ((rep.busIdLength + 3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + _XReadPad(dpy, *busId, rep.busIdLength); + (*busId)[rep.busIdLength] = '\0'; + + UnlockDisplay(dpy); + SyncHandle(); + + return rep.sareaHandle != 0; +} + +Bool DRI2AuthConnection(Display *dpy, int screen, drm_magic_t magic) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2AuthConnectionReq *req; + xDRI2AuthConnectionReply rep; + + XextCheckExtension (dpy, info, dri2ExtensionName, False); + + LockDisplay(dpy); + GetReq(DRI2AuthConnection, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2AuthConnection; + req->screen = screen; + req->magic = magic; + rep.authenticated = 0; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + + return rep.authenticated; +} + +Bool DRI2CreateDrawable(Display *dpy, XID drawable, + unsigned int *handle, unsigned int *head) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2CreateDrawableReply rep; + xDRI2CreateDrawableReq *req; + + XextCheckExtension (dpy, info, dri2ExtensionName, False); + + LockDisplay(dpy); + GetReq(DRI2CreateDrawable, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2CreateDrawable; + req->drawable = drawable; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + + *handle = rep.handle; + *head = rep.head; + + return True; +} + +void DRI2DestroyDrawable(Display *dpy, XID drawable) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2DestroyDrawableReq *req; + + XextSimpleCheckExtension (dpy, info, dri2ExtensionName); + + XSync(dpy, GL_FALSE); + + LockDisplay(dpy); + GetReq(DRI2DestroyDrawable, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2DestroyDrawable; + req->drawable = drawable; + UnlockDisplay(dpy); + SyncHandle(); +} + +Bool DRI2ReemitDrawableInfo(Display *dpy, XID drawable, unsigned int *head) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2ReemitDrawableInfoReply rep; + xDRI2ReemitDrawableInfoReq *req; + + XextCheckExtension (dpy, info, dri2ExtensionName, False); + + LockDisplay(dpy); + GetReq(DRI2ReemitDrawableInfo, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2ReemitDrawableInfo; + req->drawable = drawable; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + + *head = rep.head; + + return True; +} diff --git a/src/glx/x11/dri2.h b/src/glx/x11/dri2.h new file mode 100644 index 00000000000..1dfd0448b2f --- /dev/null +++ b/src/glx/x11/dri2.h @@ -0,0 +1,53 @@ +/* + * Copyright © 2007,2008 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Soft- + * ware"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, provided that the above copyright + * notice(s) and this permission notice appear in all copies of the Soft- + * ware and that both the above copyright notice(s) and this permission + * notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- + * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY + * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN + * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- + * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- + * MANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization of + * the copyright holder. + * + * Authors: + * Kristian Høgsberg ([email protected]) + */ + +#ifndef _DRI2_H_ +#define _DRI2_H_ + +extern Bool +DRI2QueryExtension(Display *display, int *eventBase, int *errorBase); +extern Bool +DRI2QueryVersion(Display *display, int *major, int *minor); +extern Bool +DRI2Connect(Display *display, int screen, + char **driverName, char **busId, unsigned int *sareaHandle); +extern Bool +DRI2AuthConnection(Display *display, int screen, drm_magic_t magic); +extern Bool +DRI2CreateDrawable(Display *display, XID drawable, + unsigned int *handle, unsigned int *head); +extern void +DRI2DestroyDrawable(Display *display, XID handle); +extern Bool +DRI2ReemitDrawableInfo(Display *dpy, XID handle, unsigned int *head); + +#endif diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c new file mode 100644 index 00000000000..1a6abaedab8 --- /dev/null +++ b/src/glx/x11/dri2_glx.c @@ -0,0 +1,471 @@ +/* + * Copyright © 2008 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Soft- + * ware"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, provided that the above copyright + * notice(s) and this permission notice appear in all copies of the Soft- + * ware and that both the above copyright notice(s) and this permission + * notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- + * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY + * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN + * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- + * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- + * MANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization of + * the copyright holder. + * + * Authors: + * Kristian Høgsberg ([email protected]) + */ + +#ifdef GLX_DIRECT_RENDERING + +#include <unistd.h> +#include <X11/Xlibint.h> +#include <X11/extensions/Xext.h> +#include <X11/extensions/extutil.h> +#include <X11/extensions/Xfixes.h> +#include <X11/extensions/Xdamage.h> +#include "glheader.h" +#include "glxclient.h" +#include "xf86dri.h" +#include "sarea.h" +#include <stdio.h> +#include <dlfcn.h> +#include <sys/types.h> +#include <stdarg.h> +#include "glcontextmodes.h" +#include <sys/mman.h> +#include "xf86drm.h" +#include "dri2.h" + + +#ifndef RTLD_NOW +#define RTLD_NOW 0 +#endif +#ifndef RTLD_GLOBAL +#define RTLD_GLOBAL 0 +#endif + +typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate; +typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate; +typedef struct __GLXDRIconfigPrivateRec __GLXDRIconfigPrivate; + +struct __GLXDRIdisplayPrivateRec { + __GLXDRIdisplay base; + + /* + ** XFree86-DRI version information + */ + int driMajor; + int driMinor; + int driPatch; +}; + +struct __GLXDRIcontextPrivateRec { + __GLXDRIcontext base; + __DRIcontext *driContext; + __GLXscreenConfigs *psc; +}; + +struct __GLXDRIconfigPrivateRec { + __GLcontextModes modes; + const __DRIconfig *driConfig; +}; + +static void dri2DestroyContext(__GLXDRIcontext *context, + __GLXscreenConfigs *psc, Display *dpy) +{ + __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context; + const __DRIcoreExtension *core = pcp->psc->core; + + (*core->destroyContext)(pcp->driContext); + + Xfree(pcp); +} + +static Bool dri2BindContext(__GLXDRIcontext *context, + __GLXDRIdrawable *draw, __GLXDRIdrawable *read) +{ + __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context; + const __DRIcoreExtension *core = pcp->psc->core; + + return (*core->bindContext)(pcp->driContext, + draw->driDrawable, + read->driDrawable); +} + +static void dri2UnbindContext(__GLXDRIcontext *context) +{ + __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context; + const __DRIcoreExtension *core = pcp->psc->core; + + (*core->unbindContext)(pcp->driContext); +} + +static __GLXDRIcontext *dri2CreateContext(__GLXscreenConfigs *psc, + const __GLcontextModes *mode, + GLXContext gc, + GLXContext shareList, int renderType) +{ + __GLXDRIcontextPrivate *pcp, *pcp_shared; + __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode; + const __DRIcoreExtension *core = psc->core; + __DRIcontext *shared = NULL; + + if (shareList) { + pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext; + shared = pcp_shared->driContext; + } + + pcp = Xmalloc(sizeof *pcp); + if (pcp == NULL) + return NULL; + + pcp->psc = psc; + pcp->driContext = + (*core->createNewContext)(psc->__driScreen, + config->driConfig, shared, pcp); + gc->__driContext = pcp->driContext; + + if (pcp->driContext == NULL) { + Xfree(pcp); + return NULL; + } + + pcp->base.destroyContext = dri2DestroyContext; + pcp->base.bindContext = dri2BindContext; + pcp->base.unbindContext = dri2UnbindContext; + + return &pcp->base; +} + +static void dri2DestroyDrawable(__GLXDRIdrawable *pdraw) +{ + const __DRIcoreExtension *core = pdraw->psc->core; + + (*core->destroyDrawable)(pdraw->driDrawable); + DRI2DestroyDrawable(pdraw->psc->dpy, pdraw->drawable); + Xfree(pdraw); +} + +static __GLXDRIdrawable *dri2CreateDrawable(__GLXscreenConfigs *psc, + XID xDrawable, + GLXDrawable drawable, + const __GLcontextModes *modes) +{ + __GLXDRIdrawable *pdraw; + __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes; + unsigned int handle, head; + const __DRIcoreExtension *core = psc->core; + + pdraw = Xmalloc(sizeof(*pdraw)); + if (!pdraw) + return NULL; + + pdraw->destroyDrawable = dri2DestroyDrawable; + pdraw->xDrawable = xDrawable; + pdraw->drawable = drawable; + pdraw->psc = psc; + + fprintf(stderr, "calling DRI2CreateDrawable, XID 0x%lx, GLX ID 0x%lx\n", + xDrawable, drawable); + + if (!DRI2CreateDrawable(psc->dpy, xDrawable, &handle, &head)) { + Xfree(pdraw); + return NULL; + } + + fprintf(stderr, "success, head 0x%x, handle 0x%x\n", head, handle); + + /* Create a new drawable */ + pdraw->driDrawable = + (*core->createNewDrawable)(psc->__driScreen, + config->driConfig, + handle, + head, + pdraw); + + if (!pdraw->driDrawable) { + DRI2DestroyDrawable(psc->dpy, drawable); + Xfree(pdraw); + return NULL; + } + + return pdraw; +} + +static void dri2DestroyScreen(__GLXscreenConfigs *psc) +{ + /* Free the direct rendering per screen data */ + (*psc->core->destroyScreen)(psc->__driScreen); + drmClose(psc->fd); + psc->__driScreen = NULL; +} + + +static void dri2ReemitDrawableInfo(__DRIdrawable *draw, unsigned int *tail, + void *loaderPrivate) +{ + __GLXDRIdrawable *pdraw = loaderPrivate; + + DRI2ReemitDrawableInfo(pdraw->psc->dpy, pdraw->drawable, tail); +} + +static void dri2PostDamage(__DRIdrawable *draw, + struct drm_clip_rect *rects, + int numRects, void *loaderPrivate) +{ + XRectangle *xrects; + XserverRegion region; + __GLXDRIdrawable *glxDraw = loaderPrivate; + __GLXscreenConfigs *psc = glxDraw->psc; + Display *dpy = psc->dpy; + int i; + + xrects = malloc(sizeof(XRectangle) * numRects); + if (xrects == NULL) + return; + + for (i = 0; i < numRects; i++) { + xrects[i].x = rects[i].x1; + xrects[i].y = rects[i].y1; + xrects[i].width = rects[i].x2 - rects[i].x1; + xrects[i].height = rects[i].y2 - rects[i].y1; + } + region = XFixesCreateRegion(dpy, xrects, numRects); + free(xrects); + XDamageAdd(dpy, glxDraw->xDrawable, region); + XFixesDestroyRegion(dpy, region); +} + +static const __DRIloaderExtension dri2LoaderExtension = { + { __DRI_LOADER, __DRI_LOADER_VERSION }, + dri2ReemitDrawableInfo, + dri2PostDamage +}; + +_X_HIDDEN const __DRIsystemTimeExtension systemTimeExtension; + +static const __DRIextension *loader_extensions[] = { + &dri2LoaderExtension.base, + &systemTimeExtension.base, + NULL +}; + +/* We need a dri_common.h type-of-thing. */ + +extern void ErrorMessageF(const char *f, ...); + +extern void *driOpenDriver(const char *driverName); + +extern __GLcontextModes * +driConvertConfigs(const __DRIcoreExtension *core, + __GLcontextModes *modes, const __DRIconfig **configs); + +extern void driBindExtensions(__GLXscreenConfigs *psc); + +void +driBindExtensions(__GLXscreenConfigs *psc) +{ + const __DRIextension **extensions; + int i; + + extensions = psc->core->getExtensions(psc->__driScreen); + + for (i = 0; extensions[i]; i++) { +#ifdef __DRI_COPY_SUB_BUFFER + if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { + psc->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i]; + __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer_bit"); + } +#endif + +#ifdef __DRI_SWAP_CONTROL + if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) { + psc->swapControl = (__DRIswapControlExtension *) extensions[i]; + __glXEnableDirectExtension(psc, "GLX_SGI_swap_control"); + __glXEnableDirectExtension(psc, "GLX_MESA_swap_control"); + } +#endif + +#ifdef __DRI_ALLOCATE + if (strcmp(extensions[i]->name, __DRI_ALLOCATE) == 0) { + psc->allocate = (__DRIallocateExtension *) extensions[i]; + __glXEnableDirectExtension(psc, "GLX_MESA_allocate_memory"); + } +#endif + +#ifdef __DRI_FRAME_TRACKING + if (strcmp(extensions[i]->name, __DRI_FRAME_TRACKING) == 0) { + psc->frameTracking = (__DRIframeTrackingExtension *) extensions[i]; + __glXEnableDirectExtension(psc, "GLX_MESA_swap_frame_usage"); + } +#endif + +#ifdef __DRI_MEDIA_STREAM_COUNTER + if (strcmp(extensions[i]->name, __DRI_MEDIA_STREAM_COUNTER) == 0) { + psc->msc = (__DRImediaStreamCounterExtension *) extensions[i]; + __glXEnableDirectExtension(psc, "GLX_SGI_video_sync"); + } +#endif + +#ifdef __DRI_SWAP_BUFFER_COUNTER + /* No driver supports this at this time and the extension is + * not defined in dri_interface.h. Will enable + * GLX_OML_sync_control if implemented. */ +#endif + +#ifdef __DRI_READ_DRAWABLE + if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) { + __glXEnableDirectExtension(psc, "GLX_SGI_make_current_read"); + } +#endif + +#ifdef __DRI_TEX_BUFFER + if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) { + psc->texBuffer = (__DRItexBufferExtension *) extensions[i]; + __glXEnableDirectExtension(psc, "GLX_EXT_texture_from_pixmap"); + } +#endif + + /* Ignore unknown extensions */ + } +} + +static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen, + __GLXdisplayPrivate *priv) +{ + const __DRIconfig **driver_configs; + const __DRIextension **extensions; + __GLXDRIscreen *psp; + unsigned int sareaHandle; + char *driverName, *busID; + drm_magic_t magic; + int i; + + psp = Xmalloc(sizeof *psp); + if (psp == NULL) + return NULL; + + /* Initialize per screen dynamic client GLX extensions */ + psc->ext_list_first_time = GL_TRUE; + + if (!DRI2Connect(psc->dpy, screen, &driverName, &busID, &sareaHandle)) + return NULL; + + psc->driver = driOpenDriver(driverName); + if (psc->driver == NULL) + goto handle_error; + + extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS); + if (extensions == NULL) { + ErrorMessageF("driver exports no extensions (%s)\n", dlerror()); + goto handle_error; + } + + for (i = 0; extensions[i]; i++) { + if (strcmp(extensions[i]->name, __DRI_CORE) == 0) + psc->core = (__DRIcoreExtension *) extensions[i]; + } + + if (psc->core == NULL) { + ErrorMessageF("core dri extension not found\n"); + goto handle_error; + } + + psc->fd = drmOpen(NULL, busID); + if (psc->fd < 0) { + ErrorMessageF("failed to open drm device: %s\n", strerror(errno)); + return NULL; + } + + if (drmGetMagic(psc->fd, &magic)) + return NULL; + + if (!DRI2AuthConnection(psc->dpy, screen, magic)) { + ErrorMessageF("failed to authenticate drm access\n"); + return NULL; + } + + psc->__driScreen = + psc->core->createNewScreen(screen, psc->fd, sareaHandle, + loader_extensions, &driver_configs, psc); + if (psc->__driScreen == NULL) { + ErrorMessageF("failed to create dri screen\n"); + return NULL; + } + + driBindExtensions(psc); + + psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs); + psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs); + + psp->destroyScreen = dri2DestroyScreen; + psp->createContext = dri2CreateContext; + psp->createDrawable = dri2CreateDrawable; + + Xfree(driverName); + Xfree(busID); + + return psp; + + handle_error: + Xfree(driverName); + Xfree(busID); + + /* FIXME: clean up here */ + + return NULL; +} + +/* Called from __glXFreeDisplayPrivate. + */ +static void dri2DestroyDisplay(__GLXDRIdisplay *dpy) +{ + Xfree(dpy); +} + +/* + * Allocate, initialize and return a __DRIdisplayPrivate object. + * This is called from __glXInitialize() when we are given a new + * display pointer. + */ +_X_HIDDEN __GLXDRIdisplay *dri2CreateDisplay(Display *dpy) +{ + __GLXDRIdisplayPrivate *pdp; + int eventBase, errorBase; + + if (!DRI2QueryExtension(dpy, &eventBase, &errorBase)) + return NULL; + + pdp = Xmalloc(sizeof *pdp); + if (pdp == NULL) + return NULL; + + if (!DRI2QueryVersion(dpy, &pdp->driMajor, &pdp->driMinor)) { + Xfree(pdp); + return NULL; + } + + pdp->driPatch = 0; + + pdp->base.destroyDisplay = dri2DestroyDisplay; + pdp->base.createScreen = dri2CreateScreen; + + return &pdp->base; +} + +#endif /* GLX_DIRECT_RENDERING */ diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c index 514c082f6cd..31ade0da2a3 100644 --- a/src/glx/x11/dri_glx.c +++ b/src/glx/x11/dri_glx.c @@ -52,7 +52,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <sys/mman.h> #include "xf86drm.h" - #ifndef RTLD_NOW #define RTLD_NOW 0 #endif @@ -62,6 +61,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate; typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate; +typedef struct __GLXDRIconfigPrivateRec __GLXDRIconfigPrivate; struct __GLXDRIdisplayPrivateRec { __GLXDRIdisplay base; @@ -76,8 +76,14 @@ struct __GLXDRIdisplayPrivateRec { struct __GLXDRIcontextPrivateRec { __GLXDRIcontext base; - __DRIcontext driContext; + __DRIcontext *driContext; XID hwContextID; + __GLXscreenConfigs *psc; +}; + +struct __GLXDRIconfigPrivateRec { + __GLcontextModes modes; + const __DRIconfig *driConfig; }; #ifndef DEFAULT_DRIVER_DIR @@ -98,10 +104,12 @@ static void InfoMessageF(const char *f, ...) } } +extern void ErrorMessageF(const char *f, ...); + /** * Print error to stderr, unless LIBGL_DEBUG=="quiet". */ -static void ErrorMessageF(const char *f, ...) +_X_HIDDEN void ErrorMessageF(const char *f, ...) { va_list args; const char *env; @@ -114,16 +122,7 @@ static void ErrorMessageF(const char *f, ...) } } - -/** - * Versioned name of the expected \c __driCreateNewScreen function. - * - * The version of the last incompatible loader/driver inteface change is - * appended to the name of the \c __driCreateNewScreen function. This - * prevents loaders from trying to load drivers that are too old. - */ -static const char createNewScreenName[] = __DRI_CREATE_NEW_SCREEN_STRING; - +extern void *driOpenDriver(const char *driverName); /** * Try to \c dlopen the named driver. @@ -137,7 +136,7 @@ static const char createNewScreenName[] = __DRI_CREATE_NEW_SCREEN_STRING; * \returns * A handle from \c dlopen, or \c NULL if driver file not found. */ -static void *OpenDriver(const char *driverName) +_X_HIDDEN void *driOpenDriver(const char *driverName) { void *glhandle, *handle; const char *libPaths, *p, *next; @@ -244,7 +243,7 @@ static void *driGetDriver(Display *dpy, int scrNum) void *ret; if (GetDriverName(dpy, scrNum, &driverName)) { - ret = OpenDriver(driverName); + ret = driOpenDriver(driverName); if (driverName) Xfree(driverName); return ret; @@ -287,17 +286,22 @@ PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) { * * Note: The driver remains opened after this function returns. */ -PUBLIC const char *glXGetDriverConfig (const char *driverName) { - void *handle = OpenDriver (driverName); +PUBLIC const char *glXGetDriverConfig (const char *driverName) +{ + void *handle = driOpenDriver (driverName); if (handle) return dlsym (handle, "__driConfigOptions"); else return NULL; } -static void -filter_modes( __GLcontextModes ** server_modes, - const __GLcontextModes * driver_modes ) +extern void +driFilterModes(__GLcontextModes ** server_modes, + const __GLcontextModes * driver_modes); + +_X_HIDDEN void +driFilterModes(__GLcontextModes ** server_modes, + const __GLcontextModes * driver_modes) { __GLcontextModes * m; __GLcontextModes ** prev_next; @@ -349,6 +353,7 @@ filter_modes( __GLcontextModes ** server_modes, } #ifdef XDAMAGE_1_1_INTERFACE + static GLboolean has_damage_post(Display *dpy) { static GLboolean inited = GL_FALSE; @@ -369,20 +374,18 @@ static GLboolean has_damage_post(Display *dpy) return has_damage; } -#endif /* XDAMAGE_1_1_INTERFACE */ static void __glXReportDamage(__DRIdrawable *driDraw, int x, int y, drm_clip_rect_t *rects, int num_rects, - GLboolean front_buffer) + GLboolean front_buffer, + void *loaderPrivate) { -#ifdef XDAMAGE_1_1_INTERFACE XRectangle *xrects; XserverRegion region; int i; int x_off, y_off; - __GLXDRIdrawable *glxDraw = - containerOf(driDraw, __GLXDRIdrawable, driDrawable); + __GLXDRIdrawable *glxDraw = loaderPrivate; __GLXscreenConfigs *psc = glxDraw->psc; Display *dpy = psc->dpy; Drawable drawable; @@ -397,7 +400,7 @@ static void __glXReportDamage(__DRIdrawable *driDraw, } else{ x_off = 0; y_off = 0; - drawable = glxDraw->drawable; + drawable = glxDraw->xDrawable; } xrects = malloc(sizeof(XRectangle) * num_rects); @@ -414,19 +417,25 @@ static void __glXReportDamage(__DRIdrawable *driDraw, free(xrects); XDamageAdd(dpy, drawable, region); XFixesDestroyRegion(dpy, region); -#endif } +static const __DRIdamageExtension damageExtension = { + { __DRI_DAMAGE, __DRI_DAMAGE_VERSION }, + __glXReportDamage, +}; + +#endif + static GLboolean __glXDRIGetDrawableInfo(__DRIdrawable *drawable, unsigned int *index, unsigned int *stamp, int *X, int *Y, int *W, int *H, int *numClipRects, drm_clip_rect_t ** pClipRects, int *backX, int *backY, - int *numBackClipRects, drm_clip_rect_t **pBackClipRects) + int *numBackClipRects, drm_clip_rect_t **pBackClipRects, + void *loaderPrivate) { - __GLXDRIdrawable *glxDraw = - containerOf(drawable, __GLXDRIdrawable, driDrawable); + __GLXDRIdrawable *glxDraw = loaderPrivate; __GLXscreenConfigs *psc = glxDraw->psc; Display *dpy = psc->dpy; @@ -437,17 +446,7 @@ __glXDRIGetDrawableInfo(__DRIdrawable *drawable, numBackClipRects, pBackClipRects); } - -/** - * Table of functions exported by the loader to the driver. - */ -static const __DRIcontextModesExtension contextModesExtension = { - { __DRI_CONTEXT_MODES, __DRI_CONTEXT_MODES_VERSION }, - _gl_context_modes_create, - _gl_context_modes_destroy, -}; - -static const __DRIsystemTimeExtension systemTimeExtension = { +_X_HIDDEN const __DRIsystemTimeExtension systemTimeExtension = { { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION }, __glXGetUST, __driGetMscRateOML, @@ -458,19 +457,189 @@ static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = { __glXDRIGetDrawableInfo }; -static const __DRIdamageExtension damageExtension = { - { __DRI_DAMAGE, __DRI_DAMAGE_VERSION }, - __glXReportDamage, -}; - static const __DRIextension *loader_extensions[] = { - &contextModesExtension.base, &systemTimeExtension.base, &getDrawableInfoExtension.base, + +#ifdef XDAMAGE_1_1_INTERFACE &damageExtension.base, +#endif + NULL }; +#define __ATTRIB(attrib, field) \ + { attrib, offsetof(__GLcontextModes, field) } + +static const struct { unsigned int attrib, offset; } attribMap[] = { + __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits), + __ATTRIB(__DRI_ATTRIB_LEVEL, level), + __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits), + __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits), + __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits), + __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits), + __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits), + __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits), + __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers), + __ATTRIB(__DRI_ATTRIB_SAMPLES, samples), + __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode), + __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode), + __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers), +#if 0 + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentIndex), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha), + __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask), + __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask), + __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask), + __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask), +#endif + __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth), + __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight), + __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels), + __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth), + __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight), +#if 0 + __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod), + __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb), + __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba), + __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture), + __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted), +#endif +}; + +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) + +static int +scalarEqual(__GLcontextModes *mode, unsigned int attrib, unsigned int value) +{ + unsigned int driValue; + int i; + + for (i = 0; i < ARRAY_SIZE(attribMap); i++) + if (attribMap[i].attrib == attrib) { + driValue = *(unsigned int *) ((char *) mode + attribMap[i].offset); + return driValue == value; + } + + return GL_TRUE; /* Is a non-existing attribute equal to value? */ +} + +static int +driConfigEqual(const __DRIcoreExtension *core, + __GLcontextModes *modes, const __DRIconfig *driConfig) +{ + unsigned int attrib, value, glxValue; + int i; + + i = 0; + while (core->indexConfigAttrib(driConfig, i++, &attrib, &value)) { + switch (attrib) { + case __DRI_ATTRIB_RENDER_TYPE: + glxValue = 0; + if (value & __DRI_ATTRIB_RGBA_BIT) { + glxValue |= GLX_RGBA_BIT; + } else if (value & __DRI_ATTRIB_COLOR_INDEX_BIT) { + glxValue |= GLX_COLOR_INDEX_BIT; + } + if (glxValue != modes->renderType) + return GL_FALSE; + break; + + case __DRI_ATTRIB_CONFIG_CAVEAT: + if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG) + glxValue = GLX_NON_CONFORMANT_CONFIG; + else if (value & __DRI_ATTRIB_SLOW_BIT) + glxValue = GLX_SLOW_CONFIG; + else + glxValue = GLX_NONE; + if (glxValue != modes->visualRating) + return GL_FALSE; + break; + +#if 0 + /* The X server doesn't send these, so ignore them for now. */ + case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS: + glxValue = 0; + if (value & __DRI_ATTRIB_TEXTURE_1D_BIT) + glxValue |= GLX_TEXTURE_1D_BIT_EXT; + if (value & __DRI_ATTRIB_TEXTURE_2D_BIT) + glxValue |= GLX_TEXTURE_2D_BIT_EXT; + if (value & __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT) + glxValue |= GLX_TEXTURE_RECTANGLE_BIT_EXT; + if (glxValue != modes->bindToTextureTargets) + return GL_FALSE; + break; +#endif + + default: + if (!scalarEqual(modes, attrib, value)) + return GL_FALSE; + } + } + + return GL_TRUE; +} + +static __GLcontextModes * +createDriMode(const __DRIcoreExtension *core, + __GLcontextModes *modes, const __DRIconfig **driConfigs) +{ + __GLXDRIconfigPrivate *config; + int i; + + for (i = 0; driConfigs[i]; i++) { + if (driConfigEqual(core, modes, driConfigs[i])) + break; + } + + if (driConfigs[i] == NULL) + return NULL; + + config = Xmalloc(sizeof *config); + if (config == NULL) + return NULL; + + config->modes = *modes; + config->driConfig = driConfigs[i]; + + return &config->modes; +} + +extern __GLcontextModes * +driConvertConfigs(const __DRIcoreExtension *core, + __GLcontextModes *modes, const __DRIconfig **configs); + +_X_HIDDEN __GLcontextModes * +driConvertConfigs(const __DRIcoreExtension *core, + __GLcontextModes *modes, const __DRIconfig **configs) +{ + __GLcontextModes head, *tail, *m; + + tail = &head; + head.next = NULL; + for (m = modes; m; m = m->next) { + tail->next = createDriMode(core, m, configs); + if (tail->next == NULL) { + /* no matching dri config for m */ + continue; + } + + + tail = tail->next; + } + + _gl_context_modes_destroy(modes); + + return head.next; +} /** * Perform the required libGL-side initialization and call the client-side @@ -491,8 +660,7 @@ static const __DRIextension *loader_extensions[] = { */ static void * CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc, - __GLXDRIdisplayPrivate * driDpy, - PFNCREATENEWSCREENFUNC createNewScreen) + __GLXDRIdisplayPrivate * driDpy) { void *psp = NULL; #ifndef GLX_USE_APPLEGL @@ -507,12 +675,12 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc, int status; const char * err_msg; const char * err_extra; + const __DRIconfig **driver_configs; dri_version.major = driDpy->driMajor; dri_version.minor = driDpy->driMinor; dri_version.patch = driDpy->driPatch; - err_msg = "XF86DRIOpenConnection"; err_extra = NULL; @@ -608,12 +776,9 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc, err_extra = strerror( -status ); if ( status == 0 ) { - __GLcontextModes * driver_modes = NULL; - err_msg = "InitDriver"; err_extra = NULL; - psp = (*createNewScreen)(scrn, - &psc->__driScreen, + psp = (*psc->legacy->createNewScreen)(scrn, & ddx_version, & dri_version, & drm_version, @@ -621,11 +786,17 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc, pSAREA, fd, loader_extensions, - & driver_modes ); - - filter_modes(&psc->configs, driver_modes); - filter_modes(&psc->visuals, driver_modes); - _gl_context_modes_destroy(driver_modes); + & driver_configs, + psc); + + psc->configs = + driConvertConfigs(psc->core, + psc->configs, + driver_configs); + psc->visuals = + driConvertConfigs(psc->core, + psc->visuals, + driver_configs); } } } @@ -674,7 +845,7 @@ static void driDestroyContext(__GLXDRIcontext *context, { __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context; - (*pcp->driContext.destroyContext)(&pcp->driContext); + (*psc->core->destroyContext)(pcp->driContext); XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID); } @@ -683,17 +854,19 @@ static Bool driBindContext(__GLXDRIcontext *context, __GLXDRIdrawable *draw, __GLXDRIdrawable *read) { __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context; + const __DRIcoreExtension *core = pcp->psc->core; - return (*pcp->driContext.bindContext)(&pcp->driContext, - &draw->driDrawable, - &read->driDrawable); + return (*core->bindContext)(pcp->driContext, + draw->driDrawable, + read->driDrawable); } static void driUnbindContext(__GLXDRIcontext *context) { __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context; + const __DRIcoreExtension *core = pcp->psc->core; - (*pcp->driContext.unbindContext)(&pcp->driContext); + (*core->unbindContext)(pcp->driContext); } static __GLXDRIcontext *driCreateContext(__GLXscreenConfigs *psc, @@ -704,17 +877,19 @@ static __GLXDRIcontext *driCreateContext(__GLXscreenConfigs *psc, __GLXDRIcontextPrivate *pcp, *pcp_shared; drm_context_t hwContext; __DRIcontext *shared = NULL; + __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode; if (psc && psc->driScreen) { if (shareList) { pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext; - shared = &pcp_shared->driContext; + shared = pcp_shared->driContext; } pcp = Xmalloc(sizeof *pcp); if (pcp == NULL) return NULL; + pcp->psc = psc; if (!XF86DRICreateContextWithConfig(psc->dpy, psc->scr, mode->visualID, &pcp->hwContextID, &hwContext)) { @@ -722,13 +897,14 @@ static __GLXDRIcontext *driCreateContext(__GLXscreenConfigs *psc, return NULL; } - pcp->driContext.private = - (*psc->__driScreen.createNewContext)(&psc->__driScreen, - mode, renderType, - shared, - hwContext, - &pcp->driContext); - if (pcp->driContext.private == NULL) { + pcp->driContext = + (*psc->legacy->createNewContext)(psc->__driScreen, + config->driConfig, + renderType, + shared, + hwContext, + pcp); + if (pcp->driContext == NULL) { XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID); Xfree(pcp); return NULL; @@ -748,18 +924,24 @@ static void driDestroyDrawable(__GLXDRIdrawable *pdraw) { __GLXscreenConfigs *psc = pdraw->psc; - (*pdraw->driDrawable.destroyDrawable)(&pdraw->driDrawable); + (*psc->core->destroyDrawable)(pdraw->driDrawable); XF86DRIDestroyDrawable(psc->dpy, psc->scr, pdraw->drawable); Xfree(pdraw); } static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc, + XID xDrawable, GLXDrawable drawable, - GLXContext gc) + const __GLcontextModes *modes) { __GLXDRIdrawable *pdraw; drm_drawable_t hwDrawable; void *empty_attribute_list = NULL; + __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes; + + /* Old dri can't handle GLX 1.3+ drawable constructors. */ + if (xDrawable != drawable) + return NULL; pdraw = Xmalloc(sizeof(*pdraw)); if (!pdraw) @@ -772,16 +954,15 @@ static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc, return NULL; /* Create a new drawable */ - pdraw->driDrawable.private = - (*psc->__driScreen.createNewDrawable)(&psc->__driScreen, - gc->mode, - &pdraw->driDrawable, - hwDrawable, - GLX_WINDOW_BIT, - 0, - empty_attribute_list); - - if (!pdraw->driDrawable.private) { + pdraw->driDrawable = + (*psc->legacy->createNewDrawable)(psc->__driScreen, + config->driConfig, + hwDrawable, + GLX_WINDOW_BIT, + empty_attribute_list, + pdraw); + + if (!pdraw->driDrawable) { XF86DRIDestroyDrawable(psc->dpy, psc->scr, drawable); Xfree(pdraw); return NULL; @@ -795,19 +976,23 @@ static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc, static void driDestroyScreen(__GLXscreenConfigs *psc) { /* Free the direct rendering per screen data */ - if (psc->__driScreen.private) - (*psc->__driScreen.destroyScreen)(&psc->__driScreen); - psc->__driScreen.private = NULL; + if (psc->__driScreen) + (*psc->core->destroyScreen)(psc->__driScreen); + psc->__driScreen = NULL; if (psc->driver) dlclose(psc->driver); } +void +driBindExtensions(__GLXscreenConfigs *psc); + static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen, __GLXdisplayPrivate *priv) { - PFNCREATENEWSCREENFUNC createNewScreen; __GLXDRIdisplayPrivate *pdp; __GLXDRIscreen *psp; + const __DRIextension **extensions; + int i; psp = Xmalloc(sizeof *psp); if (psp == NULL) @@ -817,15 +1002,40 @@ static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen, psc->ext_list_first_time = GL_TRUE; psc->driver = driGetDriver(priv->dpy, screen); - createNewScreen = dlsym(psc->driver, createNewScreenName); - if (createNewScreen == NULL) + if (psc->driver == NULL) { + Xfree(psp); + return NULL; + } + + extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS); + if (extensions == NULL) { + ErrorMessageF("driver exports no extensions (%s)\n", dlerror()); + Xfree(psp); return NULL; + } + for (i = 0; extensions[i]; i++) { + if (strcmp(extensions[i]->name, __DRI_CORE) == 0) + psc->core = (__DRIcoreExtension *) extensions[i]; + if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0) + psc->legacy = (__DRIlegacyExtension *) extensions[i]; + } + + if (psc->core == NULL || psc->legacy == NULL) { + Xfree(psp); + return NULL; + } + pdp = (__GLXDRIdisplayPrivate *) priv->driDisplay; - psc->__driScreen.private = - CallCreateNewScreen(psc->dpy, screen, psc, pdp, createNewScreen); - if (psc->__driScreen.private != NULL) - __glXScrEnableDRIExtension(psc); + psc->__driScreen = + CallCreateNewScreen(psc->dpy, screen, psc, pdp); + if (psc->__driScreen == NULL) { + dlclose(psc->driver); + Xfree(psp); + return NULL; + } + + driBindExtensions(psc); psp->destroyScreen = driDestroyScreen; psp->createContext = driCreateContext; diff --git a/src/glx/x11/glx_pbuffer.c b/src/glx/x11/glx_pbuffer.c index 52dad65170f..b0a8f71fd4a 100644 --- a/src/glx/x11/glx_pbuffer.c +++ b/src/glx/x11/glx_pbuffer.c @@ -271,6 +271,32 @@ GetDrawableAttribute( Display *dpy, GLXDrawable drawable, return 0; } +#ifdef GLX_DIRECT_RENDERING +extern __GLXDRIdrawable * +GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num); + +static GLenum +determineTextureTarget(const int *attribs, int numAttribs) +{ + GLenum target = 0; + int i; + + for (i = 0; i < numAttribs; i++) { + if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) { + switch (attribs[2 * i + 1]) { + case GLX_TEXTURE_2D_EXT: + target = GL_TEXTURE_2D; + break; + case GLX_TEXTURE_RECTANGLE_EXT: + target = GL_TEXTURE_RECTANGLE_ARB; + break; + } + } + } + + return target; +} +#endif /** * Create a non-pbuffer GLX drawable. @@ -306,7 +332,7 @@ CreateDrawable( Display *dpy, const __GLcontextModes * fbconfig, req->glxCode = glxCode; req->screen = (CARD32) fbconfig->screen; req->fbconfig = fbconfig->fbconfigID; - req->window = (GLXPbuffer) drawable; + req->window = (CARD32) drawable; req->glxwindow = (GLXWindow) XAllocID(dpy); req->numAttribs = (CARD32) i; @@ -315,6 +341,34 @@ CreateDrawable( Display *dpy, const __GLcontextModes * fbconfig, UnlockDisplay(dpy); SyncHandle(); +#ifdef GLX_DIRECT_RENDERING + do { + /* FIXME: Maybe delay __DRIdrawable creation until the drawable + * is actually bound to a context... */ + + __GLXdisplayPrivate * const priv = __glXInitialize(dpy); + __GLXDRIdrawable *pdraw; + __GLXscreenConfigs *psc; + + psc = &priv->screenConfigs[fbconfig->screen]; + if (psc->driScreen == NULL) + break; + pdraw = psc->driScreen->createDrawable(psc, drawable, + req->glxwindow, fbconfig); + if (pdraw == NULL) { + fprintf(stderr, "failed to create drawable\n"); + break; + } + + if (__glxHashInsert(psc->drawHash, req->glxwindow, pdraw)) { + (*pdraw->destroyDrawable)(pdraw); + return None; /* FIXME: Check what we're supposed to do here... */ + } + + pdraw->textureTarget = determineTextureTarget(attrib_list, i); + } while (0); +#endif + return (GLXDrawable)req->glxwindow; } @@ -350,6 +404,20 @@ DestroyDrawable( Display * dpy, GLXDrawable drawable, CARD32 glxCode ) UnlockDisplay(dpy); SyncHandle(); +#ifdef GLX_DIRECT_RENDERING + { + int screen; + __GLXdisplayPrivate * const priv = __glXInitialize(dpy); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); + __GLXscreenConfigs *psc = &priv->screenConfigs[screen]; + + if (pdraw != NULL) { + (*pdraw->destroyDrawable)(pdraw); + __glxHashDelete(psc->drawHash, drawable); + } + } +#endif + return; } diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h index ea90282b08f..5fd64209df5 100644 --- a/src/glx/x11/glxclient.h +++ b/src/glx/x11/glxclient.h @@ -59,7 +59,6 @@ #include "GL/glxproto.h" #include "GL/internal/glcore.h" #include "glapitable.h" -#include "glxextensions.h" #include "glxhash.h" #if defined( USE_XTHREADS ) # include <X11/Xthreads.h> @@ -97,6 +96,8 @@ typedef struct __GLXDRIscreenRec __GLXDRIscreen; typedef struct __GLXDRIdrawableRec __GLXDRIdrawable; typedef struct __GLXDRIcontextRec __GLXDRIcontext; +#include "glxextensions.h" + struct __GLXDRIdisplayRec { /** * Method to destroy the private DRI display data. @@ -117,8 +118,9 @@ struct __GLXDRIscreenRec { GLXContext shareList, int renderType); __GLXDRIdrawable *(*createDrawable)(__GLXscreenConfigs *psc, - GLXDrawable drawable, - GLXContext gc); + XID drawable, + GLXDrawable glxDrawable, + const __GLcontextModes *modes); }; struct __GLXDRIcontextRec { @@ -134,9 +136,11 @@ struct __GLXDRIcontextRec { struct __GLXDRIdrawableRec { void (*destroyDrawable)(__GLXDRIdrawable *drawable); + XID xDrawable; XID drawable; __GLXscreenConfigs *psc; - __DRIdrawable driDrawable; + __DRIdrawable *driDrawable; + GLenum textureTarget; }; /* @@ -144,6 +148,7 @@ struct __GLXDRIdrawableRec { ** dependent methods. */ extern __GLXDRIdisplay *driCreateDisplay(Display *dpy); +extern __GLXDRIdisplay *dri2CreateDisplay(Display *dpy); extern void DRI_glXUseXFont( Font font, int first, int count, int listbase ); @@ -364,6 +369,7 @@ struct __GLXcontextRec { #ifdef GLX_DIRECT_RENDERING __GLXDRIcontext *driContext; + __DRIcontext *__driContext; #endif /** @@ -458,32 +464,38 @@ struct __GLXscreenConfigsRec { /** * Per screen direct rendering interface functions and data. */ - __DRIscreen __driScreen; + __DRIscreen *__driScreen; + const __DRIcoreExtension *core; + const __DRIlegacyExtension *legacy; __glxHashTable *drawHash; Display *dpy; - int scr; + int scr, fd; void *driver; __GLXDRIscreen *driScreen; #ifdef __DRI_COPY_SUB_BUFFER - __DRIcopySubBufferExtension *copySubBuffer; + const __DRIcopySubBufferExtension *copySubBuffer; #endif #ifdef __DRI_SWAP_CONTROL - __DRIswapControlExtension *swapControl; + const __DRIswapControlExtension *swapControl; #endif #ifdef __DRI_ALLOCATE - __DRIallocateExtension *allocate; + const __DRIallocateExtension *allocate; #endif #ifdef __DRI_FRAME_TRACKING - __DRIframeTrackingExtension *frameTracking; + const __DRIframeTrackingExtension *frameTracking; #endif #ifdef __DRI_MEDIA_STREAM_COUNTER - __DRImediaStreamCounterExtension *msc; + const __DRImediaStreamCounterExtension *msc; +#endif + +#ifdef __DRI_TEX_BUFFER + const __DRItexBufferExtension *texBuffer; #endif #endif @@ -555,6 +567,7 @@ struct __GLXdisplayPrivateRec { * Per display direct rendering interface functions and data. */ __GLXDRIdisplay *driDisplay; + __GLXDRIdisplay *dri2Display; #endif }; @@ -720,7 +733,8 @@ extern GLboolean __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, #ifdef GLX_DIRECT_RENDERING GLboolean -__driGetMscRateOML(__DRIdrawable *draw, int32_t *numerator, int32_t *denominator); +__driGetMscRateOML(__DRIdrawable *draw, + int32_t *numerator, int32_t *denominator, void *private); #endif #endif /* !__GLX_client_h__ */ diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c index 8d0f07fd0a1..ddb006193c2 100644 --- a/src/glx/x11/glxcmds.c +++ b/src/glx/x11/glxcmds.c @@ -109,6 +109,9 @@ static void GarbageCollectDRIDrawables(Display *dpy, __GLXscreenConfigs *sc) XSetErrorHandler(oldXErrorHandler); } +extern __GLXDRIdrawable * +GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num); + /** * Get the __DRIdrawable for the drawable associated with a GLXContext * @@ -118,24 +121,27 @@ static void GarbageCollectDRIDrawables(Display *dpy, __GLXscreenConfigs *sc) * \returns A pointer to the context's __DRIdrawable on success, or NULL if * the drawable is not associated with a direct-rendering context. */ -static __DRIdrawable * -GetDRIDrawable( Display *dpy, GLXDrawable drawable, int * const scrn_num ) +_X_HIDDEN __GLXDRIdrawable * +GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num) { - __GLXdisplayPrivate * const priv = __glXInitialize(dpy); - __GLXDRIdrawable * const pdraw; + __GLXdisplayPrivate *priv = __glXInitialize(dpy); + __GLXDRIdrawable *pdraw; const unsigned screen_count = ScreenCount(dpy); unsigned i; - __GLXscreenConfigs *sc; + __GLXscreenConfigs *psc; - if (priv == NULL || priv->driDisplay == NULL) + if (priv == NULL) return NULL; for (i = 0; i < screen_count; i++) { - sc = &priv->screenConfigs[i]; - if (__glxHashLookup(sc->drawHash, drawable, (void *) &pdraw) == 0) { + psc = &priv->screenConfigs[i]; + if (psc->drawHash == NULL) + continue; + + if (__glxHashLookup(psc->drawHash, drawable, (void *) &pdraw) == 0) { if (scrn_num != NULL) *scrn_num = i; - return &pdraw->driDrawable; + return pdraw; } } @@ -837,10 +843,10 @@ PUBLIC void glXSwapBuffers(Display *dpy, GLXDrawable drawable) GLXContextTag tag; CARD8 opcode; #ifdef GLX_DIRECT_RENDERING - __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, NULL ); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL); - if ( pdraw != NULL ) { - (*pdraw->swapBuffers)(pdraw); + if (pdraw != NULL) { + (*pdraw->psc->core->swapBuffers)(pdraw->driDrawable); return; } #endif @@ -1721,11 +1727,11 @@ static int __glXSwapIntervalSGI(int interval) if (gc->driContext) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - __DRIdrawable * const pdraw = GetDRIDrawable( gc->currentDpy, - gc->currentDrawable, - NULL ); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, + gc->currentDrawable, + NULL); if (psc->swapControl != NULL && pdraw != NULL) { - psc->swapControl->setSwapInterval(pdraw, interval); + psc->swapControl->setSwapInterval(pdraw->driDrawable, interval); return 0; } else { @@ -1775,10 +1781,10 @@ static int __glXSwapIntervalMESA(unsigned int interval) gc->screen ); if ( (psc != NULL) && (psc->driScreen != NULL) ) { - __DRIdrawable * const pdraw = - GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); + __GLXDRIdrawable *pdraw = + GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); if (psc->swapControl != NULL && pdraw != NULL) { - psc->swapControl->setSwapInterval(pdraw, interval); + psc->swapControl->setSwapInterval(pdraw->driDrawable, interval); return 0; } } @@ -1801,10 +1807,10 @@ static int __glXGetSwapIntervalMESA(void) gc->screen ); if ( (psc != NULL) && (psc->driScreen != NULL) ) { - __DRIdrawable * const pdraw = - GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); + __GLXDRIdrawable *pdraw = + GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); if (psc->swapControl != NULL && pdraw != NULL) { - return psc->swapControl->getSwapInterval(pdraw); + return psc->swapControl->getSwapInterval(pdraw->driDrawable); } } } @@ -1823,11 +1829,11 @@ static GLint __glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable) int status = GLX_BAD_CONTEXT; #ifdef __DRI_FRAME_TRACKING int screen; - __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); if (pdraw != NULL && psc->frameTracking != NULL) - status = psc->frameTracking->frameTracking(pdraw, GL_TRUE); + status = psc->frameTracking->frameTracking(pdraw->driDrawable, GL_TRUE); #else (void) dpy; (void) drawable; @@ -1841,11 +1847,12 @@ static GLint __glXEndFrameTrackingMESA(Display *dpy, GLXDrawable drawable) int status = GLX_BAD_CONTEXT; #ifdef __DRI_FRAME_TRACKING int screen; - __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); - __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, & screen); + __GLXscreenConfigs *psc = GetGLXScreenConfigs(dpy, screen); if (pdraw != NULL && psc->frameTracking != NULL) - status = psc->frameTracking->frameTracking(pdraw, GL_FALSE); + status = psc->frameTracking->frameTracking(pdraw->driDrawable, + GL_FALSE); #else (void) dpy; (void) drawable; @@ -1860,14 +1867,15 @@ static GLint __glXGetFrameUsageMESA(Display *dpy, GLXDrawable drawable, int status = GLX_BAD_CONTEXT; #ifdef __DRI_FRAME_TRACKING int screen; - __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); + __GLXDRIdrawable * const pdraw = GetGLXDRIDrawable(dpy, drawable, & screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); if (pdraw != NULL && psc->frameTracking != NULL) { int64_t sbc, missedFrames; float lastMissedUsage; - status = psc->frameTracking->queryFrameTracking(pdraw, &sbc, + status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable, + &sbc, &missedFrames, &lastMissedUsage, usage); @@ -1888,13 +1896,14 @@ static GLint __glXQueryFrameTrackingMESA(Display *dpy, GLXDrawable drawable, int status = GLX_BAD_CONTEXT; #ifdef __DRI_FRAME_TRACKING int screen; - __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, & screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); if (pdraw != NULL && psc->frameTracking != NULL) { float usage; - status = psc->frameTracking->queryFrameTracking(pdraw, sbc, missedFrames, + status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable, + sbc, missedFrames, lastMissedUsage, &usage); } #else @@ -1925,12 +1934,13 @@ static int __glXGetVideoSyncSGI(unsigned int *count) __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); if ( psc->msc && psc->driScreen ) { - __DRIdrawable * const pdraw = - GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); + __GLXDRIdrawable *pdraw = + GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); int64_t temp; int ret; - ret = (*psc->msc->getDrawableMSC)(&psc->__driScreen, pdraw, &temp); + ret = (*psc->msc->getDrawableMSC)(psc->__driScreen, + pdraw->driDrawable, &temp); *count = (unsigned) temp; return (ret == 0) ? 0 : GLX_BAD_CONTEXT; @@ -1954,14 +1964,14 @@ static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); if (psc->msc != NULL && psc->driScreen ) { - __DRIdrawable * const pdraw = - GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); + __GLXDRIdrawable *pdraw = + GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); int ret; int64_t msc; int64_t sbc; - ret = (*psc->msc->waitForMSC)(pdraw, 0, divisor, remainder, &msc, - &sbc); + ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, 0, + divisor, remainder, &msc, &sbc); *count = (unsigned) msc; return (ret == 0) ? 0 : GLX_BAD_CONTEXT; } @@ -2120,13 +2130,13 @@ static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable, if ( priv != NULL ) { int i; - __DRIdrawable * const pdraw = GetDRIDrawable( dpy, drawable, & i ); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &i); __GLXscreenConfigs * const psc = &priv->screenConfigs[i]; assert( (pdraw == NULL) || (i != -1) ); return ( (pdraw && psc->sbc && psc->msc) - && ((*psc->msc->getMSC)(&psc->driScreen, msc) == 0) - && ((*psc->sbc->getSBC)(pdraw, sbc) == 0) + && ((*psc->msc->getMSC)(psc->driScreen, msc) == 0) + && ((*psc->sbc->getSBC)(pdraw->driDrawable, sbc) == 0) && (__glXGetUST(ust) == 0) ); } #else @@ -2141,16 +2151,16 @@ static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable, #ifdef GLX_DIRECT_RENDERING _X_HIDDEN GLboolean -__driGetMscRateOML(__DRIdrawable *draw, int32_t *numerator, int32_t *denominator) +__driGetMscRateOML(__DRIdrawable *draw, + int32_t *numerator, int32_t *denominator, void *private) { #ifdef XF86VIDMODE __GLXscreenConfigs *psc; XF86VidModeModeLine mode_line; int dot_clock; int i; - __GLXDRIdrawable *glxDraw; + __GLXDRIdrawable *glxDraw = private; - glxDraw = containerOf(draw, __GLXDRIdrawable, driDrawable); psc = glxDraw->psc; if (XF86VidModeQueryVersion(psc->dpy, &i, &i) && XF86VidModeGetModeLine(psc->dpy, psc->scr, &dot_clock, &mode_line) ) { @@ -2223,12 +2233,12 @@ _X_HIDDEN GLboolean __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, int32_t * denominator) { #if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE ) - __DRIdrawable *driDraw = GetDRIDrawable(dpy, drawable, NULL); + __GLXDRIdrawable *draw = GetGLXDRIDrawable(dpy, drawable, NULL); - if (driDraw == NULL) + if (draw == NULL) return False; - return __driGetMscRateOML(driDraw, numerator, denominator); + return __driGetMscRateOML(draw->driDrawable, numerator, denominator, draw); #else (void) dpy; (void) drawable; @@ -2245,7 +2255,7 @@ static int64_t __glXSwapBuffersMscOML(Display *dpy, GLXDrawable drawable, { #ifdef __DRI_SWAP_BUFFER_COUNTER int screen; - __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE @@ -2259,7 +2269,7 @@ static int64_t __glXSwapBuffersMscOML(Display *dpy, GLXDrawable drawable, return -1; if (pdraw != NULL && psc->counters != NULL) - return (*psc->sbc->swapBuffersMSC)(pdraw, target_msc, + return (*psc->sbc->swapBuffersMSC)(pdraw->driDrawable, target_msc, divisor, remainder); #else @@ -2280,7 +2290,7 @@ static Bool __glXWaitForMscOML(Display * dpy, GLXDrawable drawable, { #ifdef __DRI_MEDIA_STREAM_COUNTER int screen; - __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); int ret; @@ -2293,7 +2303,7 @@ static Bool __glXWaitForMscOML(Display * dpy, GLXDrawable drawable, return False; if (pdraw != NULL && psc->msc != NULL) { - ret = (*psc->msc->waitForMSC)(pdraw, target_msc, + ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, target_msc, divisor, remainder, msc, sbc); /* __glXGetUST returns zero on success and non-zero on failure. @@ -2321,7 +2331,7 @@ static Bool __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, { #ifdef __DRI_SWAP_BUFFER_COUNTER int screen; - __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); int ret; @@ -2332,7 +2342,7 @@ static Bool __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, return False; if (pdraw != NULL && psc->sbc != NULL) { - ret = (*psc->sbc->waitForSBC)(pdraw, target_sbc, msc, sbc); + ret = (*psc->sbc->waitForSBC)(pdraw->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. @@ -2364,9 +2374,8 @@ PUBLIC void *glXAllocateMemoryMESA(Display *dpy, int scrn, __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn ); if (psc && psc->allocate) - return (*psc->allocate->allocateMemory)( &psc->__driScreen, size, - readFreq, writeFreq, - priority ); + return (*psc->allocate->allocateMemory)(psc->__driScreen, size, + readFreq, writeFreq, priority); #else (void) dpy; @@ -2387,7 +2396,7 @@ PUBLIC void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer) __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn ); if (psc && psc->allocate) - (*psc->allocate->freeMemory)( &psc->__driScreen, pointer ); + (*psc->allocate->freeMemory)(psc->__driScreen, pointer); #else (void) dpy; @@ -2404,7 +2413,7 @@ PUBLIC GLuint glXGetMemoryOffsetMESA( Display *dpy, int scrn, __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn ); if (psc && psc->allocate) - return (*psc->allocate->memoryOffset)( &psc->__driScreen, pointer ); + return (*psc->allocate->memoryOffset)(psc->__driScreen, pointer); #else (void) dpy; @@ -2480,11 +2489,12 @@ static void __glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, #ifdef __DRI_COPY_SUB_BUFFER int screen; - __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); if ( pdraw != NULL ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); if (psc->copySubBuffer != NULL) { - (*psc->copySubBuffer->copySubBuffer)(pdraw, x, y, width, height); + (*psc->copySubBuffer->copySubBuffer)(pdraw->driDrawable, + x, y, width, height); } return; @@ -2560,8 +2570,16 @@ static void __glXBindTexImageEXT(Display *dpy, } #ifdef GLX_DIRECT_RENDERING - if (gc->driContext) + if (gc->driContext) { + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL); + + if (pdraw != NULL) + (*pdraw->psc->texBuffer->setTexBuffer)(gc->__driContext, + pdraw->textureTarget, + pdraw->driDrawable); + return; + } #endif opcode = __glXSetupForCommand(dpy); diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c index 525faab10e9..cd5c3196e36 100644 --- a/src/glx/x11/glxext.c +++ b/src/glx/x11/glxext.c @@ -107,9 +107,6 @@ static int _mesa_sparc_needs_init = 1; #define INIT_MESA_SPARC #endif -static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw, - GLXDrawable read, GLXContext gc); - /* ** We setup some dummy structures here so that the API can be used ** even if no context is current. @@ -348,10 +345,10 @@ static void FreeScreenConfigs(__GLXdisplayPrivate *priv) Xfree((char*) psc->serverGLXexts); #ifdef GLX_DIRECT_RENDERING - if (psc->driScreen) + if (psc->driScreen) { psc->driScreen->destroyScreen(psc); - if (psc->drawHash) __glxHashDestroy(psc->drawHash); + } #endif } XFree((char*) priv->screenConfigs); @@ -381,6 +378,9 @@ static int __glXFreeDisplayPrivate(XExtData *extension) if (priv->driDisplay) (*priv->driDisplay->destroyDisplay)(priv->driDisplay); priv->driDisplay = NULL; + if (priv->dri2Display) + (*priv->dri2Display->destroyDisplay)(priv->dri2Display); + priv->dri2Display = NULL; #endif Xfree((char*) priv); @@ -774,14 +774,16 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) psc->scr = i; psc->dpy = dpy; #ifdef GLX_DIRECT_RENDERING - if (priv->driDisplay) { - /* Create drawable hash */ - psc->drawHash = __glxHashCreate(); - if (psc->drawHash == NULL) - continue; + psc->drawHash = __glxHashCreate(); + if (psc->drawHash == NULL) + continue; + if (priv->dri2Display) + psc->driScreen = (*priv->dri2Display->createScreen)(psc, i, priv); + if (psc->driScreen == NULL && priv->driDisplay) psc->driScreen = (*priv->driDisplay->createScreen)(psc, i, priv); - if (psc->driScreen == NULL) - __glxHashDestroy(psc->drawHash); + if (psc->driScreen == NULL) { + __glxHashDestroy(psc->drawHash); + psc->drawHash = NULL; } #endif } @@ -872,7 +874,8 @@ _X_HIDDEN __GLXdisplayPrivate *__glXInitialize(Display* dpy) ** (e.g., those called in AllocAndFetchScreenConfigs). */ if (getenv("LIBGL_ALWAYS_INDIRECT") == NULL) { - dpyPriv->driDisplay = driCreateDisplay(dpy); + dpyPriv->dri2Display = dri2CreateDisplay(dpy); + dpyPriv->driDisplay = driCreateDisplay(dpy); } #endif @@ -1188,21 +1191,35 @@ static Bool SendMakeCurrentRequest(Display *dpy, CARD8 opcode, #ifdef GLX_DIRECT_RENDERING static __GLXDRIdrawable * -FetchDRIDrawable(Display *dpy, GLXDrawable drawable, GLXContext gc) +FetchDRIDrawable(Display *dpy, + GLXDrawable glxDrawable, GLXContext gc, Bool pre13) { __GLXdisplayPrivate * const priv = __glXInitialize(dpy); __GLXDRIdrawable *pdraw; __GLXscreenConfigs *psc; + XID drawable; - if (priv == NULL || priv->driDisplay == NULL) + if (priv == NULL) return NULL; psc = &priv->screenConfigs[gc->screen]; - if (__glxHashLookup(psc->drawHash, drawable, (void *) &pdraw) == 0) + if (psc->drawHash == NULL) + return NULL; + + if (__glxHashLookup(psc->drawHash, glxDrawable, (void *) &pdraw) == 0) return pdraw; - pdraw = psc->driScreen->createDrawable(psc, drawable, gc); - if (__glxHashInsert(psc->drawHash, drawable, pdraw)) { + /* If this is glXMakeCurrent (pre GLX 1.3) we allow creating the + * GLX drawable on the fly. Otherwise we pass None as the X + * drawable */ + if (pre13) + drawable = glxDrawable; + else + drawable = None; + + pdraw = psc->driScreen->createDrawable(psc, drawable, + glxDrawable, gc->mode); + if (__glxHashInsert(psc->drawHash, glxDrawable, pdraw)) { (*pdraw->destroyDrawable)(pdraw); return NULL; } @@ -1218,7 +1235,8 @@ FetchDRIDrawable(Display *dpy, GLXDrawable drawable, GLXContext gc) * \note This is in this file so that it can access dummyContext. */ static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw, - GLXDrawable read, GLXContext gc) + GLXDrawable read, GLXContext gc, + Bool pre13) { xGLXMakeCurrentReply reply; const GLXContext oldGC = __glXGetCurrentContext(); @@ -1245,8 +1263,8 @@ static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw, #ifdef GLX_DIRECT_RENDERING /* Bind the direct rendering context to the drawable */ if (gc && gc->driContext) { - __GLXDRIdrawable *pdraw = FetchDRIDrawable(dpy, draw, gc); - __GLXDRIdrawable *pread = FetchDRIDrawable(dpy, read, gc); + __GLXDRIdrawable *pdraw = FetchDRIDrawable(dpy, draw, gc, pre13); + __GLXDRIdrawable *pread = FetchDRIDrawable(dpy, read, gc, pre13); bindReturnValue = (gc->driContext->bindContext) (gc->driContext, pdraw, pread); @@ -1368,16 +1386,16 @@ static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw, PUBLIC Bool glXMakeCurrent(Display *dpy, GLXDrawable draw, GLXContext gc) { - return MakeContextCurrent( dpy, draw, draw, gc ); + return MakeContextCurrent(dpy, draw, draw, gc, True); } PUBLIC GLX_ALIAS(Bool, glXMakeCurrentReadSGI, (Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx), - (dpy, d, r, ctx), MakeContextCurrent) + (dpy, d, r, ctx, False), MakeContextCurrent) PUBLIC GLX_ALIAS(Bool, glXMakeContextCurrent, (Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx), - (dpy, d, r, ctx), MakeContextCurrent) + (dpy, d, r, ctx, False), MakeContextCurrent) #ifdef DEBUG diff --git a/src/glx/x11/glxextensions.c b/src/glx/x11/glxextensions.c index 6d78c7067d1..e8437184722 100644 --- a/src/glx/x11/glxextensions.c +++ b/src/glx/x11/glxextensions.c @@ -356,72 +356,16 @@ __glXProcessServerString( const struct extension_info * ext, } } -#ifdef GLX_DIRECT_RENDERING - void -__glXScrEnableDRIExtension(__GLXscreenConfigs *psc) +__glXEnableDirectExtension(__GLXscreenConfigs *psc, const char *name) { - const __DRIextension **extensions; - int i; - __glXExtensionsCtr(); __glXExtensionsCtrScreen(psc); - extensions = psc->__driScreen.getExtensions(&psc->__driScreen); - for (i = 0; extensions[i]; i++) { -#ifdef __DRI_COPY_SUB_BUFFER - if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { - psc->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i]; - SET_BIT(psc->direct_support, MESA_copy_sub_buffer_bit); - } -#endif - -#ifdef __DRI_SWAP_CONTROL - if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) { - psc->swapControl = (__DRIswapControlExtension *) extensions[i]; - SET_BIT(psc->direct_support, SGI_swap_control_bit); - SET_BIT(psc->direct_support, MESA_swap_control_bit); - } -#endif - -#ifdef __DRI_ALLOCATE - if (strcmp(extensions[i]->name, __DRI_ALLOCATE) == 0) { - psc->allocate = (__DRIallocateExtension *) extensions[i]; - SET_BIT(psc->direct_support, MESA_allocate_memory_bit); - } -#endif - -#ifdef __DRI_FRAME_TRACKING - if (strcmp(extensions[i]->name, __DRI_FRAME_TRACKING) == 0) { - psc->frameTracking = (__DRIframeTrackingExtension *) extensions[i]; - SET_BIT(psc->direct_support, MESA_swap_frame_usage_bit); - } -#endif - -#ifdef __DRI_MEDIA_STREAM_COUNTER - if (strcmp(extensions[i]->name, __DRI_MEDIA_STREAM_COUNTER) == 0) { - psc->msc = (__DRImediaStreamCounterExtension *) extensions[i]; - SET_BIT(psc->direct_support, SGI_video_sync_bit); - } -#endif - -#ifdef __DRI_SWAP_BUFFER_COUNTER - /* No driver supports this at this time and the extension is - * not defined in dri_interface.h. Will enable - * GLX_OML_sync_control if implemented. */ -#endif - -#ifdef __DRI_READ_DRAWABLE - if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) { - SET_BIT(psc->direct_support, SGI_make_current_read_bit); - } -#endif - /* Ignore unknown extensions */ - } + set_glx_extension(known_glx_extensions, + name, strlen(name), GL_TRUE, psc->direct_support); } -#endif - /** * Initialize global extension support tables. */ diff --git a/src/glx/x11/glxextensions.h b/src/glx/x11/glxextensions.h index 144b02ad033..9cdd05ed761 100644 --- a/src/glx/x11/glxextensions.h +++ b/src/glx/x11/glxextensions.h @@ -235,10 +235,6 @@ extern const char * __glXGetClientExtensions( void ); extern void __glXCalculateUsableExtensions( struct __GLXscreenConfigsRec *psc, GLboolean display_is_direct_capable, int server_minor_version ); -#ifdef GLX_DIRECT_RENDERING -extern void __glXScrEnableDRIExtension( struct __GLXscreenConfigsRec *psc ); -#endif - extern void __glXCalculateUsableGLExtensions( struct __GLXcontextRec * gc, const char * server_string, int major_version, int minor_version ); extern void __glXGetGLVersion( int * major_version, int * minor_version ); @@ -247,6 +243,8 @@ extern char * __glXGetClientGLExtensionString( void ); extern GLboolean __glExtensionBitIsEnabled( const struct __GLXcontextRec * gc, unsigned bit ); +extern void +__glXEnableDirectExtension(__GLXscreenConfigs *psc, const char *name); /* Source-level backwards compatibility with old drivers. They won't * find the respective functions, though. |