summaryrefslogtreecommitdiff
path: root/src/glx/x11
diff options
context:
space:
mode:
Diffstat (limited to 'src/glx/x11')
-rw-r--r--src/glx/x11/.gitignore1
-rw-r--r--src/glx/x11/Makefile24
-rw-r--r--src/glx/x11/XF86dri.c39
-rw-r--r--src/glx/x11/dri2.c252
-rw-r--r--src/glx/x11/dri2.h53
-rw-r--r--src/glx/x11/dri2_glx.c371
-rw-r--r--src/glx/x11/dri_common.c399
-rw-r--r--src/glx/x11/dri_common.h60
-rw-r--r--src/glx/x11/dri_glx.c917
-rw-r--r--src/glx/x11/dri_glx.h61
-rw-r--r--src/glx/x11/drisw_glx.c441
-rw-r--r--src/glx/x11/glcontextmodes.c30
-rw-r--r--src/glx/x11/glcontextmodes.h6
-rw-r--r--src/glx/x11/glx_pbuffer.c100
-rw-r--r--src/glx/x11/glxclient.h181
-rw-r--r--src/glx/x11/glxcmds.c725
-rw-r--r--src/glx/x11/glxcurrent.c518
-rw-r--r--src/glx/x11/glxext.c1225
-rw-r--r--src/glx/x11/glxextensions.c25
-rw-r--r--src/glx/x11/glxextensions.h4
-rw-r--r--src/glx/x11/glxhash.c414
-rw-r--r--src/glx/x11/glxhash.h16
-rw-r--r--src/glx/x11/indirect.c393
-rw-r--r--src/glx/x11/indirect_texture_compression.c (renamed from src/glx/x11/glx_texture_compression.c)0
-rw-r--r--src/glx/x11/indirect_vertex_array.c63
-rw-r--r--src/glx/x11/indirect_vertex_array_priv.h (renamed from src/glx/x11/indirect_va_private.h)0
-rw-r--r--src/glx/x11/indirect_vertex_program.c1
-rw-r--r--src/glx/x11/pixelstore.c1
-rw-r--r--src/glx/x11/singlepix.c9
-rw-r--r--src/glx/x11/xf86dri.h14
-rw-r--r--src/glx/x11/xfont.c6
31 files changed, 4308 insertions, 2041 deletions
diff --git a/src/glx/x11/.gitignore b/src/glx/x11/.gitignore
deleted file mode 100644
index ffc14ab766..0000000000
--- a/src/glx/x11/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-glcontextmodes.c
diff --git a/src/glx/x11/Makefile b/src/glx/x11/Makefile
index c99bcf26a9..8d49a174e8 100644
--- a/src/glx/x11/Makefile
+++ b/src/glx/x11/Makefile
@@ -10,12 +10,14 @@ SOURCES = \
compsize.c \
eval.c \
glxcmds.c \
+ glxcurrent.c \
glxext.c \
glxextensions.c \
indirect.c \
indirect_init.c \
indirect_size.c \
indirect_window_pos.c \
+ indirect_texture_compression.c \
indirect_transpose_matrix.c \
indirect_vertex_array.c \
indirect_vertex_program.c \
@@ -29,9 +31,13 @@ SOURCES = \
xfont.c \
glx_pbuffer.c \
glx_query.c \
- glx_texture_compression.c \
+ drisw_glx.c \
+ dri_common.c \
dri_glx.c \
- XF86dri.c
+ XF86dri.c \
+ glxhash.c \
+ dri2_glx.c \
+ dri2.c
include $(TOP)/src/mesa/sources.mak
@@ -48,6 +54,7 @@ INCLUDES = -I. \
-I$(TOP)/src/mesa/main \
-I$(TOP)/src/mesa/glapi \
$(LIBDRM_CFLAGS) \
+ $(DRI2PROTO_CFLAGS) \
$(X11_INCLUDES)
@@ -65,9 +72,10 @@ default: depend $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
# Make libGL
$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(OBJECTS) Makefile
- $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' \
+ $(MKLIB) -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
-major 1 -minor 2 $(MKLIB_OPTIONS) \
- -install $(TOP)/$(LIB_DIR) $(GL_LIB_DEPS) $(OBJECTS)
+ -install $(TOP)/$(LIB_DIR) -id $(INSTALL_LIB_DIR)/lib$(GL_LIB).1.dylib \
+ $(GL_LIB_DEPS) $(OBJECTS)
depend: $(SOURCES) $(MESA_GLAPI_SOURCES) $(MESA_GLAPI_ASM_SOURCES) Makefile
@@ -81,13 +89,13 @@ depend: $(SOURCES) $(MESA_GLAPI_SOURCES) $(MESA_GLAPI_ASM_SOURCES) Makefile
tags:
etags `find . -name \*.[ch]` `find $(TOP)/include`
-# Dummy install target
-install:
+install: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
+ $(MAKE) -C $(TOP)/src/mesa install-libgl
# Remove .o and backup files
clean:
-rm -f $(TOP)/$(LIB_DIR)/libGL.so*
-rm -f *.o *~
- -rm -f depend
+ -rm -f depend depend.bak
-include depend
+-include depend
diff --git a/src/glx/x11/XF86dri.c b/src/glx/x11/XF86dri.c
index 9919a40977..ba38949c0b 100644
--- a/src/glx/x11/XF86dri.c
+++ b/src/glx/x11/XF86dri.c
@@ -374,10 +374,9 @@ PUBLIC Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext)
context, hHWContext );
}
-PUBLIC GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen,
- __DRIid context )
+PUBLIC GLboolean XF86DRIDestroyContext(Display *dpy, int screen,
+ XID context )
{
- Display * const dpy = (Display *) ndpy;
XExtDisplayInfo *info = find_display (dpy);
xXF86DRIDestroyContextReq *req;
@@ -396,10 +395,9 @@ PUBLIC GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen,
return True;
}
-PUBLIC GLboolean XF86DRICreateDrawable( __DRInativeDisplay * ndpy, int screen,
- __DRIid drawable, drm_drawable_t * hHWDrawable )
+PUBLIC GLboolean XF86DRICreateDrawable(Display *dpy, int screen,
+ XID drawable, drm_drawable_t * hHWDrawable )
{
- Display * const dpy = (Display *) ndpy;
XExtDisplayInfo *info = find_display (dpy);
xXF86DRICreateDrawableReply rep;
xXF86DRICreateDrawableReq *req;
@@ -426,16 +424,36 @@ PUBLIC GLboolean XF86DRICreateDrawable( __DRInativeDisplay * ndpy, int screen,
return True;
}
-PUBLIC GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen,
- __DRIid drawable )
+static int noopErrorHandler(Display *dpy, XErrorEvent *xerr)
+{
+ return 0;
+}
+
+PUBLIC GLboolean XF86DRIDestroyDrawable(Display *dpy, int screen,
+ XID drawable )
{
- Display * const dpy = (Display *) ndpy;
XExtDisplayInfo *info = find_display (dpy);
xXF86DRIDestroyDrawableReq *req;
+ int (*oldXErrorHandler)(Display *, XErrorEvent *);
TRACE("DestroyDrawable...");
XF86DRICheckExtension (dpy, info, False);
+ /* This is called from the DRI driver, which used call it like this
+ *
+ * if (windowExists(drawable))
+ * destroyDrawable(drawable);
+ *
+ * which is a textbook race condition - the window may disappear
+ * from the server between checking for its existance and
+ * destroying it. Instead we change the semantics of
+ * __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if
+ * the windows is gone, by wrapping the destroy call in an error
+ * handler. */
+
+ XSync(dpy, GL_FALSE);
+ oldXErrorHandler = XSetErrorHandler(noopErrorHandler);
+
LockDisplay(dpy);
GetReq(XF86DRIDestroyDrawable, req);
req->reqType = info->codes->major_opcode;
@@ -444,6 +462,9 @@ PUBLIC GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen,
req->drawable = drawable;
UnlockDisplay(dpy);
SyncHandle();
+
+ XSetErrorHandler(oldXErrorHandler);
+
TRACE("DestroyDrawable... return True");
return True;
}
diff --git a/src/glx/x11/dri2.c b/src/glx/x11/dri2.c
new file mode 100644
index 0000000000..e7044ab424
--- /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 (krh@redhat.com)
+ */
+
+
+#define NEED_REPLIES
+#include <X11/Xlibint.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#include <X11/extensions/dri2proto.h>
+#include "glheader.h"
+#include "xf86drm.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 0000000000..1dfd0448b2
--- /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 (krh@redhat.com)
+ */
+
+#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 0000000000..0be65bce62
--- /dev/null
+++ b/src/glx/x11/dri2_glx.c
@@ -0,0 +1,371 @@
+/*
+ * 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 (krh@redhat.com)
+ */
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include <X11/Xlib.h>
+#include <X11/extensions/Xfixes.h>
+#include <X11/extensions/Xdamage.h>
+#include "glheader.h"
+#include "glxclient.h"
+#include "glcontextmodes.h"
+#include "xf86dri.h"
+#include "sarea.h"
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include "xf86drm.h"
+#include "dri2.h"
+#include "dri_common.h"
+
+typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
+typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
+
+struct __GLXDRIdisplayPrivateRec {
+ __GLXDRIdisplay base;
+
+ /*
+ ** XFree86-DRI version information
+ */
+ int driMajor;
+ int driMinor;
+ int driPatch;
+};
+
+struct __GLXDRIcontextPrivateRec {
+ __GLXDRIcontext base;
+ __DRIcontext *driContext;
+ __GLXscreenConfigs *psc;
+};
+
+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
+};
+
+static const __DRIextension *loader_extensions[] = {
+ &dri2LoaderExtension.base,
+ &systemTimeExtension.base,
+ NULL
+};
+
+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, 1);
+
+ 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_common.c b/src/glx/x11/dri_common.c
new file mode 100644
index 0000000000..8175f46c54
--- /dev/null
+++ b/src/glx/x11/dri_common.c
@@ -0,0 +1,399 @@
+/*
+ * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+ * 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:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Brian Paul <brian@precisioninsight.com>
+ * Kristian Høgsberg (krh@redhat.com)
+ */
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include <unistd.h>
+#include <dlfcn.h>
+#include "glheader.h"
+#include "glxclient.h"
+#include "glcontextmodes.h"
+#include "dri_common.h"
+
+#ifndef RTLD_NOW
+#define RTLD_NOW 0
+#endif
+#ifndef RTLD_GLOBAL
+#define RTLD_GLOBAL 0
+#endif
+
+_X_HIDDEN void InfoMessageF(const char *f, ...)
+{
+ va_list args;
+ const char *env;
+
+ if ((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) {
+ fprintf(stderr, "libGL: ");
+ va_start(args, f);
+ vfprintf(stderr, f, args);
+ va_end(args);
+ }
+}
+
+/**
+ * Print error to stderr, unless LIBGL_DEBUG=="quiet".
+ */
+_X_HIDDEN void ErrorMessageF(const char *f, ...)
+{
+ va_list args;
+ const char *env;
+
+ if ((env = getenv("LIBGL_DEBUG")) && !strstr(env, "quiet")) {
+ fprintf(stderr, "libGL error: ");
+ va_start(args, f);
+ vfprintf(stderr, f, args);
+ va_end(args);
+ }
+}
+
+#ifndef DEFAULT_DRIVER_DIR
+/* this is normally defined in Mesa/configs/default with DRI_DRIVER_SEARCH_PATH */
+#define DEFAULT_DRIVER_DIR "/usr/local/lib/dri"
+#endif
+
+/**
+ * Try to \c dlopen the named driver.
+ *
+ * This function adds the "_dri.so" suffix to the driver name and searches the
+ * directories specified by the \c LIBGL_DRIVERS_PATH environment variable in
+ * order to find the driver.
+ *
+ * \param driverName - a name like "tdfx", "i810", "mga", etc.
+ *
+ * \returns
+ * A handle from \c dlopen, or \c NULL if driver file not found.
+ */
+_X_HIDDEN void *driOpenDriver(const char *driverName)
+{
+ void *glhandle, *handle;
+ const char *libPaths, *p, *next;
+ char realDriverName[200];
+ int len;
+
+ /* Attempt to make sure libGL symbols will be visible to the driver */
+ glhandle = dlopen("libGL.so.1", RTLD_NOW | RTLD_GLOBAL);
+
+ libPaths = NULL;
+ if (geteuid() == getuid()) {
+ /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
+ libPaths = getenv("LIBGL_DRIVERS_PATH");
+ if (!libPaths)
+ libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */
+ }
+ if (libPaths == NULL)
+ libPaths = DEFAULT_DRIVER_DIR;
+
+ handle = NULL;
+ for (p = libPaths; *p; p = next) {
+ next = strchr(p, ':');
+ if (next == NULL) {
+ len = strlen(p);
+ next = p + len;
+ } else {
+ len = next - p;
+ next++;
+ }
+
+#ifdef GLX_USE_TLS
+ snprintf(realDriverName, sizeof realDriverName,
+ "%.*s/tls/%s_dri.so", len, p, driverName);
+ InfoMessageF("OpenDriver: trying %s\n", realDriverName);
+ handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
+#endif
+
+ if ( handle == NULL ) {
+ snprintf(realDriverName, sizeof realDriverName,
+ "%.*s/%s_dri.so", len, p, driverName);
+ InfoMessageF("OpenDriver: trying %s\n", realDriverName);
+ handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
+ }
+
+ if ( handle != NULL )
+ break;
+ else
+ ErrorMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror());
+ }
+
+ if (!handle)
+ ErrorMessageF("unable to load driver: %s_dri.so\n", driverName);
+
+ if (glhandle)
+ dlclose(glhandle);
+
+ return handle;
+}
+
+_X_HIDDEN const __DRIsystemTimeExtension systemTimeExtension = {
+ { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION },
+ __glXGetUST,
+ __driGetMscRateOML
+};
+
+#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),
+#endif
+ __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),
+};
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+
+static int
+scalarEqual(__GLcontextModes *mode, unsigned int attrib, unsigned int value)
+{
+ unsigned int glxValue;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(attribMap); i++)
+ if (attribMap[i].attrib == attrib) {
+ glxValue = *(unsigned int *) ((char *) mode + attribMap[i].offset);
+ return glxValue == GLX_DONT_CARE || glxValue == 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;
+
+ 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 (modes->bindToTextureTargets != GLX_DONT_CARE &&
+ glxValue != modes->bindToTextureTargets)
+ return GL_FALSE;
+ break;
+
+ 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;
+}
+
+_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;
+}
+
+_X_HIDDEN void
+driBindExtensions(__GLXscreenConfigs *psc, int dri2)
+{
+ 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) && dri2) {
+ psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
+ __glXEnableDirectExtension(psc, "GLX_EXT_texture_from_pixmap");
+ }
+#endif
+
+ /* Ignore unknown extensions */
+ }
+}
+
+#endif /* GLX_DIRECT_RENDERING */
diff --git a/src/glx/x11/dri_common.h b/src/glx/x11/dri_common.h
new file mode 100644
index 0000000000..15f6cc87b9
--- /dev/null
+++ b/src/glx/x11/dri_common.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+ * 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:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Brian Paul <brian@precisioninsight.com>
+ * Kristian Høgsberg (krh@redhat.com)
+ */
+
+#ifndef _DRI_COMMON_H
+#define _DRI_COMMON_H
+
+typedef struct __GLXDRIconfigPrivateRec __GLXDRIconfigPrivate;
+
+struct __GLXDRIconfigPrivateRec {
+ __GLcontextModes modes;
+ const __DRIconfig *driConfig;
+};
+
+extern __GLcontextModes *
+driConvertConfigs(const __DRIcoreExtension *core,
+ __GLcontextModes *modes, const __DRIconfig **configs);
+
+extern const __DRIsystemTimeExtension systemTimeExtension;
+
+extern void InfoMessageF(const char *f, ...);
+
+extern void ErrorMessageF(const char *f, ...);
+
+extern void *driOpenDriver(const char *driverName);
+
+extern void driBindExtensions(__GLXscreenConfigs *psc, int dri2);
+
+#endif /* _DRI_COMMON_H */
diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c
index e637c96ac9..08c83a2310 100644
--- a/src/glx/x11/dri_glx.c
+++ b/src/glx/x11/dri_glx.c
@@ -34,294 +34,47 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef GLX_DIRECT_RENDERING
-#include <unistd.h>
-#include <X11/Xlibint.h>
-#include <X11/extensions/Xext.h>
-#include <X11/extensions/extutil.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/Xfixes.h>
+#include <X11/extensions/Xdamage.h>
#include "glheader.h"
#include "glxclient.h"
+#include "glcontextmodes.h"
#include "xf86dri.h"
#include "sarea.h"
-#include <stdio.h>
#include <dlfcn.h>
-#include "dri_glx.h"
#include <sys/types.h>
-#include <stdarg.h>
-
-#ifndef RTLD_NOW
-#define RTLD_NOW 0
-#endif
-#ifndef RTLD_GLOBAL
-#define RTLD_GLOBAL 0
-#endif
-
-
-#ifndef DEFAULT_DRIVER_DIR
-/* this is normally defined in Mesa/configs/default with DRI_DRIVER_SEARCH_PATH */
-#define DEFAULT_DRIVER_DIR "/usr/X11R6/lib/modules/dri"
-#endif
-
-static __DRIdriver *Drivers = NULL;
-
-
-/** If non-zero, prefer an "egl_foo_dri.so" driver over "foo_dri.so" */
-static int PreferEGL = 0;
-
-
-/**
- * This may be called by libEGL.so to tell libGL to prefer "egl_" drivers
- * over regular DRI drivers".
- */
-void __glXPreferEGL(int state)
-{
- PreferEGL = state;
-}
-
-
-/*
- * printf wrappers
- */
-
-static void InfoMessageF(const char *f, ...)
-{
- va_list args;
- const char *env;
-
- if ((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) {
- fprintf(stderr, "libGL: ");
- va_start(args, f);
- vfprintf(stderr, f, args);
- va_end(args);
- }
-}
-
-/**
- * Print error to stderr, unless LIBGL_DEBUG=="quiet".
- */
-static void ErrorMessageF(const char *f, ...)
-{
- va_list args;
- const char *env;
-
- if ((env = getenv("LIBGL_DEBUG")) && !strstr(env, "quiet")) {
- fprintf(stderr, "libGL error: ");
- va_start(args, f);
- vfprintf(stderr, f, args);
- va_end(args);
- }
-}
-
-
-/**
- * Extract the ith directory path out of a colon-separated list of paths. No
- * more than \c dirLen characters, including the terminating \c NUL, will be
- * written to \c dir.
- *
- * \param index Index of path to extract (starting at zero)
- * \param paths The colon-separated list of paths
- * \param dirLen Maximum length of result to store in \c dir
- * \param dir Buffer to hold the extracted directory path
- *
- * \returns
- * The number of characters that would have been written to \c dir had there
- * been enough room. This does not include the terminating \c NUL. When
- * extraction fails, zero will be returned.
- *
- * \todo
- * It seems like this function could be rewritten to use \c strchr.
- */
-static size_t
-ExtractDir(int index, const char *paths, int dirLen, char *dir)
-{
- int i, len;
- const char *start, *end;
-
- /* find ith colon */
- start = paths;
- i = 0;
- while (i < index) {
- if (*start == ':') {
- i++;
- start++;
- }
- else if (*start == 0) {
- /* end of string and couldn't find ith colon */
- dir[0] = 0;
- return 0;
- }
- else {
- start++;
- }
- }
-
- while (*start == ':')
- start++;
-
- /* find next colon, or end of string */
- end = start + 1;
- while (*end != ':' && *end != 0) {
- end++;
- }
-
- /* copy string between <start> and <end> into result string */
- len = end - start;
- if (len > dirLen - 1)
- len = dirLen - 1;
- strncpy(dir, start, len);
- dir[len] = 0;
-
- return( end - start );
-}
-
-
-/**
- * Try to dlopen() a driver.
- * \param libDir the directory to search
- * \param driverName the name of the driver (such as "r300").
- * \param tls if true, try to find TLS version of driver
- * \param preferEGL if true, try to find EGL-specific driver
- * \return handle from dlopen(), will be NULL if fails.
- */
-static void *
-try_open(const char *libDir, const char *driverName,
- GLboolean tls, GLboolean preferEGL)
-{
- const char *tlsDir = tls ? "/tls/" : "";
- const char *eglPrefix = preferEGL ? "egl_" : "";
- char fullPathName[200];
- void *handle = NULL;
-
- snprintf(fullPathName, 200, "%s%s/%s%s_dri.so",
- libDir, tlsDir, eglPrefix, driverName);
- InfoMessageF("OpenDriver: trying %s\n", fullPathName);
- handle = dlopen(fullPathName, RTLD_NOW | RTLD_GLOBAL);
-
- return handle;
-}
-
-
-
-/**
- * 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.
- *
- * \todo
- * Create a macro or something so that this is automatically updated.
- */
-static const char createNewScreenName[] = "__driCreateNewScreen_20050727";
-
-
-/**
- * Try to \c dlopen the named driver.
- *
- * This function adds the "_dri.so" suffix to the driver name and searches the
- * directories specified by the \c LIBGL_DRIVERS_PATH environment variable in
- * order to find the driver.
- *
- * \param driverName - a name like "tdfx", "i810", "mga", etc.
- *
- * \returns
- * A handle from \c dlopen, or \c NULL if driver file not found.
- */
-static __DRIdriver *OpenDriver(const char *driverName)
-{
- void *glhandle = NULL;
- char *libPaths = NULL;
- char libDir[1000];
- int i;
- __DRIdriver *driver;
-
- /* First, search Drivers list to see if we've already opened this driver */
- for (driver = Drivers; driver; driver = driver->next) {
- if (strcmp(driver->name, driverName) == 0) {
- /* found it */
- return driver;
- }
- }
-
- /* Attempt to make sure libGL symbols will be visible to the driver */
- glhandle = dlopen("libGL.so.1", RTLD_NOW | RTLD_GLOBAL);
-
- if (geteuid() == getuid()) {
- /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
- libPaths = getenv("LIBGL_DRIVERS_PATH");
- if (!libPaths)
- libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */
- }
- if (!libPaths)
- libPaths = DEFAULT_DRIVER_DIR;
-
- for ( i = 0 ; ExtractDir(i, libPaths, 1000, libDir) != 0 ; i++ ) {
- void *handle = NULL;
-
- if (PreferEGL)
- handle = try_open(libDir, driverName, GL_FALSE, GL_TRUE);
-#ifdef GLX_USE_TLS
- if (!handle)
- handle = try_open(libDir, driverName, GL_TRUE, GL_FALSE);
-#endif
- if (!handle)
- handle = try_open(libDir, driverName, GL_FALSE, GL_FALSE);
-
- if ( handle != NULL ) {
- /* allocate __DRIdriver struct */
- driver = (__DRIdriver *) Xmalloc(sizeof(__DRIdriver));
- if (!driver)
- break; /* out of memory! */
- /* init the struct */
- driver->name = __glXstrdup(driverName);
- if (!driver->name) {
- Xfree(driver);
- driver = NULL;
- break; /* out of memory! */
- }
-
- driver->createNewScreenFunc = (PFNCREATENEWSCREENFUNC)
- dlsym(handle, createNewScreenName);
-
- if ( driver->createNewScreenFunc == NULL ) {
- /* If the driver doesn't have this symbol then something's
- * really, really wrong.
- */
- ErrorMessageF("%s not defined in %s_dri.so!\n"
- "Your driver may be too old for this libGL.\n",
- createNewScreenName, driverName);
- Xfree(driver);
- driver = NULL;
- dlclose(handle);
- continue;
- }
- driver->handle = handle;
- /* put at head of linked list */
- driver->next = Drivers;
- Drivers = driver;
- break;
- }
- else {
- ErrorMessageF("Unable to find/open driver for %s (%s)\n",
- driverName, dlerror());
- }
- }
-
- if (!driver)
- ErrorMessageF("unable to load driver: %s_dri.so\n", driverName);
-
- if (glhandle)
- dlclose(glhandle);
-
- return driver;
-}
-
+#include <sys/mman.h>
+#include "xf86drm.h"
+#include "dri_common.h"
+
+typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
+typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
+
+struct __GLXDRIdisplayPrivateRec {
+ __GLXDRIdisplay base;
+
+ /*
+ ** XFree86-DRI version information
+ */
+ int driMajor;
+ int driMinor;
+ int driPatch;
+};
+
+struct __GLXDRIcontextPrivateRec {
+ __GLXDRIcontext base;
+ __DRIcontext *driContext;
+ XID hwContextID;
+ __GLXscreenConfigs *psc;
+};
/*
* Given a display pointer and screen number, determine the name of
* the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
* Return True for success, False for failure.
*/
-static Bool GetDriverName(Display *dpy, int scrNum, char **driverName)
+static Bool driGetDriverName(Display *dpy, int scrNum, char **driverName)
{
int directCapable;
Bool b;
@@ -351,25 +104,6 @@ static Bool GetDriverName(Display *dpy, int scrNum, char **driverName)
return True;
}
-
-/*
- * Given a display pointer and screen number, return a __DRIdriver handle.
- * Return NULL if anything goes wrong.
- */
-__DRIdriver *driGetDriver(Display *dpy, int scrNum)
-{
- char *driverName;
- if (GetDriverName(dpy, scrNum, &driverName)) {
- __DRIdriver *ret;
- ret = OpenDriver(driverName);
- if (driverName)
- Xfree(driverName);
- return ret;
- }
- return NULL;
-}
-
-
/*
* Exported function for querying the DRI driver for a given screen.
*
@@ -379,7 +113,7 @@ __DRIdriver *driGetDriver(Display *dpy, int scrNum)
PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) {
static char ret[32];
char *driverName;
- if (GetDriverName(dpy, scrNum, &driverName)) {
+ if (driGetDriverName(dpy, scrNum, &driverName)) {
int len;
if (!driverName)
return NULL;
@@ -393,7 +127,6 @@ PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) {
return NULL;
}
-
/*
* Exported function for obtaining a driver's option list (UTF-8 encoded XML).
*
@@ -405,71 +138,530 @@ PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) {
*
* Note: The driver remains opened after this function returns.
*/
-PUBLIC const char *glXGetDriverConfig (const char *driverName) {
- __DRIdriver *driver = OpenDriver (driverName);
- if (driver)
- return dlsym (driver->handle, "__driConfigOptions");
+PUBLIC const char *glXGetDriverConfig (const char *driverName)
+{
+ void *handle = driOpenDriver (driverName);
+ if (handle)
+ return dlsym (handle, "__driConfigOptions");
else
return NULL;
}
+#ifdef XDAMAGE_1_1_INTERFACE
-/* Called from __glXFreeDisplayPrivate.
+static GLboolean has_damage_post(Display *dpy)
+{
+ static GLboolean inited = GL_FALSE;
+ static GLboolean has_damage;
+
+ if (!inited) {
+ int major, minor;
+
+ if (XDamageQueryVersion(dpy, &major, &minor) &&
+ major == 1 && minor >= 1)
+ {
+ has_damage = GL_TRUE;
+ } else {
+ has_damage = GL_FALSE;
+ }
+ inited = GL_TRUE;
+ }
+
+ return has_damage;
+}
+
+static void __glXReportDamage(__DRIdrawable *driDraw,
+ int x, int y,
+ drm_clip_rect_t *rects, int num_rects,
+ GLboolean front_buffer,
+ void *loaderPrivate)
+{
+ XRectangle *xrects;
+ XserverRegion region;
+ int i;
+ int x_off, y_off;
+ __GLXDRIdrawable *glxDraw = loaderPrivate;
+ __GLXscreenConfigs *psc = glxDraw->psc;
+ Display *dpy = psc->dpy;
+ Drawable drawable;
+
+ if (!has_damage_post(dpy))
+ return;
+
+ if (front_buffer) {
+ x_off = x;
+ y_off = y;
+ drawable = RootWindow(dpy, psc->scr);
+ } else{
+ x_off = 0;
+ y_off = 0;
+ drawable = glxDraw->xDrawable;
+ }
+
+ xrects = malloc(sizeof(XRectangle) * num_rects);
+ if (xrects == NULL)
+ return;
+
+ for (i = 0; i < num_rects; i++) {
+ xrects[i].x = rects[i].x1 + x_off;
+ xrects[i].y = rects[i].y1 + y_off;
+ xrects[i].width = rects[i].x2 - rects[i].x1;
+ xrects[i].height = rects[i].y2 - rects[i].y1;
+ }
+ region = XFixesCreateRegion(dpy, xrects, num_rects);
+ free(xrects);
+ XDamageAdd(dpy, drawable, region);
+ XFixesDestroyRegion(dpy, region);
+}
+
+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,
+ void *loaderPrivate)
+{
+ __GLXDRIdrawable *glxDraw = loaderPrivate;
+ __GLXscreenConfigs *psc = glxDraw->psc;
+ Display *dpy = psc->dpy;
+
+ return XF86DRIGetDrawableInfo(dpy, psc->scr, glxDraw->drawable,
+ index, stamp, X, Y, W, H,
+ numClipRects, pClipRects,
+ backX, backY,
+ numBackClipRects, pBackClipRects);
+}
+
+static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = {
+ { __DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION },
+ __glXDRIGetDrawableInfo
+};
+
+static const __DRIextension *loader_extensions[] = {
+ &systemTimeExtension.base,
+ &getDrawableInfoExtension.base,
+#ifdef XDAMAGE_1_1_INTERFACE
+ &damageExtension.base,
+#endif
+ NULL
+};
+
+#ifndef GLX_USE_APPLEGL
+
+/**
+ * Perform the required libGL-side initialization and call the client-side
+ * driver's \c __driCreateNewScreen function.
+ *
+ * \param dpy Display pointer.
+ * \param scrn Screen number on the display.
+ * \param psc DRI screen information.
+ * \param driDpy DRI display information.
+ * \param createNewScreen Pointer to the client-side driver's
+ * \c __driCreateNewScreen function.
+ * \returns A pointer to the \c __DRIscreenPrivate structure returned by
+ * the client-side driver on success, or \c NULL on failure.
*/
-static void driDestroyDisplay(Display *dpy, void *private)
+static void *
+CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
+ __GLXDRIdisplayPrivate * driDpy)
{
- __DRIdisplayPrivate *pdpyp = (__DRIdisplayPrivate *)private;
-
- if (pdpyp) {
- const int numScreens = ScreenCount(dpy);
- int i;
- for (i = 0; i < numScreens; i++) {
- if (pdpyp->libraryHandles[i]) {
- __DRIdriver *driver, *prev;
-
- /* Remove driver from Drivers list */
- for (prev = NULL, driver = Drivers; driver;
- prev = driver, driver = driver->next) {
- if (driver->handle == pdpyp->libraryHandles[i]) {
- if (prev)
- prev->next = driver->next;
- else
- Drivers = driver->next;
-
- Xfree((void *) driver->name);
- Xfree(driver);
- break;
- }
- }
-
- dlclose(pdpyp->libraryHandles[i]);
- }
- }
- Xfree(pdpyp->libraryHandles);
- Xfree(pdpyp);
+ void *psp = NULL;
+ drm_handle_t hSAREA;
+ drmAddress pSAREA = MAP_FAILED;
+ char *BusID;
+ __DRIversion ddx_version;
+ __DRIversion dri_version;
+ __DRIversion drm_version;
+ __DRIframebuffer framebuffer;
+ int fd = -1;
+ int status;
+
+ drm_magic_t magic;
+ drmVersionPtr version;
+ int newlyopened;
+ char *driverName;
+ drm_handle_t hFB;
+ int junk;
+ const __DRIconfig **driver_configs;
+
+ /* DRI protocol version. */
+ dri_version.major = driDpy->driMajor;
+ dri_version.minor = driDpy->driMinor;
+ dri_version.patch = driDpy->driPatch;
+
+ framebuffer.base = MAP_FAILED;
+ framebuffer.dev_priv = NULL;
+
+ if (!XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
+ ErrorMessageF("XF86DRIOpenConnection failed\n");
+ goto handle_error;
+ }
+
+ fd = drmOpenOnce(NULL, BusID, &newlyopened);
+
+ Xfree(BusID); /* No longer needed */
+
+ if (fd < 0) {
+ ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd));
+ goto handle_error;
}
+
+ if (drmGetMagic(fd, &magic)) {
+ ErrorMessageF("drmGetMagic failed\n");
+ goto handle_error;
+ }
+
+ version = drmGetVersion(fd);
+ if (version) {
+ drm_version.major = version->version_major;
+ drm_version.minor = version->version_minor;
+ drm_version.patch = version->version_patchlevel;
+ drmFreeVersion(version);
+ }
+ else {
+ drm_version.major = -1;
+ drm_version.minor = -1;
+ drm_version.patch = -1;
+ }
+
+ if (newlyopened && !XF86DRIAuthConnection(dpy, scrn, magic)) {
+ ErrorMessageF("XF86DRIAuthConnection failed\n");
+ goto handle_error;
+ }
+
+ /* Get device name (like "tdfx") and the ddx version numbers.
+ * We'll check the version in each DRI driver's "createNewScreen"
+ * function. */
+ if (!XF86DRIGetClientDriverName(dpy, scrn,
+ &ddx_version.major,
+ &ddx_version.minor,
+ &ddx_version.patch,
+ &driverName)) {
+ ErrorMessageF("XF86DRIGetClientDriverName failed\n");
+ goto handle_error;
+ }
+
+ Xfree(driverName); /* No longer needed. */
+
+ /*
+ * Get device-specific info. pDevPriv will point to a struct
+ * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
+ * has information about the screen size, depth, pitch, ancilliary
+ * buffers, DRM mmap handles, etc.
+ */
+ if (!XF86DRIGetDeviceInfo(dpy, scrn, &hFB, &junk,
+ &framebuffer.size, &framebuffer.stride,
+ &framebuffer.dev_priv_size, &framebuffer.dev_priv)) {
+ ErrorMessageF("XF86DRIGetDeviceInfo failed");
+ goto handle_error;
+ }
+
+ framebuffer.width = DisplayWidth(dpy, scrn);
+ framebuffer.height = DisplayHeight(dpy, scrn);
+
+ /* Map the framebuffer region. */
+ status = drmMap(fd, hFB, framebuffer.size,
+ (drmAddressPtr)&framebuffer.base);
+ if (status != 0) {
+ ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status));
+ goto handle_error;
+ }
+
+ /* Map the SAREA region. Further mmap regions may be setup in
+ * each DRI driver's "createNewScreen" function.
+ */
+ status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA);
+ if (status != 0) {
+ ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status));
+ goto handle_error;
+ }
+
+ psp = (*psc->legacy->createNewScreen)(scrn,
+ &ddx_version,
+ &dri_version,
+ &drm_version,
+ &framebuffer,
+ pSAREA,
+ fd,
+ loader_extensions,
+ &driver_configs,
+ psc);
+
+ if (psp == NULL) {
+ ErrorMessageF("Calling driver entry point failed");
+ goto handle_error;
+ }
+
+ psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
+ psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
+
+ return psp;
+
+ handle_error:
+ if (pSAREA != MAP_FAILED)
+ drmUnmap(pSAREA, SAREA_MAX);
+
+ if (framebuffer.base != MAP_FAILED)
+ drmUnmap((drmAddress)framebuffer.base, framebuffer.size);
+
+ if (framebuffer.dev_priv != NULL)
+ Xfree(framebuffer.dev_priv);
+
+ if (fd >= 0)
+ drmCloseOnce(fd);
+
+ XF86DRICloseConnection(dpy, scrn);
+
+ ErrorMessageF("reverting to software direct rendering\n");
+
+ return NULL;
+}
+
+#else /* !GLX_USE_APPLEGL */
+
+static void *
+CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
+ __GLXDRIdisplayPrivate * driDpy)
+{
+ return NULL;
+}
+
+#endif /* !GLX_USE_APPLEGL */
+
+static void driDestroyContext(__GLXDRIcontext *context,
+ __GLXscreenConfigs *psc, Display *dpy)
+{
+ __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
+
+ (*psc->core->destroyContext)(pcp->driContext);
+
+ XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID);
+ Xfree(pcp);
+}
+
+static Bool driBindContext(__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 driUnbindContext(__GLXDRIcontext *context)
+{
+ __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
+ const __DRIcoreExtension *core = pcp->psc->core;
+
+ (*core->unbindContext)(pcp->driContext);
+}
+
+static __GLXDRIcontext *driCreateContext(__GLXscreenConfigs *psc,
+ const __GLcontextModes *mode,
+ GLXContext gc,
+ GLXContext shareList, int renderType)
+{
+ __GLXDRIcontextPrivate *pcp, *pcp_shared;
+ drm_context_t hwContext;
+ __DRIcontext *shared = NULL;
+ __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
+
+ if (!psc || !psc->driScreen)
+ return NULL;
+
+ if (shareList) {
+ pcp_shared = (__GLXDRIcontextPrivate *) shareList->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)) {
+ Xfree(pcp);
+ return 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;
+ }
+
+ pcp->base.destroyContext = driDestroyContext;
+ pcp->base.bindContext = driBindContext;
+ pcp->base.unbindContext = driUnbindContext;
+
+ return &pcp->base;
+}
+
+static void driDestroyDrawable(__GLXDRIdrawable *pdraw)
+{
+ __GLXscreenConfigs *psc = pdraw->psc;
+
+ (*psc->core->destroyDrawable)(pdraw->driDrawable);
+ XF86DRIDestroyDrawable(psc->dpy, psc->scr, pdraw->drawable);
+ Xfree(pdraw);
+}
+
+static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc,
+ XID xDrawable,
+ GLXDrawable drawable,
+ 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)
+ return NULL;
+
+ pdraw->drawable = drawable;
+ pdraw->psc = psc;
+
+ if (!XF86DRICreateDrawable(psc->dpy, psc->scr, drawable, &hwDrawable))
+ return NULL;
+
+ /* Create a new drawable */
+ 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;
+ }
+
+ pdraw->destroyDrawable = driDestroyDrawable;
+
+ return pdraw;
+}
+
+static void driDestroyScreen(__GLXscreenConfigs *psc)
+{
+ /* Free the direct rendering per screen data */
+ if (psc->__driScreen)
+ (*psc->core->destroyScreen)(psc->__driScreen);
+ psc->__driScreen = NULL;
+ if (psc->driver)
+ dlclose(psc->driver);
+}
+
+static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen,
+ __GLXdisplayPrivate *priv)
+{
+ __GLXDRIdisplayPrivate *pdp;
+ __GLXDRIscreen *psp;
+ const __DRIextension **extensions;
+ char *driverName;
+ 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 (!driGetDriverName(priv->dpy, screen, &driverName)) {
+ Xfree(psp);
+ return NULL;
+ }
+
+ psc->driver = driOpenDriver(driverName);
+ Xfree(driverName);
+ 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 =
+ CallCreateNewScreen(psc->dpy, screen, psc, pdp);
+ if (psc->__driScreen == NULL) {
+ dlclose(psc->driver);
+ Xfree(psp);
+ return NULL;
+ }
+
+ driBindExtensions(psc, 0);
+
+ psp->destroyScreen = driDestroyScreen;
+ psp->createContext = driCreateContext;
+ psp->createDrawable = driCreateDrawable;
+
+ return psp;
+}
+
+/* Called from __glXFreeDisplayPrivate.
+ */
+static void driDestroyDisplay(__GLXDRIdisplay *dpy)
+{
+ Xfree(dpy);
+}
/*
* Allocate, initialize and return a __DRIdisplayPrivate object.
* This is called from __glXInitialize() when we are given a new
* display pointer.
*/
-void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp)
+_X_HIDDEN __GLXDRIdisplay *driCreateDisplay(Display *dpy)
{
- const int numScreens = ScreenCount(dpy);
- __DRIdisplayPrivate *pdpyp;
+ __GLXDRIdisplayPrivate *pdpyp;
int eventBase, errorBase;
int major, minor, patch;
- int scrn;
-
- /* Initialize these fields to NULL in case we fail.
- * If we don't do this we may later get segfaults trying to free random
- * addresses when the display is closed.
- */
- pdisp->private = NULL;
- pdisp->destroyDisplay = NULL;
if (!XF86DRIQueryExtension(dpy, &eventBase, &errorBase)) {
return NULL;
@@ -479,7 +671,7 @@ void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp)
return NULL;
}
- pdpyp = (__DRIdisplayPrivate *)Xmalloc(sizeof(__DRIdisplayPrivate));
+ pdpyp = Xmalloc(sizeof *pdpyp);
if (!pdpyp) {
return NULL;
}
@@ -488,41 +680,10 @@ void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp)
pdpyp->driMinor = minor;
pdpyp->driPatch = patch;
- pdisp->destroyDisplay = driDestroyDisplay;
-
- /* allocate array of pointers to createNewScreen funcs */
- pdisp->createNewScreen = (PFNCREATENEWSCREENFUNC *)
- Xmalloc(numScreens * sizeof(void *));
- if (!pdisp->createNewScreen) {
- Xfree(pdpyp);
- return NULL;
- }
-
- /* allocate array of library handles */
- pdpyp->libraryHandles = (void **) Xmalloc(numScreens * sizeof(void*));
- if (!pdpyp->libraryHandles) {
- Xfree(pdisp->createNewScreen);
- Xfree(pdpyp);
- return NULL;
- }
-
- /* dynamically discover DRI drivers for all screens, saving each
- * driver's "__driCreateScreen" function pointer. That's the bootstrap
- * entrypoint for all DRI drivers.
- */
- for (scrn = 0; scrn < numScreens; scrn++) {
- __DRIdriver *driver = driGetDriver(dpy, scrn);
- if (driver) {
- pdisp->createNewScreen[scrn] = driver->createNewScreenFunc;
- pdpyp->libraryHandles[scrn] = driver->handle;
- }
- else {
- pdisp->createNewScreen[scrn] = NULL;
- pdpyp->libraryHandles[scrn] = NULL;
- }
- }
+ pdpyp->base.destroyDisplay = driDestroyDisplay;
+ pdpyp->base.createScreen = driCreateScreen;
- return (void *)pdpyp;
+ return &pdpyp->base;
}
#endif /* GLX_DIRECT_RENDERING */
diff --git a/src/glx/x11/dri_glx.h b/src/glx/x11/dri_glx.h
deleted file mode 100644
index 75561685c8..0000000000
--- a/src/glx/x11/dri_glx.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Kevin E. Martin <kevin@precisioninsight.com>
- * Brian Paul <brian@precisioninsight.com>
- *
- */
-
-#ifndef _DRI_GLX_H_
-#define _DRI_GLX_H_
-
-#ifdef GLX_DIRECT_RENDERING
-
-struct __DRIdisplayPrivateRec {
- /*
- ** XFree86-DRI version information
- */
- int driMajor;
- int driMinor;
- int driPatch;
-
- /*
- ** Array of library handles [indexed by screen number]
- */
- void **libraryHandles;
-};
-
-typedef struct __DRIdisplayPrivateRec __DRIdisplayPrivate;
-typedef struct __DRIscreenPrivateRec __DRIscreenPrivate;
-typedef struct __DRIvisualPrivateRec __DRIvisualPrivate;
-typedef struct __DRIcontextPrivateRec __DRIcontextPrivate;
-typedef struct __DRIdrawablePrivateRec __DRIdrawablePrivate;
-
-#endif
-#endif /* _DRI_GLX_H_ */
diff --git a/src/glx/x11/drisw_glx.c b/src/glx/x11/drisw_glx.c
new file mode 100644
index 0000000000..bcf7e144ef
--- /dev/null
+++ b/src/glx/x11/drisw_glx.c
@@ -0,0 +1,441 @@
+/*
+ * Copyright 2008 George Sapountzis
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifdef GLX_DIRECT_RENDERING
+
+#include <X11/Xlib.h>
+#include "glheader.h"
+#include "glxclient.h"
+#include "glcontextmodes.h"
+#include <dlfcn.h>
+#include "dri_common.h"
+
+typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
+typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
+typedef struct __GLXDRIdrawablePrivateRec __GLXDRIdrawablePrivate;
+
+struct __GLXDRIdisplayPrivateRec {
+ __GLXDRIdisplay base;
+};
+
+struct __GLXDRIcontextPrivateRec {
+ __GLXDRIcontext base;
+ __DRIcontext *driContext;
+ __GLXscreenConfigs *psc;
+};
+
+struct __GLXDRIdrawablePrivateRec {
+ __GLXDRIdrawable base;
+
+ GC gc;
+ GC swapgc;
+
+ XVisualInfo *visinfo;
+ XImage *ximage;
+ int bpp;
+};
+
+/**
+ * swrast loader functions
+ */
+
+static Bool XCreateDrawable(__GLXDRIdrawablePrivate *pdp,
+ Display *dpy, XID drawable, int visualid)
+{
+ XGCValues gcvalues;
+ long visMask;
+ XVisualInfo visTemp;
+ int num_visuals;
+
+ /* create GC's */
+ pdp->gc = XCreateGC(dpy, drawable, 0, NULL);
+ pdp->swapgc = XCreateGC(dpy, drawable, 0, NULL);
+
+ gcvalues.function = GXcopy;
+ gcvalues.graphics_exposures = False;
+ XChangeGC(dpy, pdp->gc, GCFunction, &gcvalues);
+ XChangeGC(dpy, pdp->swapgc, GCFunction, &gcvalues);
+ XChangeGC(dpy, pdp->swapgc, GCGraphicsExposures, &gcvalues);
+
+ /* create XImage */
+ visTemp.screen = DefaultScreen(dpy);
+ visTemp.visualid = visualid;
+ visMask = (VisualScreenMask | VisualIDMask);
+ pdp->visinfo = XGetVisualInfo(dpy, visMask, &visTemp, &num_visuals);
+
+ pdp->ximage = XCreateImage(dpy,
+ pdp->visinfo->visual,
+ pdp->visinfo->depth,
+ ZPixmap, 0, /* format, offset */
+ NULL, /* data */
+ 0, 0, /* size */
+ 32, /* bitmap_pad */
+ 0); /* bytes_per_line */
+
+ /* get the true number of bits per pixel */
+ pdp->bpp = pdp->ximage->bits_per_pixel;
+
+ return True;
+}
+
+static void XDestroyDrawable(__GLXDRIdrawablePrivate *pdp,
+ Display *dpy, XID drawable)
+{
+ XDestroyImage(pdp->ximage);
+ XFree(pdp->visinfo);
+
+ XFreeGC(dpy, pdp->gc);
+ XFreeGC(dpy, pdp->swapgc);
+}
+
+static void
+swrastGetDrawableInfo(__DRIdrawable *draw,
+ int *x, int *y, int *w, int *h,
+ void *loaderPrivate)
+{
+ __GLXDRIdrawablePrivate *pdp = loaderPrivate;
+ __GLXDRIdrawable *pdraw = &(pdp->base);;
+ Display *dpy = pdraw->psc->dpy;
+ Drawable drawable;
+
+ Window root;
+ Status stat;
+ unsigned int bw, depth;
+
+ drawable = pdraw->xDrawable;
+
+ stat = XGetGeometry(dpy, drawable, &root,
+ x, y, (unsigned int *)w, (unsigned int *)h,
+ &bw, &depth);
+}
+
+static inline int
+bytes_per_line(int w, int bpp, unsigned mul)
+{
+ unsigned mask = mul - 1;
+
+ return ((w * bpp + mask) & ~mask) / 8;
+}
+
+static void
+swrastPutImage(__DRIdrawable *draw, int op,
+ int x, int y, int w, int h, char *data,
+ void *loaderPrivate)
+{
+ __GLXDRIdrawablePrivate *pdp = loaderPrivate;
+ __GLXDRIdrawable *pdraw = &(pdp->base);;
+ Display *dpy = pdraw->psc->dpy;
+ Drawable drawable;
+ XImage *ximage;
+ GC gc;
+
+ switch (op) {
+ case __DRI_SWRAST_IMAGE_OP_DRAW:
+ gc = pdp->gc;
+ break;
+ case __DRI_SWRAST_IMAGE_OP_SWAP:
+ gc = pdp->swapgc;
+ break;
+ default:
+ return;
+ }
+
+ drawable = pdraw->xDrawable;
+
+ ximage = pdp->ximage;
+ ximage->data = data;
+ ximage->width = w;
+ ximage->height = h;
+ ximage->bytes_per_line = bytes_per_line(w, pdp->bpp, 32);
+
+ XPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h);
+
+ ximage->data = NULL;
+}
+
+static void
+swrastGetImage(__DRIdrawable *draw,
+ int x, int y, int w, int h, char *data,
+ void *loaderPrivate)
+{
+ __GLXDRIdrawablePrivate *pdp = loaderPrivate;
+ __GLXDRIdrawable *pdraw = &(pdp->base);;
+ Display *dpy = pdraw->psc->dpy;
+ Drawable drawable;
+ XImage *ximage;
+
+ drawable = pdraw->xDrawable;
+
+ ximage = pdp->ximage;
+ ximage->data = data;
+ ximage->width = w;
+ ximage->height = h;
+ ximage->bytes_per_line = bytes_per_line(w, pdp->bpp, 32);
+
+ XGetSubImage(dpy, drawable, x, y, w, h, ~0L, ZPixmap, ximage, 0, 0);
+
+ ximage->data = NULL;
+}
+
+static const __DRIswrastLoaderExtension swrastLoaderExtension = {
+ { __DRI_SWRAST_LOADER, __DRI_SWRAST_LOADER_VERSION },
+ swrastGetDrawableInfo,
+ swrastPutImage,
+ swrastGetImage
+};
+
+static const __DRIextension *loader_extensions[] = {
+ &systemTimeExtension.base,
+ &swrastLoaderExtension.base,
+ NULL
+};
+
+/**
+ * GLXDRI functions
+ */
+
+static void driDestroyContext(__GLXDRIcontext *context,
+ __GLXscreenConfigs *psc, Display *dpy)
+{
+ __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
+ const __DRIcoreExtension *core = pcp->psc->core;
+
+ (*core->destroyContext)(pcp->driContext);
+
+ Xfree(pcp);
+}
+
+static Bool driBindContext(__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 driUnbindContext(__GLXDRIcontext *context)
+{
+ __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
+ const __DRIcoreExtension *core = pcp->psc->core;
+
+ (*core->unbindContext)(pcp->driContext);
+}
+
+static __GLXDRIcontext *driCreateContext(__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 (!psc || !psc->driScreen)
+ return 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);
+ if (pcp->driContext == NULL) {
+ Xfree(pcp);
+ return NULL;
+ }
+
+ pcp->base.destroyContext = driDestroyContext;
+ pcp->base.bindContext = driBindContext;
+ pcp->base.unbindContext = driUnbindContext;
+
+ return &pcp->base;
+}
+
+static void driDestroyDrawable(__GLXDRIdrawable *pdraw)
+{
+ __GLXDRIdrawablePrivate *pdp = (__GLXDRIdrawablePrivate *) pdraw;
+ const __DRIcoreExtension *core = pdraw->psc->core;
+
+ (*core->destroyDrawable)(pdraw->driDrawable);
+
+ XDestroyDrawable(pdp, pdraw->psc->dpy, pdraw->drawable);
+ Xfree(pdp);
+}
+
+static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc,
+ XID xDrawable,
+ GLXDrawable drawable,
+ const __GLcontextModes *modes)
+{
+ __GLXDRIdrawable *pdraw;
+ __GLXDRIdrawablePrivate *pdp;
+ __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
+ const __DRIswrastExtension *swrast = psc->swrast;
+
+ /* Old dri can't handle GLX 1.3+ drawable constructors. */
+ if (xDrawable != drawable)
+ return NULL;
+
+ pdp = Xmalloc(sizeof(*pdp));
+ if (!pdp)
+ return NULL;
+
+ pdraw = &(pdp->base);
+ pdraw->xDrawable = xDrawable;
+ pdraw->drawable = drawable;
+ pdraw->psc = psc;
+
+ XCreateDrawable(pdp, psc->dpy, xDrawable, modes->visualID);
+
+ /* Create a new drawable */
+ pdraw->driDrawable =
+ (*swrast->createNewDrawable)(psc->__driScreen,
+ config->driConfig,
+ pdp);
+
+ if (!pdraw->driDrawable) {
+ XDestroyDrawable(pdp, psc->dpy, xDrawable);
+ Xfree(pdp);
+ return NULL;
+ }
+
+ pdraw->destroyDrawable = driDestroyDrawable;
+
+ return pdraw;
+}
+
+static void driDestroyScreen(__GLXscreenConfigs *psc)
+{
+ /* Free the direct rendering per screen data */
+ (*psc->core->destroyScreen)(psc->__driScreen);
+ psc->__driScreen = NULL;
+ if (psc->driver)
+ dlclose(psc->driver);
+}
+
+static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen,
+ __GLXdisplayPrivate *priv)
+{
+ __GLXDRIscreen *psp;
+ const __DRIconfig **driver_configs;
+ const __DRIextension **extensions;
+ const char *driverName = "swrast";
+ 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;
+
+ 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 (strcmp(extensions[i]->name, __DRI_SWRAST) == 0)
+ psc->swrast = (__DRIswrastExtension *) extensions[i];
+ }
+
+ if (psc->core == NULL || psc->swrast == NULL) {
+ ErrorMessageF("core dri extension not found\n");
+ goto handle_error;
+ }
+
+ psc->__driScreen =
+ psc->swrast->createNewScreen(screen,
+ loader_extensions, &driver_configs, psc);
+ if (psc->__driScreen == NULL) {
+ ErrorMessageF("failed to create dri screen\n");
+ goto handle_error;
+ }
+
+ driBindExtensions(psc, 0);
+
+ psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
+ psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
+
+ psp->destroyScreen = driDestroyScreen;
+ psp->createContext = driCreateContext;
+ psp->createDrawable = driCreateDrawable;
+
+ return psp;
+
+ handle_error:
+ Xfree(psp);
+
+ if (psc->driver)
+ dlclose(psc->driver);
+
+ ErrorMessageF("reverting to indirect rendering\n");
+
+ return NULL;
+}
+
+/* Called from __glXFreeDisplayPrivate.
+ */
+static void driDestroyDisplay(__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 *driswCreateDisplay(Display *dpy)
+{
+ __GLXDRIdisplayPrivate *pdpyp;
+
+ pdpyp = Xmalloc(sizeof *pdpyp);
+ if (pdpyp == NULL)
+ return NULL;
+
+ pdpyp->base.destroyDisplay = driDestroyDisplay;
+ pdpyp->base.createScreen = driCreateScreen;
+
+ return &pdpyp->base;
+}
+
+#endif /* GLX_DIRECT_RENDERING */
diff --git a/src/glx/x11/glcontextmodes.c b/src/glx/x11/glcontextmodes.c
index 788ecf6a3a..326c8b2357 100644
--- a/src/glx/x11/glcontextmodes.c
+++ b/src/glx/x11/glcontextmodes.c
@@ -336,7 +336,8 @@ _gl_get_context_mode_data(const __GLcontextModes *mode, int attribute,
*value_return = mode->bindToTextureRgba;
return 0;
case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
- *value_return = mode->bindToMipmapTexture;
+ *value_return = mode->bindToMipmapTexture == GL_TRUE ? GL_TRUE :
+ GL_FALSE;
return 0;
case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
*value_return = mode->bindToTextureTargets;
@@ -417,7 +418,7 @@ _gl_context_modes_create( unsigned count, size_t minimum_size )
(*next)->bindToTextureRgb = GLX_DONT_CARE;
(*next)->bindToTextureRgba = GLX_DONT_CARE;
(*next)->bindToMipmapTexture = GLX_DONT_CARE;
- (*next)->bindToTextureTargets = 0;
+ (*next)->bindToTextureTargets = GLX_DONT_CARE;
(*next)->yInverted = GLX_DONT_CARE;
next = & ((*next)->next);
@@ -456,19 +457,28 @@ _gl_context_modes_destroy( __GLcontextModes * modes )
*/
__GLcontextModes *
-_gl_context_modes_find_visual( __GLcontextModes * modes, int vid )
+_gl_context_modes_find_visual(__GLcontextModes *modes, int vid)
{
- while ( modes != NULL ) {
- if ( modes->visualID == vid ) {
- break;
- }
+ __GLcontextModes *m;
- modes = modes->next;
- }
+ for (m = modes; m != NULL; m = m->next)
+ if (m->visualID == vid)
+ return m;
- return modes;
+ return NULL;
}
+__GLcontextModes *
+_gl_context_modes_find_fbconfig(__GLcontextModes *modes, int fbid)
+{
+ __GLcontextModes *m;
+
+ for (m = modes; m != NULL; m = m->next)
+ if (m->fbconfigID == fbid)
+ return m;
+
+ return NULL;
+}
/**
* Determine if two context-modes are the same. This is intended to be used
diff --git a/src/glx/x11/glcontextmodes.h b/src/glx/x11/glcontextmodes.h
index 4b5c6f68b8..afd09cd7fb 100644
--- a/src/glx/x11/glcontextmodes.h
+++ b/src/glx/x11/glcontextmodes.h
@@ -44,8 +44,10 @@ extern int _gl_get_context_mode_data( const __GLcontextModes *mode,
extern __GLcontextModes * _gl_context_modes_create( unsigned count,
size_t minimum_size );
extern void _gl_context_modes_destroy( __GLcontextModes * modes );
-extern __GLcontextModes * _gl_context_modes_find_visual(
- __GLcontextModes * modes, int vid );
+extern __GLcontextModes *
+ _gl_context_modes_find_visual(__GLcontextModes *modes, int vid);
+extern __GLcontextModes *
+ _gl_context_modes_find_fbconfig(__GLcontextModes *modes, int fbid);
extern GLboolean _gl_context_modes_are_same( const __GLcontextModes * a,
const __GLcontextModes * b );
diff --git a/src/glx/x11/glx_pbuffer.c b/src/glx/x11/glx_pbuffer.c
index 1df2d0f342..0f878f223f 100644
--- a/src/glx/x11/glx_pbuffer.c
+++ b/src/glx/x11/glx_pbuffer.c
@@ -164,6 +164,33 @@ DestroyPbuffer( Display * dpy, GLXDrawable drawable )
}
+#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
+
/**
* Get a drawable's attribute.
*
@@ -261,6 +288,16 @@ GetDrawableAttribute( Display *dpy, GLXDrawable drawable,
}
}
+#ifdef GLX_DIRECT_RENDERING
+ {
+ __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
+
+ if (pdraw != NULL && !pdraw->textureTarget)
+ pdraw->textureTarget = determineTextureTarget((const int *)data,
+ num_attributes);
+ }
+#endif
+
Xfree( data );
}
}
@@ -271,7 +308,6 @@ GetDrawableAttribute( Display *dpy, GLXDrawable drawable,
return 0;
}
-
/**
* Create a non-pbuffer GLX drawable.
*
@@ -306,7 +342,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 +351,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 +414,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;
}
@@ -460,8 +538,24 @@ glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
PUBLIC GLXPbuffer
glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attrib_list)
{
+ int i, width, height;
+
+ width = 0;
+ height = 0;
+
+ for (i = 0; attrib_list[i * 2]; i++) {
+ switch (attrib_list[i * 2]) {
+ case GLX_PBUFFER_WIDTH:
+ width = attrib_list[i * 2 + 1];
+ break;
+ case GLX_PBUFFER_HEIGHT:
+ height = attrib_list[i * 2 + 1];
+ break;
+ }
+ }
+
return (GLXPbuffer) CreatePbuffer( dpy, (__GLcontextModes *) config,
- 0, 0,
+ width, height,
attrib_list, GL_TRUE );
}
diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h
index f9d076f56f..8aa13da478 100644
--- a/src/glx/x11/glxclient.h
+++ b/src/glx/x11/glxclient.h
@@ -58,19 +58,23 @@
#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>
#elif defined( PTHREADS )
# include <pthread.h>
#endif
+#include "glxextensions.h"
+
#define GLX_MAJOR_VERSION 1 /* current version numbers */
#define GLX_MINOR_VERSION 4
#define __GLX_MAX_TEXTURE_UNITS 32
+typedef struct __GLXscreenConfigsRec __GLXscreenConfigs;
typedef struct __GLXcontextRec __GLXcontext;
+typedef struct __GLXdrawableRec __GLXdrawable;
typedef struct __GLXdisplayPrivateRec __GLXdisplayPrivate;
typedef struct _glapi_table __GLapi;
@@ -78,6 +82,9 @@ typedef struct _glapi_table __GLapi;
#ifdef GLX_DIRECT_RENDERING
+#define containerOf(ptr, type, member) \
+ (type *)( (char *)ptr - offsetof(type,member) )
+
#include <GL/internal/dri_interface.h>
@@ -85,43 +92,65 @@ typedef struct _glapi_table __GLapi;
* Display dependent methods. This structure is initialized during the
* \c driCreateDisplay call.
*/
-struct __DRIdisplayRec {
+typedef struct __GLXDRIdisplayRec __GLXDRIdisplay;
+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.
*/
- void (*destroyDisplay)(Display *dpy, void *displayPrivate);
+ void (*destroyDisplay)(__GLXDRIdisplay *display);
- /**
- * Opaque pointer to private per display direct rendering data.
- * \c NULL if direct rendering is not supported on this display.
- */
- struct __DRIdisplayPrivateRec *private;
+ __GLXDRIscreen *(*createScreen)(__GLXscreenConfigs *psc, int screen,
+ __GLXdisplayPrivate *priv);
+};
- /**
- * Array of pointers to methods to create and initialize the private DRI
- * screen data.
- */
- PFNCREATENEWSCREENFUNC * createNewScreen;
+struct __GLXDRIscreenRec {
+
+ void (*destroyScreen)(__GLXscreenConfigs *psc);
+
+ __GLXDRIcontext *(*createContext)(__GLXscreenConfigs *psc,
+ const __GLcontextModes *mode,
+ GLXContext gc,
+ GLXContext shareList, int renderType);
+
+ __GLXDRIdrawable *(*createDrawable)(__GLXscreenConfigs *psc,
+ XID drawable,
+ GLXDrawable glxDrawable,
+ const __GLcontextModes *modes);
};
+struct __GLXDRIcontextRec {
+ void (*destroyContext)(__GLXDRIcontext *context, __GLXscreenConfigs *psc,
+ Display *dpy);
+ Bool (*bindContext)(__GLXDRIcontext *context,
+ __GLXDRIdrawable *pdraw,
+ __GLXDRIdrawable *pread);
+
+ void (*unbindContext)(__GLXDRIcontext *context);
+};
-/*
-** We keep a linked list of these structures, one per DRI device driver.
-*/
-struct __DRIdriverRec {
- const char *name;
- void *handle;
- PFNCREATENEWSCREENFUNC createNewScreenFunc;
- struct __DRIdriverRec *next;
+struct __GLXDRIdrawableRec {
+ void (*destroyDrawable)(__GLXDRIdrawable *drawable);
+
+ XID xDrawable;
+ XID drawable;
+ __GLXscreenConfigs *psc;
+ __DRIdrawable *driDrawable;
+ GLenum textureTarget;
};
/*
** Function to create and DRI display data and initialize the display
** dependent methods.
*/
-extern void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp);
-
-extern __DRIdriver *driGetDriver(Display *dpy, int scrNum);
+extern __GLXDRIdisplay *driswCreateDisplay(Display *dpy);
+extern __GLXDRIdisplay *driCreateDisplay(Display *dpy);
+extern __GLXDRIdisplay *dri2CreateDisplay(Display *dpy);
extern void DRI_glXUseXFont( Font font, int first, int count, int listbase );
@@ -133,8 +162,6 @@ extern const char *glXGetScreenDriver (Display *dpy, int scrNum);
extern const char *glXGetDriverConfig (const char *driverName);
-extern Bool __glXWindowExists(Display *dpy, GLXDrawable draw);
-
#endif
/************************************************************************/
@@ -226,18 +253,10 @@ struct __GLXcontextRec {
XID share_xid;
/**
- * Visual id.
- *
- * \deprecated
- * This filed has been largely been replaced by the \c mode field, but
- * the work is not quite done.
- */
- VisualID vid;
-
- /**
* Screen number.
*/
GLint screen;
+ __GLXscreenConfigs *psc;
/**
* \c GL_TRUE if the context was created with ImportContext, which
@@ -343,24 +362,15 @@ struct __GLXcontextRec {
*/
GLint majorOpcode;
-#ifdef GLX_DIRECT_RENDERING
/**
- * Per context direct rendering interface functions and data.
+ * Pointer to the mode used to create this context.
*/
- __DRIcontext driContext;
+ const __GLcontextModes * mode;
+
+#ifdef GLX_DIRECT_RENDERING
+ __GLXDRIcontext *driContext;
+ __DRIcontext *__driContext;
#endif
-
- /**
- * \c GLXFBConfigID used to create this context. May be \c None. This
- * field has been replaced by the \c mode field.
- *
- * \since Internal API version 20030317.
- *
- * \deprecated
- * This filed has been largely been replaced by the \c mode field, but
- * the work is not quite done.
- */
- GLXFBConfigID fbconfigID;
/**
* The current read-drawable for this context. Will be None if this
@@ -438,7 +448,7 @@ extern void __glFreeAttributeState(__GLXcontext *);
* One of these records exists per screen of the display. It contains
* a pointer to the config data for that screen (if the screen supports GL).
*/
-typedef struct __GLXscreenConfigsRec {
+struct __GLXscreenConfigsRec {
/**
* GLX extension string reported by the X-server.
*/
@@ -454,13 +464,47 @@ typedef struct __GLXscreenConfigsRec {
/**
* Per screen direct rendering interface functions and data.
*/
- __DRIscreen driScreen;
+ __DRIscreen *__driScreen;
+ const __DRIcoreExtension *core;
+ const __DRIlegacyExtension *legacy;
+ const __DRIswrastExtension *swrast;
+ __glxHashTable *drawHash;
+ Display *dpy;
+ int scr, fd;
+ void *driver;
+
+ __GLXDRIscreen *driScreen;
+
+#ifdef __DRI_COPY_SUB_BUFFER
+ const __DRIcopySubBufferExtension *copySubBuffer;
+#endif
+
+#ifdef __DRI_SWAP_CONTROL
+ const __DRIswapControlExtension *swapControl;
+#endif
+
+#ifdef __DRI_ALLOCATE
+ const __DRIallocateExtension *allocate;
+#endif
+
+#ifdef __DRI_FRAME_TRACKING
+ const __DRIframeTrackingExtension *frameTracking;
+#endif
+
+#ifdef __DRI_MEDIA_STREAM_COUNTER
+ const __DRImediaStreamCounterExtension *msc;
+#endif
+
+#ifdef __DRI_TEX_BUFFER
+ const __DRItexBufferExtension *texBuffer;
+#endif
+
#endif
/**
- * Linked list of configurations for this screen.
+ * Linked list of glx visuals and fbconfigs for this screen.
*/
- __GLcontextModes *configs;
+ __GLcontextModes *visuals, *configs;
/**
* Per-screen dynamic GLX extension tracking. The \c direct_support
@@ -474,7 +518,7 @@ typedef struct __GLXscreenConfigsRec {
GLboolean ext_list_first_time;
/*@}*/
-} __GLXscreenConfigs;
+};
/**
* Per display private data. One of these records exists for each display
@@ -523,11 +567,12 @@ struct __GLXdisplayPrivateRec {
/**
* Per display direct rendering interface functions and data.
*/
- __DRIdisplay driDisplay;
+ __GLXDRIdisplay *driswDisplay;
+ __GLXDRIdisplay *driDisplay;
+ __GLXDRIdisplay *dri2Display;
#endif
};
-void __glXFreeContext(__GLXcontext*);
extern GLubyte *__glXFlushRenderBuffer(__GLXcontext*, GLubyte*);
@@ -573,6 +618,10 @@ extern __GLXcontext *__glXcurrentContext;
#endif /* defined( USE_XTHREADS ) || defined( PTHREADS ) */
+extern void __glXSetCurrentContextNull(void);
+
+extern void __glXFreeContext(__GLXcontext*);
+
/*
** Global lock for all threads in this address space using the GLX
@@ -647,9 +696,10 @@ extern void __glEmptyImage(__GLXcontext*, GLint, GLint, GLint, GLint, GLenum,
/*
-** Allocate and Initialize Vertex Array client state
+** Allocate and Initialize Vertex Array client state, and free.
*/
-extern void __glXInitVertexArrayState(__GLXcontext*);
+extern void __glXInitVertexArrayState(__GLXcontext *);
+extern void __glXFreeVertexArrayState(__GLXcontext *);
/*
** Inform the Server of the major and minor numbers and of the client
@@ -682,13 +732,16 @@ extern char *__glXstrdup(const char *str);
extern const char __glXGLClientVersion[];
extern const char __glXGLClientExtensions[];
-/* Determine the internal API version */
-extern int __glXGetInternalVersion(void);
-
/* Get the unadjusted system time */
extern int __glXGetUST( int64_t * ust );
-extern Bool __glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
- int32_t * numerator, int32_t * denominator);
+extern GLboolean __glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
+ int32_t * numerator, int32_t * denominator);
+
+#ifdef GLX_DIRECT_RENDERING
+GLboolean
+__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 80281896f6..cd9605cdff 100644
--- a/src/glx/x11/glxcmds.c
+++ b/src/glx/x11/glxcmds.c
@@ -38,63 +38,110 @@
* Client-side GLX interface.
*/
-#include <inttypes.h>
#include "glxclient.h"
-#include <X11/extensions/extutil.h>
-#include <X11/extensions/Xext.h>
-#include <assert.h>
-#include <string.h>
#include "glapi.h"
-#ifdef GLX_DIRECT_RENDERING
-#include "indirect_init.h"
-#include <X11/extensions/xf86vmode.h>
-#include "xf86dri.h"
-#endif
#include "glxextensions.h"
#include "glcontextmodes.h"
#include "glheader.h"
+
+#ifdef GLX_DIRECT_RENDERING
#include <sys/time.h>
+#include <X11/extensions/xf86vmode.h>
+#include "xf86dri.h"
+#endif
static const char __glXGLXClientVendorName[] = "SGI";
static const char __glXGLXClientVersion[] = "1.4";
/****************************************************************************/
+
+#ifdef GLX_DIRECT_RENDERING
+
+static Bool windowExistsFlag;
+static int windowExistsErrorHandler(Display *dpy, XErrorEvent *xerr)
+{
+ if (xerr->error_code == BadWindow) {
+ windowExistsFlag = GL_FALSE;
+ }
+ return 0;
+}
+
+/**
+ * Find drawables in the local hash that have been destroyed on the
+ * server.
+ *
+ * \param dpy Display to destroy drawables for
+ * \param screen Screen number to destroy drawables for
+ */
+static void GarbageCollectDRIDrawables(Display *dpy, __GLXscreenConfigs *sc)
+{
+ XID draw;
+ __GLXDRIdrawable *pdraw;
+ XWindowAttributes xwa;
+ int (*oldXErrorHandler)(Display *, XErrorEvent *);
+
+ /* Set no-op error handler so Xlib doesn't bail out if the windows
+ * has alreay been destroyed on the server. */
+ XSync(dpy, GL_FALSE);
+ oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler);
+
+ if (__glxHashFirst(sc->drawHash, &draw, (void *)&pdraw) == 1) {
+ do {
+ windowExistsFlag = GL_TRUE;
+ XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */
+ if (!windowExistsFlag) {
+ /* Destroy the local drawable data, if the drawable no
+ longer exists in the Xserver */
+ (*pdraw->destroyDrawable)(pdraw);
+ __glxHashDelete(sc->drawHash, draw);
+ }
+ } while (__glxHashNext(sc->drawHash, &draw, (void *)&pdraw) == 1);
+ }
+
+ XSync(dpy, GL_FALSE);
+ XSetErrorHandler(oldXErrorHandler);
+}
+
+extern __GLXDRIdrawable *
+GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num);
+
/**
* Get the __DRIdrawable for the drawable associated with a GLXContext
*
* \param dpy The display associated with \c drawable.
* \param drawable GLXDrawable whose __DRIdrawable part is to be retrieved.
+ * \param scrn_num If non-NULL, the drawables screen is stored there
* \returns A pointer to the context's __DRIdrawable on success, or NULL if
* the drawable is not associated with a direct-rendering context.
*/
-
-#ifdef GLX_DIRECT_RENDERING
-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);
-
- if ( (priv != NULL) && (priv->driDisplay.private != NULL) ) {
- const unsigned screen_count = ScreenCount(dpy);
- unsigned i;
-
- for ( i = 0 ; i < screen_count ; i++ ) {
- __DRIscreen * const psc = &priv->screenConfigs[i].driScreen;
- __DRIdrawable * const pdraw = (psc->private != NULL)
- ? (*psc->getDrawable)(dpy, drawable, psc->private) : NULL;
+ __GLXdisplayPrivate *priv = __glXInitialize(dpy);
+ __GLXDRIdrawable *pdraw;
+ const unsigned screen_count = ScreenCount(dpy);
+ unsigned i;
+ __GLXscreenConfigs *psc;
- if ( pdraw != NULL ) {
- if ( scrn_num != NULL ) {
- *scrn_num = i;
- }
- return pdraw;
- }
+ if (priv == NULL)
+ return NULL;
+
+ for (i = 0; i < screen_count; i++) {
+ 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;
}
}
return NULL;
}
+
#endif
@@ -264,9 +311,9 @@ GLXContext AllocateGLXContext( Display *dpy )
*/
gc->fastImageUnpack = GL_FALSE;
gc->fillImage = __glFillImage;
- gc->isDirect = GL_FALSE;
gc->pc = gc->buf;
gc->bufEnd = gc->buf + bufSize;
+ gc->isDirect = GL_FALSE;
if (__glXDebug) {
/*
** Set limit register so that there will be one command per packet
@@ -312,6 +359,10 @@ CreateContext(Display *dpy, XVisualInfo *vis,
Bool use_glx_1_3, int renderType)
{
GLXContext gc;
+#ifdef GLX_DIRECT_RENDERING
+ int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen;
+ __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
+#endif
if ( dpy == NULL )
return NULL;
@@ -325,41 +376,36 @@ CreateContext(Display *dpy, XVisualInfo *vis,
return NULL;
#ifdef GLX_DIRECT_RENDERING
- if (allowDirect) {
- int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen;
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
+ if (allowDirect && psc->driScreen) {
const __GLcontextModes * mode;
- /* The value of fbconfig cannot change because it is tested
- * later in the function.
- */
- if ( fbconfig == NULL ) {
- /* FIXME: Is it possible for the __GLcontextModes structure
- * FIXME: to not be found?
- */
- mode = _gl_context_modes_find_visual( psc->configs,
- vis->visualid );
- assert( mode != NULL );
- assert( mode->screen == screen );
+ if (fbconfig == NULL) {
+ mode = _gl_context_modes_find_visual(psc->visuals, vis->visualid);
+ if (mode == NULL) {
+ xError error;
+
+ error.errorCode = BadValue;
+ error.resourceID = vis->visualid;
+ error.sequenceNumber = dpy->request;
+ error.type = X_Error;
+ error.majorCode = gc->majorOpcode;
+ error.minorCode = X_GLXCreateContext;
+ _XError(dpy, &error);
+ return None;
+ }
}
else {
mode = fbconfig;
}
- if (psc && psc->driScreen.private) {
- void * const shared = (shareList != NULL)
- ? shareList->driContext.private : NULL;
- gc->driContext.private =
- (*psc->driScreen.createNewContext)( dpy, mode, renderType,
- shared,
- &gc->driContext );
- if (gc->driContext.private) {
- gc->isDirect = GL_TRUE;
- gc->screen = mode->screen;
- gc->vid = mode->visualID;
- gc->fbconfigID = mode->fbconfigID;
- gc->driContext.mode = mode;
- }
+ gc->driContext = psc->driScreen->createContext(psc, mode, gc,
+ shareList,
+ renderType);
+ if (gc->driContext != NULL) {
+ gc->screen = mode->screen;
+ gc->psc = psc;
+ gc->mode = mode;
+ gc->isDirect = GL_TRUE;
}
}
#endif
@@ -376,7 +422,11 @@ CreateContext(Display *dpy, XVisualInfo *vis,
req->visual = vis->visualid;
req->screen = vis->screen;
req->shareList = shareList ? shareList->xid : None;
- req->isDirect = gc->isDirect;
+#ifdef GLX_DIRECT_RENDERING
+ req->isDirect = gc->driContext != NULL;
+#else
+ req->isDirect = 0;
+#endif
}
else if ( use_glx_1_3 ) {
xGLXCreateNewContextReq *req;
@@ -390,7 +440,11 @@ CreateContext(Display *dpy, XVisualInfo *vis,
req->screen = fbconfig->screen;
req->renderType = renderType;
req->shareList = shareList ? shareList->xid : None;
- req->isDirect = gc->isDirect;
+#ifdef GLX_DIRECT_RENDERING
+ req->isDirect = gc->driContext != NULL;
+#else
+ req->isDirect = 0;
+#endif
}
else {
xGLXVendorPrivateWithReplyReq *vpreq;
@@ -408,7 +462,11 @@ CreateContext(Display *dpy, XVisualInfo *vis,
req->screen = fbconfig->screen;
req->renderType = renderType;
req->shareList = shareList ? shareList->xid : None;
- req->isDirect = gc->isDirect;
+#ifdef GLX_DIRECT_RENDERING
+ req->isDirect = gc->driContext != NULL;
+#else
+ req->isDirect = 0;
+#endif
}
UnlockDisplay(dpy);
@@ -430,7 +488,7 @@ PUBLIC GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis,
False, 0);
}
-void __glXFreeContext(__GLXcontext *gc)
+_X_HIDDEN void __glXFreeContext(__GLXcontext *gc)
{
if (gc->vendor) XFree((char *) gc->vendor);
if (gc->renderer) XFree((char *) gc->renderer);
@@ -466,15 +524,15 @@ DestroyContext(Display *dpy, GLXContext gc)
#ifdef GLX_DIRECT_RENDERING
/* Destroy the direct rendering context */
- if (gc->isDirect) {
- if (gc->driContext.private) {
- (*gc->driContext.destroyContext)(dpy, gc->screen,
- gc->driContext.private);
- gc->driContext.private = NULL;
- }
+ if (gc->driContext) {
+ (*gc->driContext->destroyContext)(gc->driContext, gc->psc, dpy);
+ gc->driContext = NULL;
+ GarbageCollectDRIDrawables(dpy, gc->psc);
}
#endif
+ __glXFreeVertexArrayState(gc);
+
if (gc->currentDpy) {
/* Have to free later cuz it's in use now */
__glXUnlock();
@@ -552,7 +610,7 @@ PUBLIC void glXWaitGL(void)
__glXFlushRenderBuffer(gc, gc->pc);
#ifdef GLX_DIRECT_RENDERING
- if (gc->isDirect) {
+ if (gc->driContext) {
/* This bit of ugliness unwraps the glFinish function */
#ifdef glFinish
#undef glFinish
@@ -588,7 +646,7 @@ PUBLIC void glXWaitX(void)
__glXFlushRenderBuffer(gc, gc->pc);
#ifdef GLX_DIRECT_RENDERING
- if (gc->isDirect) {
+ if (gc->driContext) {
XSync(dpy, False);
return;
}
@@ -618,7 +676,7 @@ PUBLIC void glXUseXFont(Font font, int first, int count, int listBase)
(void) __glXFlushRenderBuffer(gc, gc->pc);
#ifdef GLX_DIRECT_RENDERING
- if (gc->isDirect) {
+ if (gc->driContext) {
DRI_glXUseXFont(font, first, count, listBase);
return;
}
@@ -658,7 +716,7 @@ PUBLIC void glXCopyContext(Display *dpy, GLXContext source,
}
#ifdef GLX_DIRECT_RENDERING
- if (gc->isDirect) {
+ if (gc->driContext) {
/* NOT_DONE: This does not work yet */
}
#endif
@@ -730,7 +788,7 @@ PUBLIC Bool glXIsDirect(Display *dpy, GLXContext gc)
if (!gc) {
return GL_FALSE;
#ifdef GLX_DIRECT_RENDERING
- } else if (gc->isDirect) {
+ } else if (gc->driContext) {
return GL_TRUE;
#endif
}
@@ -793,10 +851,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)(dpy, pdraw->private);
+ if (pdraw != NULL) {
+ (*pdraw->psc->core->swapBuffers)(pdraw->driDrawable);
return;
}
#endif
@@ -840,12 +898,12 @@ PUBLIC int glXGetConfig(Display *dpy, XVisualInfo *vis, int attribute,
{
__GLXdisplayPrivate *priv;
__GLXscreenConfigs *psc;
+ __GLcontextModes *modes;
int status;
status = GetGLXPrivScreenConfig( dpy, vis->screen, & priv, & psc );
if ( status == Success ) {
- const __GLcontextModes * const modes = _gl_context_modes_find_visual(
- psc->configs, vis->visualid );
+ modes = _gl_context_modes_find_visual(psc->visuals, vis->visualid);
/* Lookup attribute after first finding a match on the visual */
if ( modes != NULL ) {
@@ -1223,7 +1281,7 @@ PUBLIC XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *attribList)
** Compute a score for those that do
** Remember which visual, if any, got the highest score
*/
- for ( modes = psc->configs ; modes != NULL ; modes = modes->next ) {
+ for ( modes = psc->visuals ; modes != NULL ; modes = modes->next ) {
if ( fbconfigs_compatible( & test_config, modes )
&& ((best_config == NULL)
|| (fbconfig_compare( (const __GLcontextModes * const * const)&modes, &best_config ) < 0)) ) {
@@ -1268,7 +1326,7 @@ PUBLIC const char *glXQueryExtensionsString( Display *dpy, int screen )
__glXCalculateUsableExtensions(psc,
#ifdef GLX_DIRECT_RENDERING
- (psc->driScreen.private != NULL),
+ (psc->driScreen != NULL),
#else
GL_FALSE,
#endif
@@ -1447,13 +1505,15 @@ static int __glXQueryContextInfo(Display *dpy, GLXContext ctx)
ctx->share_xid = *pProp++;
break;
case GLX_VISUAL_ID_EXT:
- ctx->vid = *pProp++;
+ ctx->mode =
+ _gl_context_modes_find_visual(ctx->psc->visuals, *pProp++);
break;
case GLX_SCREEN:
ctx->screen = *pProp++;
break;
case GLX_FBCONFIG_ID:
- ctx->fbconfigID = *pProp++;
+ ctx->mode =
+ _gl_context_modes_find_fbconfig(ctx->psc->configs, *pProp++);
break;
case GLX_RENDER_TYPE:
ctx->renderType = *pProp++;
@@ -1478,7 +1538,11 @@ glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value)
int retVal;
/* get the information from the server if we don't have it already */
- if (!ctx->isDirect && (ctx->vid == None)) {
+#ifdef GLX_DIRECT_RENDERING
+ if (!ctx->driContext && (ctx->mode == NULL)) {
+#else
+ if (ctx->mode == NULL) {
+#endif
retVal = __glXQueryContextInfo(dpy, ctx);
if (Success != retVal) return retVal;
}
@@ -1487,13 +1551,13 @@ glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value)
*value = (int)(ctx->share_xid);
break;
case GLX_VISUAL_ID_EXT:
- *value = (int)(ctx->vid);
+ *value = ctx->mode ? ctx->mode->visualID : None;
break;
case GLX_SCREEN:
*value = (int)(ctx->screen);
break;
case GLX_FBCONFIG_ID:
- *value = (int)(ctx->fbconfigID);
+ *value = ctx->mode ? ctx->mode->fbconfigID : None;
break;
case GLX_RENDER_TYPE:
*value = (int)(ctx->renderType);
@@ -1591,6 +1655,7 @@ PUBLIC GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements)
__GLcontextModes ** config = NULL;
int i;
+ *nelements = 0;
if ( (priv->screenConfigs != NULL)
&& (screen >= 0) && (screen <= ScreenCount(dpy))
&& (priv->screenConfigs[screen].configs != NULL)
@@ -1615,8 +1680,10 @@ PUBLIC GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements)
for ( modes = priv->screenConfigs[screen].configs
; modes != NULL
; modes = modes->next ) {
- config[i] = modes;
- i++;
+ if ( modes->fbconfigID != GLX_DONT_CARE ) {
+ config[i] = modes;
+ i++;
+ }
}
}
}
@@ -1668,16 +1735,15 @@ static int __glXSwapIntervalSGI(int interval)
return GLX_BAD_VALUE;
}
-#ifdef GLX_DIRECT_RENDERING
- if ( gc->isDirect ) {
+#ifdef __DRI_SWAP_CONTROL
+ if (gc->driContext) {
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
gc->screen );
- __DRIdrawable * const pdraw = GetDRIDrawable( gc->currentDpy,
- gc->currentDrawable,
- NULL );
- if ( __glXExtensionBitIsEnabled( psc, SGI_swap_control_bit )
- && (pdraw != NULL) ) {
- pdraw->swap_interval = interval;
+ __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
+ gc->currentDrawable,
+ NULL);
+ if (psc->swapControl != NULL && pdraw != NULL) {
+ psc->swapControl->setSwapInterval(pdraw->driDrawable, interval);
return 0;
}
else {
@@ -1715,25 +1781,22 @@ static int __glXSwapIntervalSGI(int interval)
*/
static int __glXSwapIntervalMESA(unsigned int interval)
{
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_SWAP_CONTROL
GLXContext gc = __glXGetCurrentContext();
if ( interval < 0 ) {
return GLX_BAD_VALUE;
}
- if ( (gc != NULL) && gc->isDirect ) {
+ if (gc != NULL && gc->driContext) {
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
gc->screen );
- if ( (psc != NULL) && (psc->driScreen.private != NULL)
- && __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) {
- __DRIdrawable * const pdraw =
- (*psc->driScreen.getDrawable)(gc->currentDpy,
- gc->currentDrawable,
- psc->driScreen.private);
- if ( pdraw != NULL ) {
- pdraw->swap_interval = interval;
+ if ( (psc != NULL) && (psc->driScreen != NULL) ) {
+ __GLXDRIdrawable *pdraw =
+ GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+ if (psc->swapControl != NULL && pdraw != NULL) {
+ psc->swapControl->setSwapInterval(pdraw->driDrawable, interval);
return 0;
}
}
@@ -1748,21 +1811,18 @@ static int __glXSwapIntervalMESA(unsigned int interval)
static int __glXGetSwapIntervalMESA(void)
{
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_SWAP_CONTROL
GLXContext gc = __glXGetCurrentContext();
- if ( (gc != NULL) && gc->isDirect ) {
+ if (gc != NULL && gc->driContext) {
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
gc->screen );
- if ( (psc != NULL) && (psc->driScreen.private != NULL)
- && __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) {
- __DRIdrawable * const pdraw =
- (*psc->driScreen.getDrawable)(gc->currentDpy,
- gc->currentDrawable,
- psc->driScreen.private);
- if ( pdraw != NULL ) {
- return pdraw->swap_interval;
+ if ( (psc != NULL) && (psc->driScreen != NULL) ) {
+ __GLXDRIdrawable *pdraw =
+ GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+ if (psc->swapControl != NULL && pdraw != NULL) {
+ return psc->swapControl->getSwapInterval(pdraw->driDrawable);
}
}
}
@@ -1779,15 +1839,13 @@ static int __glXGetSwapIntervalMESA(void)
static GLint __glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable)
{
int status = GLX_BAD_CONTEXT;
-#ifdef GLX_DIRECT_RENDERING
+#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) && (pdraw->frameTracking != NULL)
- && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) {
- status = pdraw->frameTracking( dpy, pdraw->private, GL_TRUE );
- }
+ if (pdraw != NULL && psc->frameTracking != NULL)
+ status = psc->frameTracking->frameTracking(pdraw->driDrawable, GL_TRUE);
#else
(void) dpy;
(void) drawable;
@@ -1799,15 +1857,14 @@ static GLint __glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable)
static GLint __glXEndFrameTrackingMESA(Display *dpy, GLXDrawable drawable)
{
int status = GLX_BAD_CONTEXT;
-#ifdef GLX_DIRECT_RENDERING
+#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) && (pdraw->frameTracking != NULL)
- && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) {
- status = pdraw->frameTracking( dpy, pdraw->private, GL_FALSE );
- }
+ if (pdraw != NULL && psc->frameTracking != NULL)
+ status = psc->frameTracking->frameTracking(pdraw->driDrawable,
+ GL_FALSE);
#else
(void) dpy;
(void) drawable;
@@ -1820,19 +1877,20 @@ static GLint __glXGetFrameUsageMESA(Display *dpy, GLXDrawable drawable,
GLfloat *usage)
{
int status = GLX_BAD_CONTEXT;
-#ifdef GLX_DIRECT_RENDERING
+#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 ) && (pdraw->queryFrameTracking != NULL)
- && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) {
- int64_t sbc, missedFrames;
- float lastMissedUsage;
+ if (pdraw != NULL && psc->frameTracking != NULL) {
+ int64_t sbc, missedFrames;
+ float lastMissedUsage;
- status = pdraw->queryFrameTracking( dpy, pdraw->private, &sbc,
- &missedFrames, &lastMissedUsage,
- usage );
+ status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable,
+ &sbc,
+ &missedFrames,
+ &lastMissedUsage,
+ usage);
}
#else
(void) dpy;
@@ -1848,18 +1906,17 @@ static GLint __glXQueryFrameTrackingMESA(Display *dpy, GLXDrawable drawable,
GLfloat *lastMissedUsage)
{
int status = GLX_BAD_CONTEXT;
-#ifdef GLX_DIRECT_RENDERING
+#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 ) && (pdraw->queryFrameTracking != NULL)
- && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) {
+ if (pdraw != NULL && psc->frameTracking != NULL) {
float usage;
- status = pdraw->queryFrameTracking( dpy, pdraw->private, sbc,
- missedFrames, lastMissedUsage,
- & usage );
+ status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable,
+ sbc, missedFrames,
+ lastMissedUsage, &usage);
}
#else
(void) dpy;
@@ -1881,21 +1938,24 @@ static int __glXGetVideoSyncSGI(unsigned int *count)
* FIXME: there should be a GLX encoding for this call. I can find no
* FIXME: documentation for the GLX encoding.
*/
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_MEDIA_STREAM_COUNTER
GLXContext gc = __glXGetCurrentContext();
- if ( (gc != NULL) && gc->isDirect ) {
+ if (gc != NULL && gc->driContext) {
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
gc->screen );
- if ( __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit )
- && psc->driScreen.private && psc->driScreen.getMSC) {
- int ret;
- int64_t temp;
+ if ( psc->msc && psc->driScreen ) {
+ __GLXDRIdrawable *pdraw =
+ GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+ int64_t temp;
+ int ret;
+
+ ret = (*psc->msc->getDrawableMSC)(psc->__driScreen,
+ pdraw->driDrawable, &temp);
+ *count = (unsigned) temp;
- ret = psc->driScreen.getMSC( psc->driScreen.private, & temp );
- *count = (unsigned) temp;
- return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
+ return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
}
}
#else
@@ -1906,32 +1966,26 @@ static int __glXGetVideoSyncSGI(unsigned int *count)
static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
{
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_MEDIA_STREAM_COUNTER
GLXContext gc = __glXGetCurrentContext();
if ( divisor <= 0 || remainder < 0 )
return GLX_BAD_VALUE;
- if ( (gc != NULL) && gc->isDirect ) {
+ if (gc != NULL && gc->driContext) {
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
gc->screen );
- if ( __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit )
- && psc->driScreen.private ) {
- __DRIdrawable * const pdraw =
- (*psc->driScreen.getDrawable)(gc->currentDpy,
- gc->currentDrawable,
- psc->driScreen.private);
- if ( (pdraw != NULL) && (pdraw->waitForMSC != NULL) ) {
- int ret;
- int64_t msc;
- int64_t sbc;
-
- ret = (*pdraw->waitForMSC)( gc->currentDpy, pdraw->private,
- 0, divisor, remainder,
- & msc, & sbc );
- *count = (unsigned) msc;
- return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
- }
+ if (psc->msc != NULL && psc->driScreen ) {
+ __GLXDRIdrawable *pdraw =
+ GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+ int ret;
+ int64_t msc;
+ int64_t sbc;
+
+ ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, 0,
+ divisor, remainder, &msc, &sbc);
+ *count = (unsigned) msc;
+ return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
}
}
#else
@@ -2083,20 +2137,19 @@ static Bool __glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable,
int64_t *ust, int64_t *msc, int64_t *sbc)
{
-#ifdef GLX_DIRECT_RENDERING
+#if defined(__DRI_SWAP_BUFFER_COUNTER) && defined(__DRI_MEDIA_STREAM_COUNTER)
__GLXdisplayPrivate * const priv = __glXInitialize(dpy);
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 && pdraw->getSBC && psc->driScreen.getMSC)
- && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit )
- && ((*psc->driScreen.getMSC)( psc->driScreen.private, msc ) == 0)
- && ((*pdraw->getSBC)( dpy, psc->driScreen.private, sbc ) == 0)
- && (__glXGetUST( ust ) == 0) );
+ return ( (pdraw && psc->sbc && psc->msc)
+ && ((*psc->msc->getMSC)(psc->driScreen, msc) == 0)
+ && ((*psc->sbc->getSBC)(pdraw->driDrawable, sbc) == 0)
+ && (__glXGetUST(ust) == 0) );
}
#else
(void) dpy;
@@ -2108,6 +2161,68 @@ static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable,
return False;
}
+#ifdef GLX_DIRECT_RENDERING
+_X_HIDDEN GLboolean
+__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 = private;
+
+ psc = glxDraw->psc;
+ if (XF86VidModeQueryVersion(psc->dpy, &i, &i) &&
+ XF86VidModeGetModeLine(psc->dpy, psc->scr, &dot_clock, &mode_line) ) {
+ unsigned n = dot_clock * 1000;
+ unsigned d = mode_line.vtotal * mode_line.htotal;
+
+# define V_INTERLACE 0x010
+# define V_DBLSCAN 0x020
+
+ if (mode_line.flags & V_INTERLACE)
+ n *= 2;
+ else if (mode_line.flags & V_DBLSCAN)
+ d *= 2;
+
+ /* The OML_sync_control spec requires that if the refresh rate is a
+ * whole number, that the returned numerator be equal to the refresh
+ * rate and the denominator be 1.
+ */
+
+ if (n % d == 0) {
+ n /= d;
+ d = 1;
+ }
+ else {
+ static const unsigned f[] = { 13, 11, 7, 5, 3, 2, 0 };
+
+ /* This is a poor man's way to reduce a fraction. It's far from
+ * perfect, but it will work well enough for this situation.
+ */
+
+ for (i = 0; f[i] != 0; i++) {
+ while (n % f[i] == 0 && d % f[i] == 0) {
+ d /= f[i];
+ n /= f[i];
+ }
+ }
+ }
+
+ *numerator = n;
+ *denominator = d;
+
+ return True;
+ }
+ else
+ return False;
+#else
+ return False;
+#endif
+}
+#endif
/**
* Determine the refresh rate of the specified drawable and display.
@@ -2125,70 +2240,17 @@ static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable,
* when GLX_OML_sync_control appears in the client extension string.
*/
-Bool __glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
- int32_t * numerator, int32_t * denominator)
+_X_HIDDEN GLboolean __glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
+ int32_t * numerator,
+ int32_t * denominator)
{
#if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE )
- __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
-
-
- if ( priv != NULL ) {
- XF86VidModeModeLine mode_line;
- int dot_clock;
- int screen_num;
- int i;
-
-
- GetDRIDrawable( dpy, drawable, & screen_num );
- if ( (screen_num != -1)
- && XF86VidModeQueryVersion( dpy, & i, & i )
- && XF86VidModeGetModeLine( dpy, screen_num, & dot_clock,
- & mode_line ) ) {
- unsigned n = dot_clock * 1000;
- unsigned d = mode_line.vtotal * mode_line.htotal;
-
-# define V_INTERLACE 0x010
-# define V_DBLSCAN 0x020
-
- if ( (mode_line.flags & V_INTERLACE) ) {
- n *= 2;
- }
- else if ( (mode_line.flags & V_DBLSCAN) ) {
- d *= 2;
- }
-
- /* The OML_sync_control spec requires that if the refresh rate is a
- * whole number, that the returned numerator be equal to the refresh
- * rate and the denominator be 1.
- */
-
- if ( (n % d) == 0 ) {
- n /= d;
- d = 1;
- }
- else {
- static const unsigned f[] = { 13, 11, 7, 5, 3, 2, 0 };
-
-
- /* This is a poor man's way to reduce a fraction. It's far from
- * perfect, but it will work well enough for this situation.
- */
-
- for ( i = 0 ; f[i] != 0 ; i++ ) {
- while ( ((n % f[i]) == 0) && ((d % f[i]) == 0) ) {
- d /= f[i];
- n /= f[i];
- }
- }
- }
+ __GLXDRIdrawable *draw = GetGLXDRIDrawable(dpy, drawable, NULL);
- *numerator = n;
- *denominator = d;
+ if (draw == NULL)
+ return False;
- (void) drawable;
- return True;
- }
- }
+ return __driGetMscRateOML(draw->driDrawable, numerator, denominator, draw);
#else
(void) dpy;
(void) drawable;
@@ -2203,9 +2265,9 @@ static int64_t __glXSwapBuffersMscOML(Display *dpy, GLXDrawable drawable,
int64_t target_msc, int64_t divisor,
int64_t remainder)
{
-#ifdef GLX_DIRECT_RENDERING
+#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
@@ -2218,11 +2280,10 @@ static int64_t __glXSwapBuffersMscOML(Display *dpy, GLXDrawable drawable,
if ( divisor > 0 && remainder >= divisor )
return -1;
- if ( (pdraw != NULL) && (pdraw->swapBuffersMSC != NULL)
- && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) ) {
- return (*pdraw->swapBuffersMSC)(dpy, pdraw->private, target_msc,
- divisor, remainder);
- }
+ if (pdraw != NULL && psc->counters != NULL)
+ return (*psc->sbc->swapBuffersMSC)(pdraw->driDrawable, target_msc,
+ divisor, remainder);
+
#else
(void) dpy;
(void) drawable;
@@ -2239,9 +2300,9 @@ static Bool __glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
int64_t remainder, int64_t *ust,
int64_t *msc, int64_t *sbc)
{
-#ifdef GLX_DIRECT_RENDERING
+#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;
@@ -2253,10 +2314,9 @@ static Bool __glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
if ( divisor > 0 && remainder >= divisor )
return False;
- if ( (pdraw != NULL) && (pdraw->waitForMSC != NULL)
- && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) ) {
- ret = (*pdraw->waitForMSC)( dpy, pdraw->private, target_msc,
- divisor, remainder, msc, sbc );
+ if (pdraw != NULL && psc->msc != NULL) {
+ ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, target_msc,
+ divisor, remainder, msc, sbc);
/* __glXGetUST returns zero on success and non-zero on failure.
* This function returns True on success and False on failure.
@@ -2281,9 +2341,9 @@ static Bool __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable,
int64_t target_sbc, int64_t *ust,
int64_t *msc, int64_t *sbc )
{
-#ifdef GLX_DIRECT_RENDERING
+#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;
@@ -2293,9 +2353,8 @@ static Bool __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable,
if ( target_sbc < 0 )
return False;
- if ( (pdraw != NULL) && (pdraw->waitForSBC != NULL)
- && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit )) {
- ret = (*pdraw->waitForSBC)( dpy, pdraw->private, target_sbc, msc, sbc );
+ if (pdraw != NULL && psc->sbc != NULL) {
+ 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.
@@ -2323,16 +2382,13 @@ PUBLIC void *glXAllocateMemoryMESA(Display *dpy, int scrn,
size_t size, float readFreq,
float writeFreq, float priority)
{
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_ALLOCATE
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn );
- if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) {
- if (psc && psc->driScreen.private && psc->driScreen.allocateMemory) {
- return (*psc->driScreen.allocateMemory)( dpy, scrn, size,
- readFreq, writeFreq,
- priority );
- }
- }
+ if (psc && psc->allocate)
+ return (*psc->allocate->allocateMemory)(psc->__driScreen, size,
+ readFreq, writeFreq, priority);
+
#else
(void) dpy;
(void) scrn;
@@ -2348,14 +2404,12 @@ PUBLIC void *glXAllocateMemoryMESA(Display *dpy, int scrn,
PUBLIC void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer)
{
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_ALLOCATE
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn );
- if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) {
- if (psc && psc->driScreen.private && psc->driScreen.freeMemory) {
- (*psc->driScreen.freeMemory)( dpy, scrn, pointer );
- }
- }
+ if (psc && psc->allocate)
+ (*psc->allocate->freeMemory)(psc->__driScreen, pointer);
+
#else
(void) dpy;
(void) scrn;
@@ -2367,14 +2421,12 @@ PUBLIC void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer)
PUBLIC GLuint glXGetMemoryOffsetMESA( Display *dpy, int scrn,
const void *pointer )
{
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_ALLOCATE
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn );
- if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) {
- if (psc && psc->driScreen.private && psc->driScreen.memoryOffset) {
- return (*psc->driScreen.memoryOffset)( dpy, scrn, pointer );
- }
- }
+ if (psc && psc->allocate)
+ return (*psc->allocate->memoryOffset)(psc->__driScreen, pointer);
+
#else
(void) dpy;
(void) scrn;
@@ -2447,13 +2499,14 @@ static void __glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable,
INT32 *x_ptr, *y_ptr, *w_ptr, *h_ptr;
CARD8 opcode;
-#ifdef GLX_DIRECT_RENDERING
+#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 ( __glXExtensionBitIsEnabled( psc, MESA_copy_sub_buffer_bit ) ) {
- (*pdraw->copySubBuffer)(dpy, pdraw->private, x, y, width, height);
+ if (psc->copySubBuffer != NULL) {
+ (*psc->copySubBuffer->copySubBuffer)(pdraw->driDrawable,
+ x, y, width, height);
}
return;
@@ -2529,8 +2582,16 @@ static void __glXBindTexImageEXT(Display *dpy,
}
#ifdef GLX_DIRECT_RENDERING
- if (gc->isDirect)
+ 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);
@@ -2581,7 +2642,7 @@ static void __glXReleaseTexImageEXT(Display *dpy,
return;
#ifdef GLX_DIRECT_RENDERING
- if (gc->isDirect)
+ if (gc->driContext)
return;
#endif
@@ -2613,7 +2674,7 @@ static void __glXReleaseTexImageEXT(Display *dpy,
*
* \sa strdup
*/
-char *
+_X_HIDDEN char *
__glXstrdup(const char *str)
{
char *copy;
@@ -2841,98 +2902,6 @@ PUBLIC void (*glXGetProcAddress(const GLubyte *procName))( void )
#ifdef GLX_DIRECT_RENDERING
/**
- * Retrieves the verion of the internal libGL API in YYYYMMDD format. This
- * might be used by the DRI drivers to determine how new libGL is at runtime.
- * Drivers should not call this function directly. They should instead use
- * \c glXGetProcAddress to obtain a pointer to the function.
- *
- * \returns An 8-digit decimal number representing the internal libGL API in
- * YYYYMMDD format.
- *
- * \sa glXGetProcAddress, PFNGLXGETINTERNALVERSIONPROC
- *
- * \since Internal API version 20021121.
- */
-int __glXGetInternalVersion(void)
-{
- /* History:
- * 20021121 - Initial version
- * 20021128 - Added __glXWindowExists() function
- * 20021207 - Added support for dynamic GLX extensions,
- * GLX_SGI_swap_control, GLX_SGI_video_sync,
- * GLX_OML_sync_control, and GLX_MESA_swap_control.
- * Never officially released. Do NOT test against
- * this version. Use 20030317 instead.
- * 20030317 - Added support GLX_SGIX_fbconfig,
- * GLX_MESA_swap_frame_usage, GLX_OML_swap_method,
- * GLX_{ARB,SGIS}_multisample, and
- * GLX_SGIX_visual_select_group.
- * 20030606 - Added support for GLX_SGI_make_current_read.
- * 20030813 - Made support for dynamic extensions multi-head aware.
- * 20030818 - Added support for GLX_MESA_allocate_memory in place of the
- * deprecated GLX_NV_vertex_array_range & GLX_MESA_agp_offset
- * interfaces.
- * 20031201 - Added support for the first round of DRI interface changes.
- * Do NOT test against this version! It has binary
- * compatibility bugs, use 20040317 instead.
- * 20040317 - Added the 'mode' field to __DRIcontextRec.
- * 20040415 - Added support for bindContext3 and unbindContext3.
- * 20040602 - Add __glXGetDrawableInfo. I though that was there
- * months ago. :(
- * 20050727 - Gut all the old interfaces. This breaks compatability with
- * any DRI driver built to any previous version.
- * 20060314 - Added support for GLX_MESA_copy_sub_buffer.
- * 20070105 - Added support for damage reporting.
- */
- return 20070105;
-}
-
-
-
-static Bool windowExistsFlag;
-
-static int windowExistsErrorHandler(Display *dpy, XErrorEvent *xerr)
-{
- if (xerr->error_code == BadWindow) {
- windowExistsFlag = GL_FALSE;
- }
- return 0;
-}
-
-/**
- * Determine if a window associated with a \c GLXDrawable exists on the
- * X-server. This function is not used internally by libGL. It is provided
- * as a utility function for DRI drivers.
- * Drivers should not call this function directly. They should instead use
- * \c glXGetProcAddress to obtain a pointer to the function.
- *
- * \param dpy Display associated with the drawable to be queried.
- * \param draw \c GLXDrawable to test.
- *
- * \returns \c GL_TRUE if a window exists that is associated with \c draw,
- * otherwise \c GL_FALSE is returned.
- *
- * \warning This function is not currently thread-safe.
- *
- * \sa glXGetProcAddress
- *
- * \since Internal API version 20021128.
- */
-Bool __glXWindowExists(Display *dpy, GLXDrawable draw)
-{
- XWindowAttributes xwa;
- int (*oldXErrorHandler)(Display *, XErrorEvent *);
-
- XSync(dpy, GL_FALSE);
- windowExistsFlag = GL_TRUE;
- oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler);
- XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */
- XSetErrorHandler(oldXErrorHandler);
- return windowExistsFlag;
-}
-
-
-/**
* Get the unadjusted system time (UST). Currently, the UST is measured in
* microseconds since Epoc. The actual resolution of the UST may vary from
* system to system, and the units may vary from release to release.
@@ -2946,7 +2915,7 @@ Bool __glXWindowExists(Display *dpy, GLXDrawable draw)
*
* \since Internal API version 20030317.
*/
-int __glXGetUST( int64_t * ust )
+_X_HIDDEN int __glXGetUST( int64_t * ust )
{
struct timeval tv;
diff --git a/src/glx/x11/glxcurrent.c b/src/glx/x11/glxcurrent.c
new file mode 100644
index 0000000000..0d0c419a84
--- /dev/null
+++ b/src/glx/x11/glxcurrent.c
@@ -0,0 +1,518 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+/**
+ * \file glxcurrent.c
+ * Client-side GLX interface for current context management.
+ */
+
+#include "glxclient.h"
+#include "glapi.h"
+#include "glheader.h"
+#include "indirect_init.h"
+
+#ifdef GLX_DIRECT_RENDERING
+#include "xf86dri.h"
+#endif
+
+/*
+** We setup some dummy structures here so that the API can be used
+** even if no context is current.
+*/
+
+static GLubyte dummyBuffer[__GLX_BUFFER_LIMIT_SIZE];
+
+/*
+** Dummy context used by small commands when there is no current context.
+** All the
+** gl and glx entry points are designed to operate as nop's when using
+** the dummy context structure.
+*/
+static __GLXcontext dummyContext = {
+ &dummyBuffer[0],
+ &dummyBuffer[0],
+ &dummyBuffer[0],
+ &dummyBuffer[__GLX_BUFFER_LIMIT_SIZE],
+ sizeof(dummyBuffer),
+};
+
+
+/*
+** All indirect rendering contexts will share the same indirect dispatch table.
+*/
+static __GLapi *IndirectAPI = NULL;
+
+
+/*
+ * Current context management and locking
+ */
+
+#if defined( USE_XTHREADS )
+
+/* thread safe */
+static GLboolean TSDinitialized = GL_FALSE;
+static xthread_key_t ContextTSD;
+
+_X_HIDDEN __GLXcontext *__glXGetCurrentContext(void)
+{
+ if (!TSDinitialized) {
+ xthread_key_create(&ContextTSD, NULL);
+ TSDinitialized = GL_TRUE;
+ return &dummyContext;
+ }
+ else {
+ void *p;
+ xthread_get_specific(ContextTSD, &p);
+ if (!p)
+ return &dummyContext;
+ else
+ return (__GLXcontext *) p;
+ }
+}
+
+_X_HIDDEN void __glXSetCurrentContext(__GLXcontext *c)
+{
+ if (!TSDinitialized) {
+ xthread_key_create(&ContextTSD, NULL);
+ TSDinitialized = GL_TRUE;
+ }
+ xthread_set_specific(ContextTSD, c);
+}
+
+
+/* Used by the __glXLock() and __glXUnlock() macros */
+_X_HIDDEN xmutex_rec __glXmutex;
+
+#elif defined( PTHREADS )
+
+_X_HIDDEN pthread_mutex_t __glXmutex = PTHREAD_MUTEX_INITIALIZER;
+
+# if defined( GLX_USE_TLS )
+
+/**
+ * Per-thread GLX context pointer.
+ *
+ * \c __glXSetCurrentContext is written is such a way that this pointer can
+ * \b never be \c NULL. This is important! Because of this
+ * \c __glXGetCurrentContext can be implemented as trivial macro.
+ */
+__thread void * __glX_tls_Context __attribute__((tls_model("initial-exec")))
+ = &dummyContext;
+
+_X_HIDDEN void __glXSetCurrentContext( __GLXcontext * c )
+{
+ __glX_tls_Context = (c != NULL) ? c : &dummyContext;
+}
+
+# else
+
+static pthread_once_t once_control = PTHREAD_ONCE_INIT;
+
+/**
+ * Per-thread data key.
+ *
+ * Once \c init_thread_data has been called, the per-thread data key will
+ * take a value of \c NULL. As each new thread is created the default
+ * value, in that thread, will be \c NULL.
+ */
+static pthread_key_t ContextTSD;
+
+/**
+ * Initialize the per-thread data key.
+ *
+ * This function is called \b exactly once per-process (not per-thread!) to
+ * initialize the per-thread data key. This is ideally done using the
+ * \c pthread_once mechanism.
+ */
+static void init_thread_data( void )
+{
+ if ( pthread_key_create( & ContextTSD, NULL ) != 0 ) {
+ perror( "pthread_key_create" );
+ exit( -1 );
+ }
+}
+
+_X_HIDDEN void __glXSetCurrentContext( __GLXcontext * c )
+{
+ pthread_once( & once_control, init_thread_data );
+ pthread_setspecific( ContextTSD, c );
+}
+
+_X_HIDDEN __GLXcontext * __glXGetCurrentContext( void )
+{
+ void * v;
+
+ pthread_once( & once_control, init_thread_data );
+
+ v = pthread_getspecific( ContextTSD );
+ return (v == NULL) ? & dummyContext : (__GLXcontext *) v;
+}
+
+# endif /* defined( GLX_USE_TLS ) */
+
+#elif defined( THREADS )
+
+#error Unknown threading method specified.
+
+#else
+
+/* not thread safe */
+_X_HIDDEN __GLXcontext *__glXcurrentContext = &dummyContext;
+
+#endif
+
+
+_X_HIDDEN void __glXSetCurrentContextNull(void)
+{
+ __glXSetCurrentContext(&dummyContext);
+#ifdef GLX_DIRECT_RENDERING
+ _glapi_set_dispatch(NULL); /* no-op functions */
+#endif
+}
+
+
+/************************************************************************/
+
+PUBLIC GLXContext glXGetCurrentContext(void)
+{
+ GLXContext cx = __glXGetCurrentContext();
+
+ if (cx == &dummyContext) {
+ return NULL;
+ } else {
+ return cx;
+ }
+}
+
+PUBLIC GLXDrawable glXGetCurrentDrawable(void)
+{
+ GLXContext gc = __glXGetCurrentContext();
+ return gc->currentDrawable;
+}
+
+
+/************************************************************************/
+
+/**
+ * Sends a GLX protocol message to the specified display to make the context
+ * and the drawables current.
+ *
+ * \param dpy Display to send the message to.
+ * \param opcode Major opcode value for the display.
+ * \param gc_id Context tag for the context to be made current.
+ * \param draw Drawable ID for the "draw" drawable.
+ * \param read Drawable ID for the "read" drawable.
+ * \param reply Space to store the X-server's reply.
+ *
+ * \warning
+ * This function assumes that \c dpy is locked with \c LockDisplay on entry.
+ */
+static Bool SendMakeCurrentRequest(Display *dpy, CARD8 opcode,
+ GLXContextID gc_id, GLXContextTag gc_tag,
+ GLXDrawable draw, GLXDrawable read,
+ xGLXMakeCurrentReply *reply)
+{
+ Bool ret;
+
+
+ LockDisplay(dpy);
+
+ if (draw == read) {
+ xGLXMakeCurrentReq *req;
+
+ GetReq(GLXMakeCurrent,req);
+ req->reqType = opcode;
+ req->glxCode = X_GLXMakeCurrent;
+ req->drawable = draw;
+ req->context = gc_id;
+ req->oldContextTag = gc_tag;
+ }
+ else {
+ __GLXdisplayPrivate *priv = __glXInitialize(dpy);
+
+ /* If the server can support the GLX 1.3 version, we should
+ * perfer that. Not only that, some servers support GLX 1.3 but
+ * not the SGI extension.
+ */
+
+ if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
+ xGLXMakeContextCurrentReq *req;
+
+ GetReq(GLXMakeContextCurrent,req);
+ req->reqType = opcode;
+ req->glxCode = X_GLXMakeContextCurrent;
+ req->drawable = draw;
+ req->readdrawable = read;
+ req->context = gc_id;
+ req->oldContextTag = gc_tag;
+ }
+ else {
+ xGLXVendorPrivateWithReplyReq *vpreq;
+ xGLXMakeCurrentReadSGIReq *req;
+
+ GetReqExtra(GLXVendorPrivateWithReply,
+ sz_xGLXMakeCurrentReadSGIReq-sz_xGLXVendorPrivateWithReplyReq,vpreq);
+ req = (xGLXMakeCurrentReadSGIReq *)vpreq;
+ req->reqType = opcode;
+ req->glxCode = X_GLXVendorPrivateWithReply;
+ req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
+ req->drawable = draw;
+ req->readable = read;
+ req->context = gc_id;
+ req->oldContextTag = gc_tag;
+ }
+ }
+
+ ret = _XReply(dpy, (xReply*) reply, 0, False);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return ret;
+}
+
+
+#ifdef GLX_DIRECT_RENDERING
+static __GLXDRIdrawable *
+FetchDRIDrawable(Display *dpy,
+ GLXDrawable glxDrawable, GLXContext gc, Bool pre13)
+{
+ __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
+ __GLXDRIdrawable *pdraw;
+ __GLXscreenConfigs *psc;
+ XID drawable;
+
+ if (priv == NULL)
+ return NULL;
+
+ psc = &priv->screenConfigs[gc->screen];
+ if (psc->drawHash == NULL)
+ return NULL;
+
+ if (__glxHashLookup(psc->drawHash, glxDrawable, (void *) &pdraw) == 0)
+ return 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;
+ }
+
+ return pdraw;
+}
+#endif /* GLX_DIRECT_RENDERING */
+
+
+/**
+ * Make a particular context current.
+ *
+ * \note This is in this file so that it can access dummyContext.
+ */
+static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw,
+ GLXDrawable read, GLXContext gc,
+ Bool pre13)
+{
+ xGLXMakeCurrentReply reply;
+ const GLXContext oldGC = __glXGetCurrentContext();
+ const CARD8 opcode = __glXSetupForCommand(dpy);
+ const CARD8 oldOpcode = ((gc == oldGC) || (oldGC == &dummyContext))
+ ? opcode : __glXSetupForCommand(oldGC->currentDpy);
+ Bool bindReturnValue;
+
+
+ if (!opcode || !oldOpcode) {
+ return GL_FALSE;
+ }
+
+ /* Make sure that the new context has a nonzero ID. In the request,
+ * a zero context ID is used only to mean that we bind to no current
+ * context.
+ */
+ if ((gc != NULL) && (gc->xid == None)) {
+ return GL_FALSE;
+ }
+
+ _glapi_check_multithread();
+
+#ifdef GLX_DIRECT_RENDERING
+ /* Bind the direct rendering context to the drawable */
+ if (gc && gc->driContext) {
+ __GLXDRIdrawable *pdraw = FetchDRIDrawable(dpy, draw, gc, pre13);
+ __GLXDRIdrawable *pread = FetchDRIDrawable(dpy, read, gc, pre13);
+
+ bindReturnValue =
+ (gc->driContext->bindContext) (gc->driContext, pdraw, pread);
+ } else
+#endif
+ {
+ /* Send a glXMakeCurrent request to bind the new context. */
+ bindReturnValue =
+ SendMakeCurrentRequest(dpy, opcode, gc ? gc->xid : None,
+ ((dpy != oldGC->currentDpy) || oldGC->isDirect)
+ ? None : oldGC->currentContextTag,
+ draw, read, &reply);
+ }
+
+
+ if (!bindReturnValue) {
+ return False;
+ }
+
+#ifdef GLX_DIRECT_RENDERING
+ if ((dpy != oldGC->currentDpy || (gc && gc->driContext)) &&
+ !oldGC->isDirect && oldGC != &dummyContext) {
+#else
+ if ((dpy != oldGC->currentDpy) && oldGC != &dummyContext) {
+#endif
+ xGLXMakeCurrentReply dummy_reply;
+
+ /* We are either switching from one dpy to another and have to
+ * send a request to the previous dpy to unbind the previous
+ * context, or we are switching away from a indirect context to
+ * a direct context and have to send a request to the dpy to
+ * unbind the previous context.
+ */
+ (void) SendMakeCurrentRequest(oldGC->currentDpy, oldOpcode, None,
+ oldGC->currentContextTag, None, None,
+ & dummy_reply);
+ }
+#ifdef GLX_DIRECT_RENDERING
+ else if (oldGC->driContext) {
+ oldGC->driContext->unbindContext(oldGC->driContext);
+ }
+#endif
+
+
+ /* Update our notion of what is current */
+ __glXLock();
+ if (gc == oldGC) {
+ /* Even though the contexts are the same the drawable might have
+ * changed. Note that gc cannot be the dummy, and that oldGC
+ * cannot be NULL, therefore if they are the same, gc is not
+ * NULL and not the dummy.
+ */
+ gc->currentDrawable = draw;
+ gc->currentReadable = read;
+ } else {
+ if (oldGC != &dummyContext) {
+ /* Old current context is no longer current to anybody */
+ oldGC->currentDpy = 0;
+ oldGC->currentDrawable = None;
+ oldGC->currentReadable = None;
+ oldGC->currentContextTag = 0;
+
+ if (oldGC->xid == None) {
+ /* We are switching away from a context that was
+ * previously destroyed, so we need to free the memory
+ * for the old handle.
+ */
+#ifdef GLX_DIRECT_RENDERING
+ /* Destroy the old direct rendering context */
+ if (oldGC->driContext) {
+ oldGC->driContext->destroyContext(oldGC->driContext,
+ oldGC->psc,
+ oldGC->createDpy);
+ oldGC->driContext = NULL;
+ }
+#endif
+ __glXFreeContext(oldGC);
+ }
+ }
+ if (gc) {
+ __glXSetCurrentContext(gc);
+
+ gc->currentDpy = dpy;
+ gc->currentDrawable = draw;
+ gc->currentReadable = read;
+
+#ifdef GLX_DIRECT_RENDERING
+ if (!gc->driContext) {
+#endif
+ if (!IndirectAPI)
+ IndirectAPI = __glXNewIndirectAPI();
+ _glapi_set_dispatch(IndirectAPI);
+
+#ifdef GLX_USE_APPLEGL
+ do {
+ extern void XAppleDRIUseIndirectDispatch(void);
+ XAppleDRIUseIndirectDispatch();
+ } while (0);
+#endif
+
+ __GLXattribute *state =
+ (__GLXattribute *)(gc->client_state_private);
+
+ gc->currentContextTag = reply.contextTag;
+ if (state->array_state == NULL) {
+ (void) glGetString(GL_EXTENSIONS);
+ (void) glGetString(GL_VERSION);
+ __glXInitVertexArrayState(gc);
+ }
+#ifdef GLX_DIRECT_RENDERING
+ }
+ else {
+ gc->currentContextTag = -1;
+ }
+#endif
+ } else {
+ __glXSetCurrentContextNull();
+ }
+ }
+ __glXUnlock();
+ return GL_TRUE;
+}
+
+
+PUBLIC Bool glXMakeCurrent(Display *dpy, GLXDrawable draw, GLXContext 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, False), MakeContextCurrent)
+
+PUBLIC GLX_ALIAS(Bool, glXMakeContextCurrent,
+ (Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx),
+ (dpy, d, r, ctx, False), MakeContextCurrent)
diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c
index 6403cbd56d..c5322f6d93 100644
--- a/src/glx/x11/glxext.c
+++ b/src/glx/x11/glxext.c
@@ -44,57 +44,25 @@
*/
#include "glxclient.h"
-#include <stdio.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
-#include <X11/extensions/Xfixes.h>
-#include <X11/extensions/Xdamage.h>
-#include <assert.h>
-#include "indirect_init.h"
#include "glapi.h"
#include "glxextensions.h"
#include "glcontextmodes.h"
#include "glheader.h"
-#ifdef GLX_DIRECT_RENDERING
-#include <inttypes.h>
-#include <sys/mman.h>
-#include "xf86dri.h"
-#include "sarea.h"
-#include "dri_glx.h"
-#endif
-
#ifdef USE_XCB
#include <X11/Xlib-xcb.h>
#include <xcb/xcb.h>
#include <xcb/glx.h>
#endif
-#include <assert.h>
#ifdef DEBUG
void __glXDumpDrawBuffer(__GLXcontext *ctx);
#endif
#ifdef USE_SPARC_ASM
-/*
- * This is where our dispatch table's bounds are.
- * And the static mesa_init is taken directly from
- * Mesa's 'sparc.c' initializer.
- *
- * We need something like this here, because this version
- * of openGL/glx never initializes a Mesa context, and so
- * the address of the dispatch table pointer never gets stuffed
- * into the dispatch jump table otherwise.
- *
- * It matters only on SPARC, and only if you are using assembler
- * code instead of C-code indirect dispatch.
- *
- * -- FEM, 04.xii.03
- */
-extern unsigned int _mesa_sparc_glapi_begin;
-extern unsigned int _mesa_sparc_glapi_end;
-extern void __glapi_sparc_icache_flush(unsigned int *);
static void _glx_mesa_init_sparc_glapi_relocs(void);
static int _mesa_sparc_needs_init = 1;
#define INIT_MESA_SPARC { \
@@ -107,173 +75,11 @@ static int _mesa_sparc_needs_init = 1;
#define INIT_MESA_SPARC
#endif
-#ifdef GLX_DIRECT_RENDERING
-static __DRIscreen *__glXFindDRIScreen(__DRInativeDisplay *dpy, int scrn);
-#endif /* GLX_DIRECT_RENDERING */
-
-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.
-*/
-
-static GLubyte dummyBuffer[__GLX_BUFFER_LIMIT_SIZE];
-
-/*
-** Dummy context used by small commands when there is no current context.
-** All the
-** gl and glx entry points are designed to operate as nop's when using
-** the dummy context structure.
-*/
-static __GLXcontext dummyContext = {
- &dummyBuffer[0],
- &dummyBuffer[0],
- &dummyBuffer[0],
- &dummyBuffer[__GLX_BUFFER_LIMIT_SIZE],
- sizeof(dummyBuffer),
-};
-
-
-/*
-** All indirect rendering contexts will share the same indirect dispatch table.
-*/
-static __GLapi *IndirectAPI = NULL;
-
-
-/*
- * Current context management and locking
- */
-
-#if defined( USE_XTHREADS )
-
-/* thread safe */
-static GLboolean TSDinitialized = GL_FALSE;
-static xthread_key_t ContextTSD;
-
-__GLXcontext *__glXGetCurrentContext(void)
-{
- if (!TSDinitialized) {
- xthread_key_create(&ContextTSD, NULL);
- TSDinitialized = GL_TRUE;
- return &dummyContext;
- }
- else {
- void *p;
- xthread_get_specific(ContextTSD, &p);
- if (!p)
- return &dummyContext;
- else
- return (__GLXcontext *) p;
- }
-}
-
-void __glXSetCurrentContext(__GLXcontext *c)
-{
- if (!TSDinitialized) {
- xthread_key_create(&ContextTSD, NULL);
- TSDinitialized = GL_TRUE;
- }
- xthread_set_specific(ContextTSD, c);
-}
-
-
-/* Used by the __glXLock() and __glXUnlock() macros */
-xmutex_rec __glXmutex;
-
-#elif defined( PTHREADS )
-
-pthread_mutex_t __glXmutex = PTHREAD_MUTEX_INITIALIZER;
-
-# if defined( GLX_USE_TLS )
-
-/**
- * Per-thread GLX context pointer.
- *
- * \c __glXSetCurrentContext is written is such a way that this pointer can
- * \b never be \c NULL. This is important! Because of this
- * \c __glXGetCurrentContext can be implemented as trivial macro.
- */
-__thread void * __glX_tls_Context __attribute__((tls_model("initial-exec")))
- = &dummyContext;
-
-void __glXSetCurrentContext( __GLXcontext * c )
-{
- __glX_tls_Context = (c != NULL) ? c : &dummyContext;
-}
-
-# else
-
-static pthread_once_t once_control = PTHREAD_ONCE_INIT;
-
-/**
- * Per-thread data key.
- *
- * Once \c init_thread_data has been called, the per-thread data key will
- * take a value of \c NULL. As each new thread is created the default
- * value, in that thread, will be \c NULL.
- */
-static pthread_key_t ContextTSD;
-
-/**
- * Initialize the per-thread data key.
- *
- * This function is called \b exactly once per-process (not per-thread!) to
- * initialize the per-thread data key. This is ideally done using the
- * \c pthread_once mechanism.
- */
-static void init_thread_data( void )
-{
- if ( pthread_key_create( & ContextTSD, NULL ) != 0 ) {
- perror( "pthread_key_create" );
- exit( -1 );
- }
-}
-
-void __glXSetCurrentContext( __GLXcontext * c )
-{
- pthread_once( & once_control, init_thread_data );
- pthread_setspecific( ContextTSD, c );
-}
-
-__GLXcontext * __glXGetCurrentContext( void )
-{
- void * v;
-
- pthread_once( & once_control, init_thread_data );
-
- v = pthread_getspecific( ContextTSD );
- return (v == NULL) ? & dummyContext : (__GLXcontext *) v;
-}
-
-# endif /* defined( GLX_USE_TLS ) */
-
-#elif defined( THREADS )
-
-#error Unknown threading method specified.
-
-#else
-
-/* not thread safe */
-__GLXcontext *__glXcurrentContext = &dummyContext;
-
-#endif
-
-
/*
** You can set this cell to 1 to force the gl drawing stuff to be
** one command per packet
*/
-int __glXDebug = 0;
-
-/*
-** forward prototype declarations
-*/
-int __glXCloseDisplay(Display *dpy, XExtCodes *codes);
-
-
-/************************************************************************/
+_X_HIDDEN int __glXDebug = 0;
/* Extension required boiler plate */
@@ -296,16 +102,13 @@ static /* const */ char *error_list[] = {
"GLXBadWindow",
};
-int __glXCloseDisplay(Display *dpy, XExtCodes *codes)
+static int __glXCloseDisplay(Display *dpy, XExtCodes *codes)
{
GLXContext gc;
gc = __glXGetCurrentContext();
if (dpy == gc->currentDpy) {
- __glXSetCurrentContext(&dummyContext);
-#ifdef GLX_DIRECT_RENDERING
- _glapi_set_dispatch(NULL); /* no-op functions */
-#endif
+ __glXSetCurrentContextNull();
__glXFreeContext(gc);
}
@@ -352,22 +155,27 @@ static void FreeScreenConfigs(__GLXdisplayPrivate *priv)
for (i = 0; i < screens; i++, psc++) {
if (psc->configs) {
_gl_context_modes_destroy( psc->configs );
- if(psc->effectiveGLXexts)
+ if (psc->effectiveGLXexts)
Xfree(psc->effectiveGLXexts);
-
psc->configs = NULL; /* NOTE: just for paranoia */
}
- Xfree((char*) psc->serverGLXexts);
+ if (psc->visuals) {
+ _gl_context_modes_destroy( psc->visuals );
+ psc->visuals = NULL; /* NOTE: just for paranoia */
+ }
+ Xfree((char*) psc->serverGLXexts);
#ifdef GLX_DIRECT_RENDERING
- /* Free the direct rendering per screen data */
- if (psc->driScreen.private)
- (*psc->driScreen.destroyScreen)(priv->dpy, i,
- psc->driScreen.private);
- psc->driScreen.private = NULL;
+ if (psc->driScreen) {
+ psc->driScreen->destroyScreen(psc);
+ __glxHashDestroy(psc->drawHash);
+ XFree(psc->driScreen);
+ psc->driScreen = NULL;
+ }
#endif
}
XFree((char*) priv->screenConfigs);
+ priv->screenConfigs = NULL;
}
/*
@@ -391,14 +199,17 @@ static int __glXFreeDisplayPrivate(XExtData *extension)
#ifdef GLX_DIRECT_RENDERING
/* Free the direct rendering per display data */
- if (priv->driDisplay.private)
- (*priv->driDisplay.destroyDisplay)(priv->dpy,
- priv->driDisplay.private);
- priv->driDisplay.private = NULL;
- if (priv->driDisplay.createNewScreen) {
- Xfree(priv->driDisplay.createNewScreen); /* free array of ptrs */
- priv->driDisplay.createNewScreen = NULL;
- }
+ if (priv->driswDisplay)
+ (*priv->driswDisplay->destroyDisplay)(priv->driswDisplay);
+ priv->driswDisplay = NULL;
+
+ 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);
@@ -440,7 +251,7 @@ static Bool QueryVersion(Display *dpy, int opcode, int *major, int *minor)
}
-void
+_X_HIDDEN void
__glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count,
const INT32 *bp, Bool tagged_only,
Bool fbconfig_style_tags )
@@ -634,371 +445,128 @@ __glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count,
config->haveStencilBuffer = (config->stencilBits > 0);
}
-
-#ifdef GLX_DIRECT_RENDERING
-static unsigned
-filter_modes( __GLcontextModes ** server_modes,
- const __GLcontextModes * driver_modes )
+static __GLcontextModes *
+createConfigsFromProperties(Display *dpy, int nvisuals, int nprops,
+ int screen, GLboolean tagged_only)
{
- __GLcontextModes * m;
- __GLcontextModes ** prev_next;
- const __GLcontextModes * check;
- unsigned modes_count = 0;
-
- if ( driver_modes == NULL ) {
- fprintf(stderr, "libGL warning: 3D driver returned no fbconfigs.\n");
- return 0;
- }
-
- /* For each mode in server_modes, check to see if a matching mode exists
- * in driver_modes. If not, then the mode is not available.
- */
+ INT32 buf[__GLX_TOTAL_CONFIG], *props;
+ unsigned prop_size;
+ __GLcontextModes *modes, *m;
+ int i;
- prev_next = server_modes;
- for ( m = *prev_next ; m != NULL ; m = *prev_next ) {
- GLboolean do_delete = GL_TRUE;
+ if (nprops == 0)
+ return NULL;
- for ( check = driver_modes ; check != NULL ; check = check->next ) {
- if ( _gl_context_modes_are_same( m, check ) ) {
- do_delete = GL_FALSE;
- break;
- }
- }
+ /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */
- /* The 3D has to support all the modes that match the GLX visuals
- * sent from the X server.
- */
- if ( do_delete && (m->visualID != 0) ) {
- do_delete = GL_FALSE;
-
- if (getenv("LIBGL_DEBUG")) {
- fprintf(stderr, "libGL warning: 3D driver claims to not support "
- "visual 0x%02x\n", m->visualID);
- }
- }
+ /* Check number of properties */
+ if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS)
+ return NULL;
- if ( do_delete ) {
- *prev_next = m->next;
+ /* Allocate memory for our config structure */
+ modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes));
+ if (!modes)
+ return NULL;
- m->next = NULL;
- _gl_context_modes_destroy( m );
- }
- else {
- modes_count++;
- prev_next = & m->next;
- }
+ prop_size = nprops * __GLX_SIZE_INT32;
+ if (prop_size <= sizeof(buf))
+ props = buf;
+ else
+ props = Xmalloc(prop_size);
+
+ /* Read each config structure and convert it into our format */
+ m = modes;
+ for (i = 0; i < nvisuals; i++) {
+ _XRead(dpy, (char *)props, prop_size);
+ /* Older X servers don't send this so we default it here. */
+ m->drawableType = GLX_WINDOW_BIT;
+ __glXInitializeVisualConfigFromTags(m, nprops, props,
+ tagged_only, GL_TRUE);
+ m->screen = screen;
+ m = m->next;
}
- return modes_count;
-}
-
+ if (props != buf)
+ Xfree(props);
-/**
- * Implement \c __DRIinterfaceMethods::getProcAddress.
- */
-static __DRIfuncPtr get_proc_address( const char * proc_name )
-{
- if (strcmp( proc_name, "glxEnableExtension" ) == 0) {
- return (__DRIfuncPtr) __glXScrEnableExtension;
- }
-
- return NULL;
+ return modes;
}
-#ifdef XDAMAGE_1_1_INTERFACE
-static GLboolean has_damage_post(__DRInativeDisplay *dpy)
+static GLboolean
+getVisualConfigs(Display *dpy, __GLXdisplayPrivate *priv, int screen)
{
- static GLboolean inited = GL_FALSE;
- static GLboolean has_damage;
-
- if (!inited) {
- int major, minor;
-
- if (XDamageQueryVersion(dpy, &major, &minor) &&
- major == 1 && minor >= 1)
- {
- has_damage = GL_TRUE;
- } else {
- has_damage = GL_FALSE;
- }
- inited = GL_TRUE;
- }
+ xGLXGetVisualConfigsReq *req;
+ __GLXscreenConfigs *psc;
+ xGLXGetVisualConfigsReply reply;
+
+ LockDisplay(dpy);
- return has_damage;
-}
-#endif /* XDAMAGE_1_1_INTERFACE */
+ psc = priv->screenConfigs + screen;
+ psc->visuals = NULL;
+ GetReq(GLXGetVisualConfigs, req);
+ req->reqType = priv->majorOpcode;
+ req->glxCode = X_GLXGetVisualConfigs;
+ req->screen = screen;
-static void __glXReportDamage(__DRInativeDisplay *dpy, int screen,
- __DRIid drawable,
- int x, int y,
- drm_clip_rect_t *rects, int num_rects,
- GLboolean front_buffer)
-{
-#ifdef XDAMAGE_1_1_INTERFACE
- XRectangle *xrects;
- XserverRegion region;
- int i;
- int x_off, y_off;
-
- if (!has_damage_post(dpy))
- return;
-
- if (front_buffer) {
- x_off = x;
- y_off = y;
- drawable = RootWindow(dpy, screen);
- } else{
- x_off = 0;
- y_off = 0;
- }
+ if (!_XReply(dpy, (xReply*) &reply, 0, False))
+ goto out;
- xrects = malloc(sizeof(XRectangle) * num_rects);
- if (xrects == NULL)
- return;
+ psc->visuals = createConfigsFromProperties(dpy,
+ reply.numVisuals,
+ reply.numProps,
+ screen, GL_FALSE);
- for (i = 0; i < num_rects; i++) {
- xrects[i].x = rects[i].x1 + x_off;
- xrects[i].y = rects[i].y1 + y_off;
- xrects[i].width = rects[i].x2 - rects[i].x1;
- xrects[i].height = rects[i].y2 - rects[i].y1;
- }
- region = XFixesCreateRegion(dpy, xrects, num_rects);
- free(xrects);
- XDamageAdd(dpy, drawable, region);
- XFixesDestroyRegion(dpy, region);
-#endif
+ out:
+ UnlockDisplay(dpy);
+ return psc->visuals != NULL;
}
-/**
- * Table of functions exported by the loader to the driver.
- */
-static const __DRIinterfaceMethods interface_methods = {
- get_proc_address,
-
- _gl_context_modes_create,
- _gl_context_modes_destroy,
-
- __glXFindDRIScreen,
- __glXWindowExists,
-
- XF86DRICreateContextWithConfig,
- XF86DRIDestroyContext,
-
- XF86DRICreateDrawable,
- XF86DRIDestroyDrawable,
- XF86DRIGetDrawableInfo,
-
- __glXGetUST,
- __glXGetMscRateOML,
-
- __glXReportDamage,
-};
-
-
-
-/**
- * Perform the required libGL-side initialization and call the client-side
- * driver's \c __driCreateNewScreen function.
- *
- * \param dpy Display pointer.
- * \param scrn Screen number on the display.
- * \param psc DRI screen information.
- * \param driDpy DRI display information.
- * \param createNewScreen Pointer to the client-side driver's
- * \c __driCreateNewScreen function.
- * \returns A pointer to the \c __DRIscreenPrivate structure returned by
- * the client-side driver on success, or \c NULL on failure.
- *
- * \todo This function needs to be modified to remove context-modes from the
- * list stored in the \c __GLXscreenConfigsRec to match the list
- * returned by the client-side driver.
- */
-static void *
-CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc,
- __DRIdisplay * driDpy,
- PFNCREATENEWSCREENFUNC createNewScreen)
+static GLboolean
+getFBConfigs(Display *dpy, __GLXdisplayPrivate *priv, int screen)
{
- __DRIscreenPrivate *psp = NULL;
-#ifndef GLX_USE_APPLEGL
- drm_handle_t hSAREA;
- drmAddress pSAREA = MAP_FAILED;
- char *BusID;
- __DRIversion ddx_version;
- __DRIversion dri_version;
- __DRIversion drm_version;
- __DRIframebuffer framebuffer;
- int fd = -1;
- int status;
- const char * err_msg;
- const char * err_extra;
- int api_ver = __glXGetInternalVersion();
-
-
- dri_version.major = driDpy->private->driMajor;
- dri_version.minor = driDpy->private->driMinor;
- dri_version.patch = driDpy->private->driPatch;
-
-
- err_msg = "XF86DRIOpenConnection";
- err_extra = NULL;
-
- framebuffer.base = MAP_FAILED;
- framebuffer.dev_priv = NULL;
-
- if (XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
- int newlyopened;
- fd = drmOpenOnce(NULL,BusID, &newlyopened);
- Xfree(BusID); /* No longer needed */
-
- err_msg = "open DRM";
- err_extra = strerror( -fd );
-
- if (fd >= 0) {
- drm_magic_t magic;
-
- err_msg = "drmGetMagic";
- err_extra = NULL;
-
- if (!drmGetMagic(fd, &magic)) {
- drmVersionPtr version = drmGetVersion(fd);
- if (version) {
- drm_version.major = version->version_major;
- drm_version.minor = version->version_minor;
- drm_version.patch = version->version_patchlevel;
- drmFreeVersion(version);
- }
- else {
- drm_version.major = -1;
- drm_version.minor = -1;
- drm_version.patch = -1;
- }
-
- err_msg = "XF86DRIAuthConnection";
- if (!newlyopened || XF86DRIAuthConnection(dpy, scrn, magic)) {
- char *driverName;
-
- /*
- * Get device name (like "tdfx") and the ddx version
- * numbers. We'll check the version in each DRI driver's
- * "createNewScreen" function.
- */
- err_msg = "XF86DRIGetClientDriverName";
- if (XF86DRIGetClientDriverName(dpy, scrn,
- &ddx_version.major,
- &ddx_version.minor,
- &ddx_version.patch,
- &driverName)) {
- drm_handle_t hFB;
- int junk;
-
- /* No longer needed. */
- Xfree( driverName );
-
-
- /*
- * Get device-specific info. pDevPriv will point to a struct
- * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h)
- * that has information about the screen size, depth, pitch,
- * ancilliary buffers, DRM mmap handles, etc.
- */
- err_msg = "XF86DRIGetDeviceInfo";
- if (XF86DRIGetDeviceInfo(dpy, scrn,
- &hFB,
- &junk,
- &framebuffer.size,
- &framebuffer.stride,
- &framebuffer.dev_priv_size,
- &framebuffer.dev_priv)) {
- framebuffer.width = DisplayWidth(dpy, scrn);
- framebuffer.height = DisplayHeight(dpy, scrn);
-
- /*
- * Map the framebuffer region.
- */
- status = drmMap(fd, hFB, framebuffer.size,
- (drmAddressPtr)&framebuffer.base);
-
- err_msg = "drmMap of framebuffer";
- err_extra = strerror( -status );
-
- if ( status == 0 ) {
- /*
- * Map the SAREA region. Further mmap regions
- * may be setup in each DRI driver's
- * "createNewScreen" function.
- */
- status = drmMap(fd, hSAREA, SAREA_MAX,
- &pSAREA);
-
- err_msg = "drmMap of sarea";
- err_extra = strerror( -status );
-
- if ( status == 0 ) {
- __GLcontextModes * driver_modes = NULL;
- __GLXscreenConfigs *configs = psc->screenConfigs;
-
- err_msg = "InitDriver";
- err_extra = NULL;
- psp = (*createNewScreen)(dpy, scrn,
- psc,
- configs->configs,
- & ddx_version,
- & dri_version,
- & drm_version,
- & framebuffer,
- pSAREA,
- fd,
- api_ver,
- & interface_methods,
- & driver_modes );
-
- filter_modes( & configs->configs,
- driver_modes );
- _gl_context_modes_destroy( driver_modes );
- }
- }
- }
- }
- }
- }
- }
- }
-
- if ( psp == NULL ) {
- if ( pSAREA != MAP_FAILED ) {
- (void)drmUnmap(pSAREA, SAREA_MAX);
- }
-
- if ( framebuffer.base != MAP_FAILED ) {
- (void)drmUnmap((drmAddress)framebuffer.base, framebuffer.size);
- }
+ xGLXGetFBConfigsReq *fb_req;
+ xGLXGetFBConfigsSGIXReq *sgi_req;
+ xGLXVendorPrivateWithReplyReq *vpreq;
+ xGLXGetFBConfigsReply reply;
+ __GLXscreenConfigs *psc;
- if ( framebuffer.dev_priv != NULL ) {
- Xfree(framebuffer.dev_priv);
- }
+ psc = priv->screenConfigs + screen;
+ psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode,
+ X_GLXQueryServerString,
+ screen, GLX_EXTENSIONS);
- if ( fd >= 0 ) {
- (void)drmCloseOnce(fd);
- }
+ LockDisplay(dpy);
- (void)XF86DRICloseConnection(dpy, scrn);
+ psc->configs = NULL;
+ if (atof(priv->serverGLXversion) >= 1.3) {
+ GetReq(GLXGetFBConfigs, fb_req);
+ fb_req->reqType = priv->majorOpcode;
+ fb_req->glxCode = X_GLXGetFBConfigs;
+ fb_req->screen = screen;
+ } else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) {
+ GetReqExtra(GLXVendorPrivateWithReply,
+ sz_xGLXGetFBConfigsSGIXReq +
+ sz_xGLXVendorPrivateWithReplyReq, vpreq);
+ sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
+ sgi_req->reqType = priv->majorOpcode;
+ sgi_req->glxCode = X_GLXVendorPrivateWithReply;
+ sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
+ sgi_req->screen = screen;
+ } else
+ goto out;
- if ( err_extra != NULL ) {
- fprintf(stderr, "libGL error: %s failed (%s)\n", err_msg,
- err_extra);
- }
- else {
- fprintf(stderr, "libGL error: %s failed\n", err_msg );
- }
+ if (!_XReply(dpy, (xReply*) &reply, 0, False))
+ goto out;
- fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n");
- }
-#endif /* !GLX_USE_APPLEGL */
+ psc->configs = createConfigsFromProperties(dpy,
+ reply.numFBConfigs,
+ reply.numAttribs * 2,
+ screen, GL_TRUE);
- return psp;
+ out:
+ UnlockDisplay(dpy);
+ return psc->configs != NULL;
}
-#endif /* GLX_DIRECT_RENDERING */
-
/*
** Allocate the memory for the per screen configs for each screen.
@@ -1006,17 +574,8 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc,
*/
static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
{
- xGLXGetVisualConfigsReq *req;
- xGLXGetFBConfigsReq *fb_req;
- xGLXVendorPrivateWithReplyReq *vpreq;
- xGLXGetFBConfigsSGIXReq *sgi_req;
- xGLXGetVisualConfigsReply reply;
__GLXscreenConfigs *psc;
- __GLcontextModes *config;
- GLint i, j, nprops, screens;
- INT32 buf[__GLX_TOTAL_CONFIG], *props;
- unsigned supported_request = 0;
- unsigned prop_size;
+ GLint i, screens;
/*
** First allocate memory for the array of per screen configs.
@@ -1030,159 +589,36 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
priv->screenConfigs = psc;
priv->serverGLXversion = __glXGetStringFromServer(dpy, priv->majorOpcode,
- X_GLXQueryServerString,
- 0, GLX_VERSION);
+ X_GLXQueryServerString,
+ 0, GLX_VERSION);
if ( priv->serverGLXversion == NULL ) {
FreeScreenConfigs(priv);
return GL_FALSE;
}
- if ( atof( priv->serverGLXversion ) >= 1.3 ) {
- supported_request = 1;
- }
-
- /*
- ** Now fetch each screens configs structures. If a screen supports
- ** GL (by returning a numVisuals > 0) then allocate memory for our
- ** config structure and then fill it in.
- */
for (i = 0; i < screens; i++, psc++) {
- if ( supported_request != 1 ) {
- psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode,
- X_GLXQueryServerString,
- i, GLX_EXTENSIONS);
- if ( strstr( psc->serverGLXexts, "GLX_SGIX_fbconfig" ) != NULL ) {
- supported_request = 2;
- }
- else {
- supported_request = 3;
- }
- }
-
+ getVisualConfigs(dpy, priv, i);
+ getFBConfigs(dpy, priv, i);
- LockDisplay(dpy);
- switch( supported_request ) {
- case 1:
- GetReq(GLXGetFBConfigs,fb_req);
- fb_req->reqType = priv->majorOpcode;
- fb_req->glxCode = X_GLXGetFBConfigs;
- fb_req->screen = i;
- break;
-
- case 2:
- GetReqExtra(GLXVendorPrivateWithReply,
- sz_xGLXGetFBConfigsSGIXReq-sz_xGLXVendorPrivateWithReplyReq,vpreq);
- sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
- sgi_req->reqType = priv->majorOpcode;
- sgi_req->glxCode = X_GLXVendorPrivateWithReply;
- sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
- sgi_req->screen = i;
- break;
-
- case 3:
- GetReq(GLXGetVisualConfigs,req);
- req->reqType = priv->majorOpcode;
- req->glxCode = X_GLXGetVisualConfigs;
- req->screen = i;
- break;
- }
-
- if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
- /* Something is busted. Punt. */
- UnlockDisplay(dpy);
- SyncHandle();
- FreeScreenConfigs(priv);
- return GL_FALSE;
- }
-
- if (!reply.numVisuals) {
- /* This screen does not support GL rendering */
- UnlockDisplay(dpy);
+#ifdef GLX_DIRECT_RENDERING
+ psc->scr = i;
+ psc->dpy = dpy;
+ psc->drawHash = __glxHashCreate();
+ if (psc->drawHash == NULL)
continue;
- }
- /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for
- * FIXME: FBconfigs?
- */
- /* Check number of properties */
- nprops = reply.numProps;
- if ((nprops < __GLX_MIN_CONFIG_PROPS) ||
- (nprops > __GLX_MAX_CONFIG_PROPS)) {
- /* Huh? Not in protocol defined limits. Punt */
- UnlockDisplay(dpy);
- SyncHandle();
- FreeScreenConfigs(priv);
- return GL_FALSE;
- }
+ if (priv->dri2Display)
+ psc->driScreen = (*priv->dri2Display->createScreen)(psc, i, priv);
- /* Allocate memory for our config structure */
- psc->configs = _gl_context_modes_create(reply.numVisuals,
- sizeof(__GLcontextModes));
- if (!psc->configs) {
- UnlockDisplay(dpy);
- SyncHandle();
- FreeScreenConfigs(priv);
- return GL_FALSE;
- }
+ if (psc->driScreen == NULL && priv->driDisplay)
+ psc->driScreen = (*priv->driDisplay->createScreen)(psc, i, priv);
- /* Allocate memory for the properties, if needed */
- if ( supported_request != 3 ) {
- nprops *= 2;
- }
+ if (psc->driScreen == NULL && priv->driswDisplay)
+ psc->driScreen = (*priv->driswDisplay->createScreen)(psc, i, priv);
- prop_size = nprops * __GLX_SIZE_INT32;
-
- if (prop_size <= sizeof(buf)) {
- props = buf;
- } else {
- props = (INT32 *) Xmalloc(prop_size);
- }
-
- /* Read each config structure and convert it into our format */
- config = psc->configs;
- for (j = 0; j < reply.numVisuals; j++) {
- assert( config != NULL );
- _XRead(dpy, (char *)props, prop_size);
-
- if ( supported_request != 3 ) {
- config->rgbMode = GL_TRUE;
- config->drawableType = GLX_WINDOW_BIT;
- }
- else {
- config->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
- }
-
- __glXInitializeVisualConfigFromTags( config, nprops, props,
- (supported_request != 3),
- GL_TRUE );
- if ( config->fbconfigID == GLX_DONT_CARE ) {
- config->fbconfigID = config->visualID;
- }
- config->screen = i;
- config = config->next;
- }
- if (props != buf) {
- Xfree((char *)props);
- }
- UnlockDisplay(dpy);
-
-#ifdef GLX_DIRECT_RENDERING
- /* Initialize per screen dynamic client GLX extensions */
- psc->ext_list_first_time = GL_TRUE;
- /* Initialize the direct rendering per screen data and functions */
- if (priv->driDisplay.private != NULL) {
- /* FIXME: Should it be some sort of an error if createNewScreen[i]
- * FIXME: is NULL?
- */
- if (priv->driDisplay.createNewScreen &&
- priv->driDisplay.createNewScreen[i]) {
-
- psc->driScreen.screenConfigs = (void *)psc;
- psc->driScreen.private =
- CallCreateNewScreen(dpy, i, & psc->driScreen,
- & priv->driDisplay,
- priv->driDisplay.createNewScreen[i] );
- }
+ if (psc->driScreen == NULL) {
+ __glxHashDestroy(psc->drawHash);
+ psc->drawHash = NULL;
}
#endif
}
@@ -1193,13 +629,16 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
/*
** Initialize the client side extension code.
*/
-__GLXdisplayPrivate *__glXInitialize(Display* dpy)
+_X_HIDDEN __GLXdisplayPrivate *__glXInitialize(Display* dpy)
{
XExtDisplayInfo *info = __glXFindDisplay(dpy);
XExtData **privList, *private, *found;
__GLXdisplayPrivate *dpyPriv;
XEDataObject dataObj;
int major, minor;
+#ifdef GLX_DIRECT_RENDERING
+ Bool glx_direct, glx_accel;
+#endif
#if defined(USE_XTHREADS)
{
@@ -1267,15 +706,20 @@ __GLXdisplayPrivate *__glXInitialize(Display* dpy)
dpyPriv->serverGLXversion = 0x0;
#ifdef GLX_DIRECT_RENDERING
+ glx_direct = (getenv("LIBGL_ALWAYS_INDIRECT") == NULL);
+ glx_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL);
+
/*
** Initialize the direct rendering per display data and functions.
** Note: This _must_ be done before calling any other DRI routines
** (e.g., those called in AllocAndFetchScreenConfigs).
*/
- if (getenv("LIBGL_ALWAYS_INDIRECT") == NULL) {
- dpyPriv->driDisplay.private =
- driCreateDisplay(dpy, &dpyPriv->driDisplay);
+ if (glx_direct && glx_accel) {
+ dpyPriv->dri2Display = dri2CreateDisplay(dpy);
+ dpyPriv->driDisplay = driCreateDisplay(dpy);
}
+ if (glx_direct)
+ dpyPriv->driswDisplay = driswCreateDisplay(dpy);
#endif
if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) {
@@ -1308,7 +752,7 @@ __GLXdisplayPrivate *__glXInitialize(Display* dpy)
** Setup for sending a GLX command on dpy. Make sure the extension is
** initialized. Try to avoid calling __glXInitialize as its kinda slow.
*/
-CARD8 __glXSetupForCommand(Display *dpy)
+_X_HIDDEN CARD8 __glXSetupForCommand(Display *dpy)
{
GLXContext gc;
__GLXdisplayPrivate *priv;
@@ -1349,7 +793,7 @@ CARD8 __glXSetupForCommand(Display *dpy)
* Modify this function to use \c ctx->pc instead of the explicit
* \c pc parameter.
*/
-GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc)
+_X_HIDDEN GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc)
{
Display * const dpy = ctx->currentDpy;
#ifdef USE_XCB
@@ -1361,7 +805,8 @@ GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc)
if ( (dpy != NULL) && (size > 0) ) {
#ifdef USE_XCB
- xcb_glx_render(c, ctx->currentContextTag, size, (char *)ctx->buf);
+ xcb_glx_render(c, ctx->currentContextTag, size,
+ (const uint8_t *)ctx->buf);
#else
/* Send the entire buffer as an X request */
LockDisplay(dpy);
@@ -1398,9 +843,9 @@ GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc)
* \param data Command data.
* \param dataLen Size, in bytes, of the command data.
*/
-void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber,
- GLint totalRequests,
- const GLvoid * data, GLint dataLen)
+_X_HIDDEN void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber,
+ GLint totalRequests,
+ const GLvoid * data, GLint dataLen)
{
Display *dpy = gc->currentDpy;
#ifdef USE_XCB
@@ -1446,9 +891,9 @@ void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber,
* \param data Command data.
* \param dataLen Size, in bytes, of the command data.
*/
-void __glXSendLargeCommand(__GLXcontext *ctx,
- const GLvoid *header, GLint headerLen,
- const GLvoid *data, GLint dataLen)
+_X_HIDDEN void __glXSendLargeCommand(__GLXcontext *ctx,
+ const GLvoid *header, GLint headerLen,
+ const GLvoid *data, GLint dataLen)
{
GLint maxSize;
GLint totalRequests, requestNumber;
@@ -1484,330 +929,8 @@ void __glXSendLargeCommand(__GLXcontext *ctx,
/************************************************************************/
-PUBLIC GLXContext glXGetCurrentContext(void)
-{
- GLXContext cx = __glXGetCurrentContext();
-
- if (cx == &dummyContext) {
- return NULL;
- } else {
- return cx;
- }
-}
-
-PUBLIC GLXDrawable glXGetCurrentDrawable(void)
-{
- GLXContext gc = __glXGetCurrentContext();
- return gc->currentDrawable;
-}
-
-
-/************************************************************************/
-
-#ifdef GLX_DIRECT_RENDERING
-/* Return the DRI per screen structure */
-__DRIscreen *__glXFindDRIScreen(__DRInativeDisplay *dpy, int scrn)
-{
- __DRIscreen *pDRIScreen = NULL;
- XExtDisplayInfo *info = __glXFindDisplay(dpy);
- XExtData **privList, *found;
- __GLXdisplayPrivate *dpyPriv;
- XEDataObject dataObj;
-
- __glXLock();
- dataObj.display = dpy;
- privList = XEHeadOfExtensionList(dataObj);
- found = XFindOnExtensionList(privList, info->codes->extension);
- __glXUnlock();
-
- if (found) {
- dpyPriv = (__GLXdisplayPrivate *)found->private_data;
- pDRIScreen = &dpyPriv->screenConfigs[scrn].driScreen;
- }
-
- return pDRIScreen;
-}
-#endif
-
-/************************************************************************/
-
-static Bool SendMakeCurrentRequest( Display *dpy, CARD8 opcode,
- GLXContextID gc, GLXContextTag old_gc, GLXDrawable draw, GLXDrawable read,
- xGLXMakeCurrentReply * reply );
-
-/**
- * Sends a GLX protocol message to the specified display to make the context
- * and the drawables current.
- *
- * \param dpy Display to send the message to.
- * \param opcode Major opcode value for the display.
- * \param gc_id Context tag for the context to be made current.
- * \param draw Drawable ID for the "draw" drawable.
- * \param read Drawable ID for the "read" drawable.
- * \param reply Space to store the X-server's reply.
- *
- * \warning
- * This function assumes that \c dpy is locked with \c LockDisplay on entry.
- */
-static Bool SendMakeCurrentRequest(Display *dpy, CARD8 opcode,
- GLXContextID gc_id, GLXContextTag gc_tag,
- GLXDrawable draw, GLXDrawable read,
- xGLXMakeCurrentReply *reply)
-{
- Bool ret;
-
-
- LockDisplay(dpy);
-
- if (draw == read) {
- xGLXMakeCurrentReq *req;
-
- GetReq(GLXMakeCurrent,req);
- req->reqType = opcode;
- req->glxCode = X_GLXMakeCurrent;
- req->drawable = draw;
- req->context = gc_id;
- req->oldContextTag = gc_tag;
- }
- else {
- __GLXdisplayPrivate *priv = __glXInitialize(dpy);
-
- /* If the server can support the GLX 1.3 version, we should
- * perfer that. Not only that, some servers support GLX 1.3 but
- * not the SGI extension.
- */
-
- if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
- xGLXMakeContextCurrentReq *req;
-
- GetReq(GLXMakeContextCurrent,req);
- req->reqType = opcode;
- req->glxCode = X_GLXMakeContextCurrent;
- req->drawable = draw;
- req->readdrawable = read;
- req->context = gc_id;
- req->oldContextTag = gc_tag;
- }
- else {
- xGLXVendorPrivateWithReplyReq *vpreq;
- xGLXMakeCurrentReadSGIReq *req;
-
- GetReqExtra(GLXVendorPrivateWithReply,
- sz_xGLXMakeCurrentReadSGIReq-sz_xGLXVendorPrivateWithReplyReq,vpreq);
- req = (xGLXMakeCurrentReadSGIReq *)vpreq;
- req->reqType = opcode;
- req->glxCode = X_GLXVendorPrivateWithReply;
- req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
- req->drawable = draw;
- req->readable = read;
- req->context = gc_id;
- req->oldContextTag = gc_tag;
- }
- }
-
- ret = _XReply(dpy, (xReply*) reply, 0, False);
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- return ret;
-}
-
-
-#ifdef GLX_DIRECT_RENDERING
-static Bool BindContextWrapper( Display *dpy, GLXContext gc,
- GLXDrawable draw, GLXDrawable read )
-{
- return (*gc->driContext.bindContext)(dpy, gc->screen, draw, read,
- & gc->driContext);
-}
-
-
-static Bool UnbindContextWrapper( GLXContext gc )
-{
- return (*gc->driContext.unbindContext)(gc->currentDpy, gc->screen,
- gc->currentDrawable,
- gc->currentReadable,
- & gc->driContext );
-}
-#endif /* GLX_DIRECT_RENDERING */
-
-
-/**
- * Make a particular context current.
- *
- * \note This is in this file so that it can access dummyContext.
- */
-USED static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw,
- GLXDrawable read, GLXContext gc)
-{
- xGLXMakeCurrentReply reply;
- const GLXContext oldGC = __glXGetCurrentContext();
- const CARD8 opcode = __glXSetupForCommand(dpy);
- const CARD8 oldOpcode = ((gc == oldGC) || (oldGC == &dummyContext))
- ? opcode : __glXSetupForCommand(oldGC->currentDpy);
- Bool bindReturnValue;
-
-
- if (!opcode || !oldOpcode) {
- return GL_FALSE;
- }
-
- /* Make sure that the new context has a nonzero ID. In the request,
- * a zero context ID is used only to mean that we bind to no current
- * context.
- */
- if ((gc != NULL) && (gc->xid == None)) {
- return GL_FALSE;
- }
-
-#ifndef GLX_DIRECT_RENDERING
- if (gc && gc->isDirect) {
- return GL_FALSE;
- }
-#endif
-
- _glapi_check_multithread();
-
-#ifdef GLX_DIRECT_RENDERING
- /* Bind the direct rendering context to the drawable */
- if (gc && gc->isDirect) {
- bindReturnValue = (gc->driContext.private)
- ? BindContextWrapper(dpy, gc, draw, read)
- : False;
- } else
-#endif
- {
- /* Send a glXMakeCurrent request to bind the new context. */
- bindReturnValue =
- SendMakeCurrentRequest(dpy, opcode, gc ? gc->xid : None,
- ((dpy != oldGC->currentDpy) || oldGC->isDirect)
- ? None : oldGC->currentContextTag,
- draw, read, &reply);
- }
-
-
- if (!bindReturnValue) {
- return False;
- }
-
- if ((dpy != oldGC->currentDpy || (gc && gc->isDirect)) &&
- !oldGC->isDirect && oldGC != &dummyContext) {
- xGLXMakeCurrentReply dummy_reply;
-
- /* We are either switching from one dpy to another and have to
- * send a request to the previous dpy to unbind the previous
- * context, or we are switching away from a indirect context to
- * a direct context and have to send a request to the dpy to
- * unbind the previous context.
- */
- (void) SendMakeCurrentRequest(oldGC->currentDpy, oldOpcode, None,
- oldGC->currentContextTag, None, None,
- & dummy_reply);
- }
-#ifdef GLX_DIRECT_RENDERING
- else if (oldGC->isDirect && oldGC->driContext.private) {
- (void) UnbindContextWrapper(oldGC);
- }
-#endif
-
-
- /* Update our notion of what is current */
- __glXLock();
- if (gc == oldGC) {
- /* Even though the contexts are the same the drawable might have
- * changed. Note that gc cannot be the dummy, and that oldGC
- * cannot be NULL, therefore if they are the same, gc is not
- * NULL and not the dummy.
- */
- gc->currentDrawable = draw;
- gc->currentReadable = read;
- } else {
- if (oldGC != &dummyContext) {
- /* Old current context is no longer current to anybody */
- oldGC->currentDpy = 0;
- oldGC->currentDrawable = None;
- oldGC->currentReadable = None;
- oldGC->currentContextTag = 0;
-
- if (oldGC->xid == None) {
- /* We are switching away from a context that was
- * previously destroyed, so we need to free the memory
- * for the old handle.
- */
-#ifdef GLX_DIRECT_RENDERING
- /* Destroy the old direct rendering context */
- if (oldGC->isDirect) {
- if (oldGC->driContext.private) {
- (*oldGC->driContext.destroyContext)
- (dpy, oldGC->screen, oldGC->driContext.private);
- oldGC->driContext.private = NULL;
- }
- }
-#endif
- __glXFreeContext(oldGC);
- }
- }
- if (gc) {
- __glXSetCurrentContext(gc);
-
- gc->currentDpy = dpy;
- gc->currentDrawable = draw;
- gc->currentReadable = read;
-
- if (!gc->isDirect) {
- if (!IndirectAPI)
- IndirectAPI = __glXNewIndirectAPI();
- _glapi_set_dispatch(IndirectAPI);
-
-#ifdef GLX_USE_APPLEGL
- do {
- extern void XAppleDRIUseIndirectDispatch(void);
- XAppleDRIUseIndirectDispatch();
- } while (0);
-#endif
-
- __GLXattribute *state =
- (__GLXattribute *)(gc->client_state_private);
-
- gc->currentContextTag = reply.contextTag;
- if (state->array_state == NULL) {
- (void) glGetString(GL_EXTENSIONS);
- (void) glGetString(GL_VERSION);
- __glXInitVertexArrayState(gc);
- }
- }
- else {
- gc->currentContextTag = -1;
- }
- } else {
- __glXSetCurrentContext(&dummyContext);
-#ifdef GLX_DIRECT_RENDERING
- _glapi_set_dispatch(NULL); /* no-op functions */
-#endif
- }
- }
- __glXUnlock();
- return GL_TRUE;
-}
-
-
-PUBLIC Bool glXMakeCurrent(Display *dpy, GLXDrawable draw, GLXContext gc)
-{
- return MakeContextCurrent( dpy, draw, draw, gc );
-}
-
-PUBLIC GLX_ALIAS(Bool, glXMakeCurrentReadSGI,
- (Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx),
- (dpy, d, r, ctx), MakeContextCurrent)
-
-PUBLIC GLX_ALIAS(Bool, glXMakeContextCurrent,
- (Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx),
- (dpy, d, r, ctx), MakeContextCurrent)
-
-
#ifdef DEBUG
-void __glXDumpDrawBuffer(__GLXcontext *ctx)
+_X_HIDDEN void __glXDumpDrawBuffer(__GLXcontext *ctx)
{
GLubyte *p = ctx->buf;
GLubyte *end = ctx->pc;
@@ -1832,9 +955,23 @@ void __glXDumpDrawBuffer(__GLXcontext *ctx)
#ifdef USE_SPARC_ASM
/*
- * Used only when we are sparc, using sparc assembler.
+ * This is where our dispatch table's bounds are.
+ * And the static mesa_init is taken directly from
+ * Mesa's 'sparc.c' initializer.
*
+ * We need something like this here, because this version
+ * of openGL/glx never initializes a Mesa context, and so
+ * the address of the dispatch table pointer never gets stuffed
+ * into the dispatch jump table otherwise.
+ *
+ * It matters only on SPARC, and only if you are using assembler
+ * code instead of C-code indirect dispatch.
+ *
+ * -- FEM, 04.xii.03
*/
+extern unsigned int _mesa_sparc_glapi_begin;
+extern unsigned int _mesa_sparc_glapi_end;
+extern void __glapi_sparc_icache_flush(unsigned int *);
static void
_glx_mesa_init_sparc_glapi_relocs(void)
diff --git a/src/glx/x11/glxextensions.c b/src/glx/x11/glxextensions.c
index 1d99b61db0..e843718472 100644
--- a/src/glx/x11/glxextensions.c
+++ b/src/glx/x11/glxextensions.c
@@ -356,28 +356,15 @@ __glXProcessServerString( const struct extension_info * ext,
}
}
-
-/**
- * Enable a named GLX extension on a given screen.
- * Drivers should not call this function directly. They should instead use
- * \c glXGetProcAddress to obtain a pointer to the function.
- *
- * \param psc Pointer to GLX per-screen record.
- * \param name Name of the extension to enable.
- *
- * \sa glXGetProcAddress
- *
- * \since Internal API version 20030813.
- */
void
-__glXScrEnableExtension( __GLXscreenConfigs *psc, const char * name )
+__glXEnableDirectExtension(__GLXscreenConfigs *psc, const char *name)
{
- __glXExtensionsCtr();
- __glXExtensionsCtrScreen(psc);
- set_glx_extension( known_glx_extensions, name, strlen( name ), GL_TRUE,
- psc->direct_support );
-}
+ __glXExtensionsCtr();
+ __glXExtensionsCtrScreen(psc);
+ set_glx_extension(known_glx_extensions,
+ name, strlen(name), GL_TRUE, psc->direct_support);
+}
/**
* Initialize global extension support tables.
diff --git a/src/glx/x11/glxextensions.h b/src/glx/x11/glxextensions.h
index a4241b6b7f..b99cebbdfa 100644
--- a/src/glx/x11/glxextensions.h
+++ b/src/glx/x11/glxextensions.h
@@ -234,7 +234,7 @@ extern GLboolean __glXExtensionBitIsEnabled( struct __GLXscreenConfigsRec *psc,
extern const char * __glXGetClientExtensions( void );
extern void __glXCalculateUsableExtensions( struct __GLXscreenConfigsRec *psc,
GLboolean display_is_direct_capable, int server_minor_version );
-extern void __glXScrEnableExtension( struct __GLXscreenConfigsRec *psc, const char * name );
+
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 );
@@ -243,6 +243,8 @@ extern char * __glXGetClientGLExtensionString( void );
extern GLboolean __glExtensionBitIsEnabled( const struct __GLXcontextRec * gc,
unsigned bit );
+extern void
+__glXEnableDirectExtension(struct __GLXscreenConfigsRec *psc, const char *name);
/* Source-level backwards compatibility with old drivers. They won't
* find the respective functions, though.
diff --git a/src/glx/x11/glxhash.c b/src/glx/x11/glxhash.c
new file mode 100644
index 0000000000..b7b8fb2738
--- /dev/null
+++ b/src/glx/x11/glxhash.c
@@ -0,0 +1,414 @@
+/* glxhash.c -- Small hash table support for integer -> integer mapping
+ * Taken from libdrm.
+ *
+ * Created: Sun Apr 18 09:35:45 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
+ *
+ * DESCRIPTION
+ *
+ * This file contains a straightforward implementation of a fixed-sized
+ * hash table using self-organizing linked lists [Knuth73, pp. 398-399] for
+ * collision resolution. There are two potentially interesting things
+ * about this implementation:
+ *
+ * 1) The table is power-of-two sized. Prime sized tables are more
+ * traditional, but do not have a significant advantage over power-of-two
+ * sized table, especially when double hashing is not used for collision
+ * resolution.
+ *
+ * 2) The hash computation uses a table of random integers [Hanson97,
+ * pp. 39-41].
+ *
+ * FUTURE ENHANCEMENTS
+ *
+ * With a table size of 512, the current implementation is sufficient for a
+ * few hundred keys. Since this is well above the expected size of the
+ * tables for which this implementation was designed, the implementation of
+ * dynamic hash tables was postponed until the need arises. A common (and
+ * naive) approach to dynamic hash table implementation simply creates a
+ * new hash table when necessary, rehashes all the data into the new table,
+ * and destroys the old table. The approach in [Larson88] is superior in
+ * two ways: 1) only a portion of the table is expanded when needed,
+ * distributing the expansion cost over several insertions, and 2) portions
+ * of the table can be locked, enabling a scalable thread-safe
+ * implementation.
+ *
+ * REFERENCES
+ *
+ * [Hanson97] David R. Hanson. C Interfaces and Implementations:
+ * Techniques for Creating Reusable Software. Reading, Massachusetts:
+ * Addison-Wesley, 1997.
+ *
+ * [Knuth73] Donald E. Knuth. The Art of Computer Programming. Volume 3:
+ * Sorting and Searching. Reading, Massachusetts: Addison-Wesley, 1973.
+ *
+ * [Larson88] Per-Ake Larson. "Dynamic Hash Tables". CACM 31(4), April
+ * 1988, pp. 446-457.
+ *
+ */
+
+#include "glxhash.h"
+#include <X11/Xfuncproto.h>
+
+#define HASH_MAIN 0
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define HASH_MAGIC 0xdeadbeef
+#define HASH_DEBUG 0
+#define HASH_SIZE 512 /* Good for about 100 entries */
+ /* If you change this value, you probably
+ have to change the HashHash hashing
+ function! */
+
+#define HASH_ALLOC malloc
+#define HASH_FREE free
+#define HASH_RANDOM_DECL
+#define HASH_RANDOM_INIT(seed) srandom(seed)
+#define HASH_RANDOM random()
+#define HASH_RANDOM_DESTROY
+
+typedef struct __glxHashBucket {
+ unsigned long key;
+ void *value;
+ struct __glxHashBucket *next;
+} __glxHashBucket, *__glxHashBucketPtr;
+
+typedef struct __glxHashTable *__glxHashTablePtr;
+struct __glxHashTable {
+ unsigned long magic;
+ unsigned long hits; /* At top of linked list */
+ unsigned long partials; /* Not at top of linked list */
+ unsigned long misses; /* Not in table */
+ __glxHashBucketPtr buckets[HASH_SIZE];
+ int p0;
+ __glxHashBucketPtr p1;
+};
+
+static unsigned long HashHash(unsigned long key)
+{
+ unsigned long hash = 0;
+ unsigned long tmp = key;
+ static int init = 0;
+ static unsigned long scatter[256];
+ int i;
+
+ if (!init) {
+ HASH_RANDOM_DECL;
+ HASH_RANDOM_INIT(37);
+ for (i = 0; i < 256; i++) scatter[i] = HASH_RANDOM;
+ HASH_RANDOM_DESTROY;
+ ++init;
+ }
+
+ while (tmp) {
+ hash = (hash << 1) + scatter[tmp & 0xff];
+ tmp >>= 8;
+ }
+
+ hash %= HASH_SIZE;
+#if HASH_DEBUG
+ printf( "Hash(%d) = %d\n", key, hash);
+#endif
+ return hash;
+}
+
+_X_HIDDEN __glxHashTable *__glxHashCreate(void)
+{
+ __glxHashTablePtr table;
+ int i;
+
+ table = HASH_ALLOC(sizeof(*table));
+ if (!table) return NULL;
+ table->magic = HASH_MAGIC;
+ table->hits = 0;
+ table->partials = 0;
+ table->misses = 0;
+
+ for (i = 0; i < HASH_SIZE; i++) table->buckets[i] = NULL;
+ return table;
+}
+
+_X_HIDDEN int __glxHashDestroy(__glxHashTable *t)
+{
+ __glxHashTablePtr table = (__glxHashTablePtr)t;
+ __glxHashBucketPtr bucket;
+ __glxHashBucketPtr next;
+ int i;
+
+ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ for (i = 0; i < HASH_SIZE; i++) {
+ for (bucket = table->buckets[i]; bucket;) {
+ next = bucket->next;
+ HASH_FREE(bucket);
+ bucket = next;
+ }
+ }
+ HASH_FREE(table);
+ return 0;
+}
+
+/* Find the bucket and organize the list so that this bucket is at the
+ top. */
+
+static __glxHashBucketPtr HashFind(__glxHashTablePtr table,
+ unsigned long key, unsigned long *h)
+{
+ unsigned long hash = HashHash(key);
+ __glxHashBucketPtr prev = NULL;
+ __glxHashBucketPtr bucket;
+
+ if (h) *h = hash;
+
+ for (bucket = table->buckets[hash]; bucket; bucket = bucket->next) {
+ if (bucket->key == key) {
+ if (prev) {
+ /* Organize */
+ prev->next = bucket->next;
+ bucket->next = table->buckets[hash];
+ table->buckets[hash] = bucket;
+ ++table->partials;
+ } else {
+ ++table->hits;
+ }
+ return bucket;
+ }
+ prev = bucket;
+ }
+ ++table->misses;
+ return NULL;
+}
+
+_X_HIDDEN int __glxHashLookup(__glxHashTable *t,
+ unsigned long key, void **value)
+{
+ __glxHashTablePtr table = (__glxHashTablePtr)t;
+ __glxHashBucketPtr bucket;
+
+ if (!table || table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ bucket = HashFind(table, key, NULL);
+ if (!bucket) return 1; /* Not found */
+ *value = bucket->value;
+ return 0; /* Found */
+}
+
+_X_HIDDEN int __glxHashInsert(__glxHashTable *t,
+ unsigned long key, void *value)
+{
+ __glxHashTablePtr table = (__glxHashTablePtr)t;
+ __glxHashBucketPtr bucket;
+ unsigned long hash;
+
+ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ if (HashFind(table, key, &hash)) return 1; /* Already in table */
+
+ bucket = HASH_ALLOC(sizeof(*bucket));
+ if (!bucket) return -1; /* Error */
+ bucket->key = key;
+ bucket->value = value;
+ bucket->next = table->buckets[hash];
+ table->buckets[hash] = bucket;
+#if HASH_DEBUG
+ printf("Inserted %d at %d/%p\n", key, hash, bucket);
+#endif
+ return 0; /* Added to table */
+}
+
+_X_HIDDEN int __glxHashDelete(__glxHashTable *t, unsigned long key)
+{
+ __glxHashTablePtr table = (__glxHashTablePtr)t;
+ unsigned long hash;
+ __glxHashBucketPtr bucket;
+
+ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ bucket = HashFind(table, key, &hash);
+
+ if (!bucket) return 1; /* Not found */
+
+ table->buckets[hash] = bucket->next;
+ HASH_FREE(bucket);
+ return 0;
+}
+
+_X_HIDDEN int __glxHashNext(__glxHashTable *t,
+ unsigned long *key, void **value)
+{
+ __glxHashTablePtr table = (__glxHashTablePtr)t;
+
+ while (table->p0 < HASH_SIZE) {
+ if (table->p1) {
+ *key = table->p1->key;
+ *value = table->p1->value;
+ table->p1 = table->p1->next;
+ return 1;
+ }
+ table->p1 = table->buckets[table->p0];
+ ++table->p0;
+ }
+ return 0;
+}
+
+_X_HIDDEN int __glxHashFirst(__glxHashTable *t,
+ unsigned long *key, void **value)
+{
+ __glxHashTablePtr table = (__glxHashTablePtr)t;
+
+ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ table->p0 = 0;
+ table->p1 = table->buckets[0];
+ return __glxHashNext(table, key, value);
+}
+
+#if HASH_MAIN
+#define DIST_LIMIT 10
+static int dist[DIST_LIMIT];
+
+static void clear_dist(void) {
+ int i;
+
+ for (i = 0; i < DIST_LIMIT; i++) dist[i] = 0;
+}
+
+static int count_entries(__glxHashBucketPtr bucket)
+{
+ int count = 0;
+
+ for (; bucket; bucket = bucket->next) ++count;
+ return count;
+}
+
+static void update_dist(int count)
+{
+ if (count >= DIST_LIMIT) ++dist[DIST_LIMIT-1];
+ else ++dist[count];
+}
+
+static void compute_dist(__glxHashTablePtr table)
+{
+ int i;
+ __glxHashBucketPtr bucket;
+
+ printf("Hits = %ld, partials = %ld, misses = %ld\n",
+ table->hits, table->partials, table->misses);
+ clear_dist();
+ for (i = 0; i < HASH_SIZE; i++) {
+ bucket = table->buckets[i];
+ update_dist(count_entries(bucket));
+ }
+ for (i = 0; i < DIST_LIMIT; i++) {
+ if (i != DIST_LIMIT-1) printf("%5d %10d\n", i, dist[i]);
+ else printf("other %10d\n", dist[i]);
+ }
+}
+
+static void check_table(__glxHashTablePtr table,
+ unsigned long key, unsigned long value)
+{
+ unsigned long retval = 0;
+ int retcode = __glxHashLookup(table, key, &retval);
+
+ switch (retcode) {
+ case -1:
+ printf("Bad magic = 0x%08lx:"
+ " key = %lu, expected = %lu, returned = %lu\n",
+ table->magic, key, value, retval);
+ break;
+ case 1:
+ printf("Not found: key = %lu, expected = %lu returned = %lu\n",
+ key, value, retval);
+ break;
+ case 0:
+ if (value != retval)
+ printf("Bad value: key = %lu, expected = %lu, returned = %lu\n",
+ key, value, retval);
+ break;
+ default:
+ printf("Bad retcode = %d: key = %lu, expected = %lu, returned = %lu\n",
+ retcode, key, value, retval);
+ break;
+ }
+}
+
+int main(void)
+{
+ __glxHashTablePtr table;
+ int i;
+
+ printf("\n***** 256 consecutive integers ****\n");
+ table = __glxHashCreate();
+ for (i = 0; i < 256; i++) __glxHashInsert(table, i, i);
+ for (i = 0; i < 256; i++) check_table(table, i, i);
+ for (i = 256; i >= 0; i--) check_table(table, i, i);
+ compute_dist(table);
+ __glxHashDestroy(table);
+
+ printf("\n***** 1024 consecutive integers ****\n");
+ table = __glxHashCreate();
+ for (i = 0; i < 1024; i++) __glxHashInsert(table, i, i);
+ for (i = 0; i < 1024; i++) check_table(table, i, i);
+ for (i = 1024; i >= 0; i--) check_table(table, i, i);
+ compute_dist(table);
+ __glxHashDestroy(table);
+
+ printf("\n***** 1024 consecutive page addresses (4k pages) ****\n");
+ table = __glxHashCreate();
+ for (i = 0; i < 1024; i++) __glxHashInsert(table, i*4096, i);
+ for (i = 0; i < 1024; i++) check_table(table, i*4096, i);
+ for (i = 1024; i >= 0; i--) check_table(table, i*4096, i);
+ compute_dist(table);
+ __glxHashDestroy(table);
+
+ printf("\n***** 1024 random integers ****\n");
+ table = __glxHashCreate();
+ srandom(0xbeefbeef);
+ for (i = 0; i < 1024; i++) __glxHashInsert(table, random(), i);
+ srandom(0xbeefbeef);
+ for (i = 0; i < 1024; i++) check_table(table, random(), i);
+ srandom(0xbeefbeef);
+ for (i = 0; i < 1024; i++) check_table(table, random(), i);
+ compute_dist(table);
+ __glxHashDestroy(table);
+
+ printf("\n***** 5000 random integers ****\n");
+ table = __glxHashCreate();
+ srandom(0xbeefbeef);
+ for (i = 0; i < 5000; i++) __glxHashInsert(table, random(), i);
+ srandom(0xbeefbeef);
+ for (i = 0; i < 5000; i++) check_table(table, random(), i);
+ srandom(0xbeefbeef);
+ for (i = 0; i < 5000; i++) check_table(table, random(), i);
+ compute_dist(table);
+ __glxHashDestroy(table);
+
+ return 0;
+}
+#endif
diff --git a/src/glx/x11/glxhash.h b/src/glx/x11/glxhash.h
new file mode 100644
index 0000000000..66012fb889
--- /dev/null
+++ b/src/glx/x11/glxhash.h
@@ -0,0 +1,16 @@
+#ifndef _GLX_HASH_H_
+#define _GLX_HASH_H_
+
+
+typedef struct __glxHashTable __glxHashTable;
+
+/* Hash table routines */
+extern __glxHashTable *__glxHashCreate(void);
+extern int __glxHashDestroy(__glxHashTable *t);
+extern int __glxHashLookup(__glxHashTable *t, unsigned long key, void **value);
+extern int __glxHashInsert(__glxHashTable *t, unsigned long key, void *value);
+extern int __glxHashDelete(__glxHashTable *t, unsigned long key);
+extern int __glxHashFirst(__glxHashTable *t, unsigned long *key, void **value);
+extern int __glxHashNext(__glxHashTable *t, unsigned long *key, void **value);
+
+#endif /* _GLX_HASH_H_ */
diff --git a/src/glx/x11/indirect.c b/src/glx/x11/indirect.c
index fbb2a91956..82e1b2edcc 100644
--- a/src/glx/x11/indirect.c
+++ b/src/glx/x11/indirect.c
@@ -300,7 +300,9 @@ __indirect_glNewList(GLuint list, GLenum mode)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -324,7 +326,9 @@ __indirect_glEndList(void)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 0;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -360,6 +364,10 @@ __indirect_glCallLists(GLsizei n, GLenum type, const GLvoid * lists)
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint compsize = __glCallLists_size(type);
const GLuint cmdlen = 12 + __GLX_PAD((compsize * n));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect((n >= 0) && (gc->currentDpy != NULL), 1)) {
if (cmdlen <= gc->maxSmallRenderCommandSize) {
if ((gc->pc + cmdlen) > gc->bufEnd) {
@@ -393,7 +401,9 @@ __indirect_glDeleteLists(GLuint list, GLsizei range)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -418,7 +428,9 @@ __indirect_glGenLists(GLsizei range)
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
GLuint retval = (GLuint) 0;
+#ifndef USE_XCB
const GLuint cmdlen = 4;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -3582,6 +3594,10 @@ __indirect_glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat * values)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 12 + __GLX_PAD((mapsize * 4));
+ if (mapsize < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect((mapsize >= 0) && (gc->currentDpy != NULL), 1)) {
if (cmdlen <= gc->maxSmallRenderCommandSize) {
if ((gc->pc + cmdlen) > gc->bufEnd) {
@@ -3615,6 +3631,10 @@ __indirect_glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint * values)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 12 + __GLX_PAD((mapsize * 4));
+ if (mapsize < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect((mapsize >= 0) && (gc->currentDpy != NULL), 1)) {
if (cmdlen <= gc->maxSmallRenderCommandSize) {
if ((gc->pc + cmdlen) > gc->bufEnd) {
@@ -3648,6 +3668,10 @@ __indirect_glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort * values)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 12 + __GLX_PAD((mapsize * 2));
+ if (mapsize < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect((mapsize >= 0) && (gc->currentDpy != NULL), 1)) {
if (cmdlen <= gc->maxSmallRenderCommandSize) {
if ((gc->pc + cmdlen) > gc->bufEnd) {
@@ -3716,7 +3740,9 @@ __indirect_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
__GLXcontext *const gc = __glXGetCurrentContext();
const __GLXattribute *const state = gc->client_state_private;
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 28;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -3808,7 +3834,9 @@ __indirect_glGetClipPlane(GLenum plane, GLdouble * equation)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 4;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -3841,7 +3869,9 @@ __indirect_glGetLightfv(GLenum light, GLenum pname, GLfloat * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -3879,7 +3909,9 @@ __indirect_glGetLightiv(GLenum light, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -3917,7 +3949,9 @@ __indirect_glGetMapdv(GLenum target, GLenum query, GLdouble * v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -3953,7 +3987,9 @@ __indirect_glGetMapfv(GLenum target, GLenum query, GLfloat * v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -3989,7 +4025,9 @@ __indirect_glGetMapiv(GLenum target, GLenum query, GLint * v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4025,7 +4063,9 @@ __indirect_glGetMaterialfv(GLenum face, GLenum pname, GLfloat * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4063,7 +4103,9 @@ __indirect_glGetMaterialiv(GLenum face, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4101,7 +4143,9 @@ __indirect_glGetPixelMapfv(GLenum map, GLfloat * values)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 4;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4137,7 +4181,9 @@ __indirect_glGetPixelMapuiv(GLenum map, GLuint * values)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 4;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4174,7 +4220,9 @@ __indirect_glGetPixelMapusv(GLenum map, GLushort * values)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 4;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4210,9 +4258,10 @@ void
__indirect_glGetPolygonStipple(GLubyte *mask)
{
__GLXcontext *const gc = __glXGetCurrentContext();
- const __GLXattribute *const state = gc->client_state_private;
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 4;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4247,7 +4296,9 @@ __indirect_glGetTexEnvfv(GLenum target, GLenum pname, GLfloat * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4285,7 +4336,9 @@ __indirect_glGetTexEnviv(GLenum target, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4323,7 +4376,9 @@ __indirect_glGetTexGendv(GLenum coord, GLenum pname, GLdouble * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4361,7 +4416,9 @@ __indirect_glGetTexGenfv(GLenum coord, GLenum pname, GLfloat * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4399,7 +4456,9 @@ __indirect_glGetTexGeniv(GLenum coord, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4439,7 +4498,9 @@ __indirect_glGetTexImage(GLenum target, GLint level, GLenum format,
__GLXcontext *const gc = __glXGetCurrentContext();
const __GLXattribute *const state = gc->client_state_private;
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 20;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4483,7 +4544,9 @@ __indirect_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4522,7 +4585,9 @@ __indirect_glGetTexParameteriv(GLenum target, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4562,7 +4627,9 @@ __indirect_glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname,
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 12;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4603,7 +4670,9 @@ __indirect_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname,
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 12;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4644,7 +4713,9 @@ __indirect_glIsList(GLuint list)
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
GLboolean retval = (GLboolean) 0;
+#ifndef USE_XCB
const GLuint cmdlen = 4;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -5012,7 +5083,13 @@ __indirect_glAreTexturesResident(GLsizei n, const GLuint * textures,
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
GLboolean retval = (GLboolean) 0;
+#ifndef USE_XCB
const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
+#endif
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return 0;
+ }
if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -5047,14 +5124,21 @@ glAreTexturesResidentEXT(GLsizei n, const GLuint * textures,
{
__GLXcontext *const gc = __glXGetCurrentContext();
- if (gc->isDirect) {
+#ifdef GLX_DIRECT_RENDERING
+ if (gc->driContext) {
return CALL_AreTexturesResident(GET_DISPATCH(),
(n, textures, residences));
- } else {
+ } else
+#endif
+ {
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
GLboolean retval = (GLboolean) 0;
const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return 0;
+ }
if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
GLubyte const *pc =
__glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
@@ -5163,7 +5247,13 @@ __indirect_glDeleteTextures(GLsizei n, const GLuint * textures)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
+#endif
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -5187,12 +5277,19 @@ glDeleteTexturesEXT(GLsizei n, const GLuint * textures)
{
__GLXcontext *const gc = __glXGetCurrentContext();
- if (gc->isDirect) {
+#ifdef GLX_DIRECT_RENDERING
+ if (gc->driContext) {
CALL_DeleteTextures(GET_DISPATCH(), (n, textures));
- } else {
+ } else
+#endif
+ {
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
GLubyte const *pc =
__glXSetupVendorRequest(gc, X_GLXVendorPrivate,
@@ -5212,7 +5309,13 @@ __indirect_glGenTextures(GLsizei n, GLuint * textures)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 4;
+#endif
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -5245,12 +5348,19 @@ glGenTexturesEXT(GLsizei n, GLuint * textures)
{
__GLXcontext *const gc = __glXGetCurrentContext();
- if (gc->isDirect) {
+#ifdef GLX_DIRECT_RENDERING
+ if (gc->driContext) {
CALL_GenTextures(GET_DISPATCH(), (n, textures));
- } else {
+ } else
+#endif
+ {
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = 4;
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
GLubyte const *pc =
__glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
@@ -5271,7 +5381,9 @@ __indirect_glIsTexture(GLuint texture)
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
GLboolean retval = (GLboolean) 0;
+#ifndef USE_XCB
const GLuint cmdlen = 4;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -5301,9 +5413,12 @@ glIsTextureEXT(GLuint texture)
{
__GLXcontext *const gc = __glXGetCurrentContext();
- if (gc->isDirect) {
+#ifdef GLX_DIRECT_RENDERING
+ if (gc->driContext) {
return CALL_IsTexture(GET_DISPATCH(), (texture));
- } else {
+ } else
+#endif
+ {
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
GLboolean retval = (GLboolean) 0;
@@ -5328,6 +5443,10 @@ __indirect_glPrioritizeTextures(GLsizei n, const GLuint * textures,
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 8 + __GLX_PAD((n * 4)) + __GLX_PAD((n * 4));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(n >= 0, 1)) {
emit_header(gc->pc, X_GLrop_PrioritizeTextures, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&n), 4);
@@ -5565,7 +5684,9 @@ __indirect_glGetColorTable(GLenum target, GLenum format, GLenum type,
__GLXcontext *const gc = __glXGetCurrentContext();
const __GLXattribute *const state = gc->client_state_private;
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 16;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -5609,9 +5730,12 @@ glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid * table)
{
__GLXcontext *const gc = __glXGetCurrentContext();
- if (gc->isDirect) {
+#ifdef GLX_DIRECT_RENDERING
+ if (gc->driContext) {
CALL_GetColorTable(GET_DISPATCH(), (target, format, type, table));
- } else {
+ } else
+#endif
+ {
__GLXcontext *const gc = __glXGetCurrentContext();
const __GLXattribute *const state = gc->client_state_private;
Display *const dpy = gc->currentDpy;
@@ -5641,7 +5765,9 @@ __indirect_glGetColorTableParameterfv(GLenum target, GLenum pname,
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -5680,10 +5806,13 @@ glGetColorTableParameterfvEXT(GLenum target, GLenum pname, GLfloat * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
- if (gc->isDirect) {
+#ifdef GLX_DIRECT_RENDERING
+ if (gc->driContext) {
CALL_GetColorTableParameterfv(GET_DISPATCH(),
(target, pname, params));
- } else {
+ } else
+#endif
+ {
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = 8;
@@ -5709,7 +5838,9 @@ __indirect_glGetColorTableParameteriv(GLenum target, GLenum pname,
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -5748,10 +5879,13 @@ glGetColorTableParameterivEXT(GLenum target, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
- if (gc->isDirect) {
+#ifdef GLX_DIRECT_RENDERING
+ if (gc->driContext) {
CALL_GetColorTableParameteriv(GET_DISPATCH(),
(target, pname, params));
- } else {
+ } else
+#endif
+ {
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = 8;
@@ -6029,7 +6163,9 @@ __indirect_glGetConvolutionFilter(GLenum target, GLenum format, GLenum type,
__GLXcontext *const gc = __glXGetCurrentContext();
const __GLXattribute *const state = gc->client_state_private;
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 16;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -6069,10 +6205,13 @@ gl_dispatch_stub_356(GLenum target, GLenum format, GLenum type,
{
__GLXcontext *const gc = __glXGetCurrentContext();
- if (gc->isDirect) {
+#ifdef GLX_DIRECT_RENDERING
+ if (gc->driContext) {
CALL_GetConvolutionFilter(GET_DISPATCH(),
(target, format, type, image));
- } else {
+ } else
+#endif
+ {
__GLXcontext *const gc = __glXGetCurrentContext();
const __GLXattribute *const state = gc->client_state_private;
Display *const dpy = gc->currentDpy;
@@ -6103,7 +6242,9 @@ __indirect_glGetConvolutionParameterfv(GLenum target, GLenum pname,
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -6142,10 +6283,13 @@ gl_dispatch_stub_357(GLenum target, GLenum pname, GLfloat * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
- if (gc->isDirect) {
+#ifdef GLX_DIRECT_RENDERING
+ if (gc->driContext) {
CALL_GetConvolutionParameterfv(GET_DISPATCH(),
(target, pname, params));
- } else {
+ } else
+#endif
+ {
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = 8;
@@ -6171,7 +6315,9 @@ __indirect_glGetConvolutionParameteriv(GLenum target, GLenum pname,
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -6210,10 +6356,13 @@ gl_dispatch_stub_358(GLenum target, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
- if (gc->isDirect) {
+#ifdef GLX_DIRECT_RENDERING
+ if (gc->driContext) {
CALL_GetConvolutionParameteriv(GET_DISPATCH(),
(target, pname, params));
- } else {
+ } else
+#endif
+ {
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = 8;
@@ -6240,7 +6389,9 @@ __indirect_glGetHistogram(GLenum target, GLboolean reset, GLenum format,
__GLXcontext *const gc = __glXGetCurrentContext();
const __GLXattribute *const state = gc->client_state_private;
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 16;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -6285,10 +6436,13 @@ gl_dispatch_stub_361(GLenum target, GLboolean reset, GLenum format,
{
__GLXcontext *const gc = __glXGetCurrentContext();
- if (gc->isDirect) {
+#ifdef GLX_DIRECT_RENDERING
+ if (gc->driContext) {
CALL_GetHistogram(GET_DISPATCH(),
(target, reset, format, type, values));
- } else {
+ } else
+#endif
+ {
__GLXcontext *const gc = __glXGetCurrentContext();
const __GLXattribute *const state = gc->client_state_private;
Display *const dpy = gc->currentDpy;
@@ -6319,7 +6473,9 @@ __indirect_glGetHistogramParameterfv(GLenum target, GLenum pname,
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -6357,9 +6513,12 @@ gl_dispatch_stub_362(GLenum target, GLenum pname, GLfloat * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
- if (gc->isDirect) {
+#ifdef GLX_DIRECT_RENDERING
+ if (gc->driContext) {
CALL_GetHistogramParameterfv(GET_DISPATCH(), (target, pname, params));
- } else {
+ } else
+#endif
+ {
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = 8;
@@ -6385,7 +6544,9 @@ __indirect_glGetHistogramParameteriv(GLenum target, GLenum pname,
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -6423,9 +6584,12 @@ gl_dispatch_stub_363(GLenum target, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
- if (gc->isDirect) {
+#ifdef GLX_DIRECT_RENDERING
+ if (gc->driContext) {
CALL_GetHistogramParameteriv(GET_DISPATCH(), (target, pname, params));
- } else {
+ } else
+#endif
+ {
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = 8;
@@ -6452,7 +6616,9 @@ __indirect_glGetMinmax(GLenum target, GLboolean reset, GLenum format,
__GLXcontext *const gc = __glXGetCurrentContext();
const __GLXattribute *const state = gc->client_state_private;
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 16;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -6493,9 +6659,12 @@ gl_dispatch_stub_364(GLenum target, GLboolean reset, GLenum format,
{
__GLXcontext *const gc = __glXGetCurrentContext();
- if (gc->isDirect) {
+#ifdef GLX_DIRECT_RENDERING
+ if (gc->driContext) {
CALL_GetMinmax(GET_DISPATCH(), (target, reset, format, type, values));
- } else {
+ } else
+#endif
+ {
__GLXcontext *const gc = __glXGetCurrentContext();
const __GLXattribute *const state = gc->client_state_private;
Display *const dpy = gc->currentDpy;
@@ -6526,7 +6695,9 @@ __indirect_glGetMinmaxParameterfv(GLenum target, GLenum pname,
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -6562,9 +6733,12 @@ gl_dispatch_stub_365(GLenum target, GLenum pname, GLfloat * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
- if (gc->isDirect) {
+#ifdef GLX_DIRECT_RENDERING
+ if (gc->driContext) {
CALL_GetMinmaxParameterfv(GET_DISPATCH(), (target, pname, params));
- } else {
+ } else
+#endif
+ {
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = 8;
@@ -6589,7 +6763,9 @@ __indirect_glGetMinmaxParameteriv(GLenum target, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -6625,9 +6801,12 @@ gl_dispatch_stub_366(GLenum target, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
- if (gc->isDirect) {
+#ifdef GLX_DIRECT_RENDERING
+ if (gc->driContext) {
CALL_GetMinmaxParameteriv(GET_DISPATCH(), (target, pname, params));
- } else {
+ } else
+#endif
+ {
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = 8;
@@ -7585,6 +7764,10 @@ __indirect_glProgramStringARB(GLenum target, GLenum format, GLsizei len,
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 16 + __GLX_PAD(len);
+ if (len < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect((len >= 0) && (gc->currentDpy != NULL), 1)) {
if (cmdlen <= gc->maxSmallRenderCommandSize) {
if ((gc->pc + cmdlen) > gc->bufEnd) {
@@ -8200,7 +8383,13 @@ __indirect_glDeleteQueriesARB(GLsizei n, const GLuint * ids)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
+#endif
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -8238,7 +8427,13 @@ __indirect_glGenQueriesARB(GLsizei n, GLuint * ids)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 4;
+#endif
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -8271,7 +8466,9 @@ __indirect_glGetQueryObjectivARB(GLuint id, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -8307,7 +8504,9 @@ __indirect_glGetQueryObjectuivARB(GLuint id, GLenum pname, GLuint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -8343,7 +8542,9 @@ __indirect_glGetQueryivARB(GLenum target, GLenum pname, GLint * params)
{
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
const GLuint cmdlen = 8;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -8383,7 +8584,9 @@ __indirect_glIsQueryARB(GLuint id)
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
GLboolean retval = (GLboolean) 0;
+#ifndef USE_XCB
const GLuint cmdlen = 4;
+#endif
if (__builtin_expect(dpy != NULL, 1)) {
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -8414,6 +8617,10 @@ __indirect_glDrawBuffersARB(GLsizei n, const GLenum * bufs)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 8 + __GLX_PAD((n * 4));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect((n >= 0) && (gc->currentDpy != NULL), 1)) {
if (cmdlen <= gc->maxSmallRenderCommandSize) {
if ((gc->pc + cmdlen) > gc->bufEnd) {
@@ -8774,6 +8981,10 @@ __indirect_glAreProgramsResidentNV(GLsizei n, const GLuint * ids,
Display *const dpy = gc->currentDpy;
GLboolean retval = (GLboolean) 0;
const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return 0;
+ }
if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
GLubyte const *pc =
__glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
@@ -8809,6 +9020,10 @@ __indirect_glDeleteProgramsNV(GLsizei n, const GLuint * programs)
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
GLubyte const *pc =
__glXSetupVendorRequest(gc, X_GLXVendorPrivate,
@@ -8845,6 +9060,10 @@ __indirect_glGenProgramsNV(GLsizei n, GLuint * programs)
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = 4;
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
GLubyte const *pc =
__glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
@@ -9051,6 +9270,10 @@ __indirect_glLoadProgramNV(GLenum target, GLuint id, GLsizei len,
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 16 + __GLX_PAD(len);
+ if (len < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(len >= 0, 1)) {
emit_header(gc->pc, X_GLrop_LoadProgramNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4);
@@ -9071,6 +9294,10 @@ __indirect_glProgramParameters4dvNV(GLenum target, GLuint index, GLuint num,
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 16 + __GLX_PAD((num * 32));
+ if (num < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(num >= 0, 1)) {
emit_header(gc->pc, X_GLrop_ProgramParameters4dvNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4);
@@ -9091,6 +9318,10 @@ __indirect_glProgramParameters4fvNV(GLenum target, GLuint index, GLuint num,
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 16 + __GLX_PAD((num * 16));
+ if (num < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(num >= 0, 1)) {
emit_header(gc->pc, X_GLrop_ProgramParameters4fvNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4);
@@ -9110,6 +9341,10 @@ __indirect_glRequestResidentProgramsNV(GLsizei n, const GLuint * ids)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 8 + __GLX_PAD((n * 4));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(n >= 0, 1)) {
emit_header(gc->pc, X_GLrop_RequestResidentProgramsNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&n), 4);
@@ -9561,6 +9796,10 @@ __indirect_glVertexAttribs1dvNV(GLuint index, GLsizei n, const GLdouble * v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 12 + __GLX_PAD((n * 8));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(n >= 0, 1)) {
emit_header(gc->pc, X_GLrop_VertexAttribs1dvNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9579,6 +9818,10 @@ __indirect_glVertexAttribs1fvNV(GLuint index, GLsizei n, const GLfloat * v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 12 + __GLX_PAD((n * 4));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(n >= 0, 1)) {
emit_header(gc->pc, X_GLrop_VertexAttribs1fvNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9597,6 +9840,10 @@ __indirect_glVertexAttribs1svNV(GLuint index, GLsizei n, const GLshort * v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 12 + __GLX_PAD((n * 2));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(n >= 0, 1)) {
emit_header(gc->pc, X_GLrop_VertexAttribs1svNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9615,6 +9862,10 @@ __indirect_glVertexAttribs2dvNV(GLuint index, GLsizei n, const GLdouble * v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 12 + __GLX_PAD((n * 16));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(n >= 0, 1)) {
emit_header(gc->pc, X_GLrop_VertexAttribs2dvNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9633,6 +9884,10 @@ __indirect_glVertexAttribs2fvNV(GLuint index, GLsizei n, const GLfloat * v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 12 + __GLX_PAD((n * 8));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(n >= 0, 1)) {
emit_header(gc->pc, X_GLrop_VertexAttribs2fvNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9651,6 +9906,10 @@ __indirect_glVertexAttribs2svNV(GLuint index, GLsizei n, const GLshort * v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 12 + __GLX_PAD((n * 4));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(n >= 0, 1)) {
emit_header(gc->pc, X_GLrop_VertexAttribs2svNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9669,6 +9928,10 @@ __indirect_glVertexAttribs3dvNV(GLuint index, GLsizei n, const GLdouble * v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 12 + __GLX_PAD((n * 24));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(n >= 0, 1)) {
emit_header(gc->pc, X_GLrop_VertexAttribs3dvNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9687,6 +9950,10 @@ __indirect_glVertexAttribs3fvNV(GLuint index, GLsizei n, const GLfloat * v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 12 + __GLX_PAD((n * 12));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(n >= 0, 1)) {
emit_header(gc->pc, X_GLrop_VertexAttribs3fvNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9705,6 +9972,10 @@ __indirect_glVertexAttribs3svNV(GLuint index, GLsizei n, const GLshort * v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 12 + __GLX_PAD((n * 6));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(n >= 0, 1)) {
emit_header(gc->pc, X_GLrop_VertexAttribs3svNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9723,6 +9994,10 @@ __indirect_glVertexAttribs4dvNV(GLuint index, GLsizei n, const GLdouble * v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 12 + __GLX_PAD((n * 32));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(n >= 0, 1)) {
emit_header(gc->pc, X_GLrop_VertexAttribs4dvNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9741,6 +10016,10 @@ __indirect_glVertexAttribs4fvNV(GLuint index, GLsizei n, const GLfloat * v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 12 + __GLX_PAD((n * 16));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(n >= 0, 1)) {
emit_header(gc->pc, X_GLrop_VertexAttribs4fvNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9759,6 +10038,10 @@ __indirect_glVertexAttribs4svNV(GLuint index, GLsizei n, const GLshort * v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 12 + __GLX_PAD((n * 8));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(n >= 0, 1)) {
emit_header(gc->pc, X_GLrop_VertexAttribs4svNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9777,6 +10060,10 @@ __indirect_glVertexAttribs4ubvNV(GLuint index, GLsizei n, const GLubyte *v)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 12 + __GLX_PAD((n * 4));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(n >= 0, 1)) {
emit_header(gc->pc, X_GLrop_VertexAttribs4ubvNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9843,6 +10130,10 @@ __indirect_glGetProgramNamedParameterdvNV(GLuint id, GLsizei len,
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = 8 + __GLX_PAD(len);
+ if (len < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect((len >= 0) && (dpy != NULL), 1)) {
GLubyte const *pc =
__glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
@@ -9867,6 +10158,10 @@ __indirect_glGetProgramNamedParameterfvNV(GLuint id, GLsizei len,
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = 8 + __GLX_PAD(len);
+ if (len < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect((len >= 0) && (dpy != NULL), 1)) {
GLubyte const *pc =
__glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
@@ -9890,6 +10185,10 @@ __indirect_glProgramNamedParameter4dNV(GLuint id, GLsizei len,
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 44 + __GLX_PAD(len);
+ if (len < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(len >= 0, 1)) {
emit_header(gc->pc, X_GLrop_ProgramNamedParameter4dvNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&x), 8);
@@ -9914,6 +10213,10 @@ __indirect_glProgramNamedParameter4dvNV(GLuint id, GLsizei len,
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 44 + __GLX_PAD(len);
+ if (len < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(len >= 0, 1)) {
emit_header(gc->pc, X_GLrop_ProgramNamedParameter4dvNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (v), 32);
@@ -9935,6 +10238,10 @@ __indirect_glProgramNamedParameter4fNV(GLuint id, GLsizei len,
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 28 + __GLX_PAD(len);
+ if (len < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(len >= 0, 1)) {
emit_header(gc->pc, X_GLrop_ProgramNamedParameter4fvNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&id), 4);
@@ -9959,6 +10266,10 @@ __indirect_glProgramNamedParameter4fvNV(GLuint id, GLsizei len,
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 28 + __GLX_PAD(len);
+ if (len < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(len >= 0, 1)) {
emit_header(gc->pc, X_GLrop_ProgramNamedParameter4fvNV, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&id), 4);
@@ -10044,6 +10355,10 @@ __indirect_glDeleteFramebuffersEXT(GLsizei n, const GLuint * framebuffers)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 8 + __GLX_PAD((n * 4));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(n >= 0, 1)) {
emit_header(gc->pc, X_GLrop_DeleteFramebuffersEXT, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&n), 4);
@@ -10062,6 +10377,10 @@ __indirect_glDeleteRenderbuffersEXT(GLsizei n, const GLuint * renderbuffers)
{
__GLXcontext *const gc = __glXGetCurrentContext();
const GLuint cmdlen = 8 + __GLX_PAD((n * 4));
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect(n >= 0, 1)) {
emit_header(gc->pc, X_GLrop_DeleteRenderbuffersEXT, cmdlen);
(void) memcpy((void *) (gc->pc + 4), (void *) (&n), 4);
@@ -10161,6 +10480,10 @@ __indirect_glGenFramebuffersEXT(GLsizei n, GLuint * framebuffers)
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = 4;
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
GLubyte const *pc =
__glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
@@ -10180,6 +10503,10 @@ __indirect_glGenRenderbuffersEXT(GLsizei n, GLuint * renderbuffers)
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = 4;
+ if (n < 0) {
+ __glXSetError(gc, GL_INVALID_VALUE);
+ return;
+ }
if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
GLubyte const *pc =
__glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
diff --git a/src/glx/x11/glx_texture_compression.c b/src/glx/x11/indirect_texture_compression.c
index 5676858017..5676858017 100644
--- a/src/glx/x11/glx_texture_compression.c
+++ b/src/glx/x11/indirect_texture_compression.c
diff --git a/src/glx/x11/indirect_vertex_array.c b/src/glx/x11/indirect_vertex_array.c
index 90ec277c41..c7a20e2bc5 100644
--- a/src/glx/x11/indirect_vertex_array.c
+++ b/src/glx/x11/indirect_vertex_array.c
@@ -32,7 +32,7 @@
#include <GL/glxproto.h>
#include "glxextensions.h"
#include "indirect_vertex_array.h"
-#include "indirect_va_private.h"
+#include "indirect_vertex_array_priv.h"
#define __GLX_PAD(n) (((n)+3) & ~3)
@@ -62,7 +62,7 @@
* "vbo", to support multiple texture coordinate arrays, generic attributes,
* and vertex buffer objects.
*
- * \author Ian Romanick <idr@us.ibm.com>
+ * \author Ian Romanick <ian.d.romanick@intel.com>
*/
static void emit_DrawArrays_none( GLenum mode, GLint first, GLsizei count );
@@ -101,6 +101,31 @@ const GLuint __glXTypeSize_table[16] = {
};
+/**
+ * Free the per-context array state that was allocated with
+ * __glXInitVertexArrayState().
+ */
+void
+__glXFreeVertexArrayState( __GLXcontext * gc )
+{
+ __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
+ struct array_state_vector* arrays = state->array_state;
+
+ if (arrays) {
+ if (arrays->stack) {
+ free(arrays->stack);
+ arrays->stack = NULL;
+ }
+ if (arrays->arrays) {
+ free(arrays->arrays);
+ arrays->arrays = NULL;
+ }
+ free(arrays);
+ arrays = NULL;
+ state->array_state = NULL;
+ }
+}
+
/**
* Initialize vertex array state of a GLX context.
@@ -485,14 +510,14 @@ emit_DrawArrays_none( GLenum mode, GLint first, GLsizei count )
for ( i = 0 ; i < count ; i++ ) {
if ( (pc + single_vertex_size) >= gc->bufEnd ) {
- pc = __glXFlushRenderBuffer(gc, gc->pc);
+ pc = __glXFlushRenderBuffer(gc, pc);
}
pc = emit_element_none( pc, arrays, first + i );
}
if ( (pc + 4) >= gc->bufEnd ) {
- pc = __glXFlushRenderBuffer(gc, gc->pc);
+ pc = __glXFlushRenderBuffer(gc, pc);
}
(void) memcpy( pc, end_cmd, 4 );
@@ -527,7 +552,7 @@ static GLubyte *
emit_DrawArrays_header_old( __GLXcontext * gc,
struct array_state_vector * arrays,
size_t * elements_per_request,
- size_t * total_requests,
+ unsigned int * total_requests,
GLenum mode, GLsizei count )
{
size_t command_size;
@@ -640,7 +665,7 @@ emit_DrawArrays_old( GLenum mode, GLint first, GLsizei count )
GLubyte * pc;
size_t elements_per_request;
- size_t total_requests = 0;
+ unsigned total_requests = 0;
unsigned i;
size_t total_sent = 0;
@@ -726,7 +751,7 @@ emit_DrawElements_none( GLenum mode, GLsizei count, GLenum type,
unsigned index = 0;
if ( (pc + single_vertex_size) >= gc->bufEnd ) {
- pc = __glXFlushRenderBuffer(gc, gc->pc);
+ pc = __glXFlushRenderBuffer(gc, pc);
}
switch( type ) {
@@ -744,7 +769,7 @@ emit_DrawElements_none( GLenum mode, GLsizei count, GLenum type,
}
if ( (pc + 4) >= gc->bufEnd ) {
- pc = __glXFlushRenderBuffer(gc, gc->pc);
+ pc = __glXFlushRenderBuffer(gc, pc);
}
(void) memcpy( pc, end_cmd, 4 );
@@ -770,9 +795,10 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,
GLubyte * pc;
size_t elements_per_request;
- size_t total_requests = 0;
+ unsigned total_requests = 0;
unsigned i;
unsigned req;
+ unsigned req_element=0;
pc = emit_DrawArrays_header_old( gc, arrays, & elements_per_request,
@@ -790,7 +816,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,
switch( type ) {
case GL_UNSIGNED_INT: {
- const GLuint * ui_ptr = (const GLuint *) indices;
+ const GLuint * ui_ptr = (const GLuint *) indices + req_element;
for ( i = 0 ; i < elements_per_request ; i++ ) {
const GLint index = (GLint) *(ui_ptr++);
@@ -799,7 +825,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,
break;
}
case GL_UNSIGNED_SHORT: {
- const GLushort * us_ptr = (const GLushort *) indices;
+ const GLushort * us_ptr = (const GLushort *) indices + req_element;
for ( i = 0 ; i < elements_per_request ; i++ ) {
const GLint index = (GLint) *(us_ptr++);
@@ -808,7 +834,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,
break;
}
case GL_UNSIGNED_BYTE: {
- const GLubyte * ub_ptr = (const GLubyte *) indices;
+ const GLubyte * ub_ptr = (const GLubyte *) indices + req_element;
for ( i = 0 ; i < elements_per_request ; i++ ) {
const GLint index = (GLint) *(ub_ptr++);
@@ -826,6 +852,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,
}
count -= elements_per_request;
+ req_element += elements_per_request;
}
@@ -1599,17 +1626,21 @@ void __indirect_glClientActiveTextureARB(GLenum texture)
/**
+ * Modify the enable state for the selected array
*/
GLboolean
-__glXSetArrayEnable( __GLXattribute * state,
- GLenum key, unsigned index, GLboolean enable )
+__glXSetArrayEnable(__GLXattribute *state, GLenum key, unsigned index,
+ GLboolean enable)
{
struct array_state_vector * arrays = state->array_state;
struct array_state * a;
- if ( key == GL_TEXTURE_COORD_ARRAY ) {
- index = arrays->active_texture_unit;
+ /* Texture coordinate arrays have an implict index set when the
+ * application calls glClientActiveTexture.
+ */
+ if (key == GL_TEXTURE_COORD_ARRAY) {
+ index = arrays->active_texture_unit;
}
a = get_array_entry( arrays, key, index );
diff --git a/src/glx/x11/indirect_va_private.h b/src/glx/x11/indirect_vertex_array_priv.h
index ab97dc645f..ab97dc645f 100644
--- a/src/glx/x11/indirect_va_private.h
+++ b/src/glx/x11/indirect_vertex_array_priv.h
diff --git a/src/glx/x11/indirect_vertex_program.c b/src/glx/x11/indirect_vertex_program.c
index 5383dcc981..8d7cec9dd2 100644
--- a/src/glx/x11/indirect_vertex_program.c
+++ b/src/glx/x11/indirect_vertex_program.c
@@ -23,6 +23,7 @@
* SOFTWARE.
*/
+#include "glheader.h"
#include <inttypes.h>
#include <GL/gl.h>
#include "indirect.h"
diff --git a/src/glx/x11/pixelstore.c b/src/glx/x11/pixelstore.c
index 6f25ed786e..82a0151752 100644
--- a/src/glx/x11/pixelstore.c
+++ b/src/glx/x11/pixelstore.c
@@ -33,6 +33,7 @@
**
*/
+#include "glheader.h"
#include "glxclient.h"
#include "indirect.h"
diff --git a/src/glx/x11/singlepix.c b/src/glx/x11/singlepix.c
index cd88684f70..9c984c75d2 100644
--- a/src/glx/x11/singlepix.c
+++ b/src/glx/x11/singlepix.c
@@ -33,6 +33,7 @@
**
*/
+#include "glheader.h"
#include "packsingle.h"
#include "indirect.h"
#include "dispatch.h"
@@ -117,12 +118,14 @@ void NAME(_gloffset_GetSeparableFilter)(GLenum target, GLenum format, GLenum typ
{
__GLXcontext * const gc = __glXGetCurrentContext();
- if (gc->isDirect) {
+#ifdef GLX_DIRECT_RENDERING
+ if (gc->driContext) {
CALL_GetSeparableFilter(GET_DISPATCH(),
(target, format, type, row, column, span));
return;
- }
- else {
+ } else
+#endif
+ {
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = __GLX_PAD(13);
diff --git a/src/glx/x11/xf86dri.h b/src/glx/x11/xf86dri.h
index c8c878f127..a6a57c3135 100644
--- a/src/glx/x11/xf86dri.h
+++ b/src/glx/x11/xf86dri.h
@@ -64,8 +64,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef _XF86DRI_SERVER_
-#include <GL/internal/dri_interface.h>
-
_XFUNCPROTOBEGIN
Bool XF86DRIQueryExtension( Display *dpy, int *event_base, int *error_base );
@@ -93,14 +91,14 @@ Bool XF86DRICreateContext( Display *dpy, int screen, Visual *visual,
Bool XF86DRICreateContextWithConfig( Display *dpy, int screen, int configID,
XID *ptr_to_returned_context_id, drm_context_t *hHWContext );
-extern GLboolean XF86DRIDestroyContext( __DRInativeDisplay *dpy, int screen,
- __DRIid context_id );
+extern GLboolean XF86DRIDestroyContext( Display *dpy, int screen,
+ XID context_id );
-extern GLboolean XF86DRICreateDrawable( __DRInativeDisplay *dpy, int screen,
- __DRIid drawable, drm_drawable_t *hHWDrawable );
+extern GLboolean XF86DRICreateDrawable( Display *dpy, int screen,
+ XID drawable, drm_drawable_t *hHWDrawable );
-extern GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay *dpy, int screen,
- __DRIid drawable);
+extern GLboolean XF86DRIDestroyDrawable( Display *dpy, int screen,
+ XID drawable);
Bool XF86DRIGetDrawableInfo( Display *dpy, int screen, Drawable drawable,
unsigned int *index, unsigned int *stamp,
diff --git a/src/glx/x11/xfont.c b/src/glx/x11/xfont.c
index f3e3da3e79..6ec8c2d6bf 100644
--- a/src/glx/x11/xfont.c
+++ b/src/glx/x11/xfont.c
@@ -33,6 +33,7 @@
called by that routine when direct rendering is enabled.
*/
+#ifdef GLX_DIRECT_RENDERING
#include "glxclient.h"
@@ -208,8 +209,7 @@ static XCharStruct *isvalid(XFontStruct *fs, int which)
return(NULL);
}
-
-void DRI_glXUseXFont( Font font, int first, int count, int listbase )
+_X_HIDDEN void DRI_glXUseXFont( Font font, int first, int count, int listbase )
{
GLXContext CC;
Display *dpy;
@@ -373,4 +373,4 @@ bm_height);
glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
}
-/* The End. */
+#endif