summaryrefslogtreecommitdiffstats
path: root/src/glx
diff options
context:
space:
mode:
Diffstat (limited to 'src/glx')
-rw-r--r--src/glx/x11/Makefile5
-rw-r--r--src/glx/x11/dri2.c252
-rw-r--r--src/glx/x11/dri2.h53
-rw-r--r--src/glx/x11/dri2_glx.c471
-rw-r--r--src/glx/x11/dri_glx.c398
-rw-r--r--src/glx/x11/glx_pbuffer.c70
-rw-r--r--src/glx/x11/glxclient.h38
-rw-r--r--src/glx/x11/glxcmds.c140
-rw-r--r--src/glx/x11/glxext.c66
-rw-r--r--src/glx/x11/glxextensions.c62
-rw-r--r--src/glx/x11/glxextensions.h6
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.