summaryrefslogtreecommitdiff
path: root/src/glx
diff options
context:
space:
mode:
Diffstat (limited to 'src/glx')
-rw-r--r--src/glx/x11/Makefile3
-rw-r--r--src/glx/x11/XF86dri.c39
-rw-r--r--src/glx/x11/dri_glx.c5
-rw-r--r--src/glx/x11/glxclient.h61
-rw-r--r--src/glx/x11/glxcmds.c350
-rw-r--r--src/glx/x11/glxext.c190
-rw-r--r--src/glx/x11/glxextensions.c77
-rw-r--r--src/glx/x11/glxextensions.h6
-rw-r--r--src/glx/x11/glxhash.c411
-rw-r--r--src/glx/x11/glxhash.h16
-rw-r--r--src/glx/x11/xf86dri.h12
-rw-r--r--src/glx/x11/xf86dristr.h5
12 files changed, 873 insertions, 302 deletions
diff --git a/src/glx/x11/Makefile b/src/glx/x11/Makefile
index 9f0943a146..00a568cdbc 100644
--- a/src/glx/x11/Makefile
+++ b/src/glx/x11/Makefile
@@ -31,7 +31,8 @@ SOURCES = \
glx_query.c \
glx_texture_compression.c \
dri_glx.c \
- XF86dri.c
+ XF86dri.c \
+ glxhash.c
include $(TOP)/src/mesa/sources
diff --git a/src/glx/x11/XF86dri.c b/src/glx/x11/XF86dri.c
index 8909a04772..5b0bf14afe 100644
--- a/src/glx/x11/XF86dri.c
+++ b/src/glx/x11/XF86dri.c
@@ -375,10 +375,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;
@@ -397,10 +396,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;
@@ -427,16 +425,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;
@@ -445,6 +463,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/dri_glx.c b/src/glx/x11/dri_glx.c
index 5cf9923979..c02f105611 100644
--- a/src/glx/x11/dri_glx.c
+++ b/src/glx/x11/dri_glx.c
@@ -167,11 +167,8 @@ ExtractDir(int index, const char *paths, int dirLen, char *dir)
* 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";
+static const char createNewScreenName[] = __DRI_CREATE_NEW_SCREEN_STRING;
/**
diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h
index 477566cc46..0709f3ef26 100644
--- a/src/glx/x11/glxclient.h
+++ b/src/glx/x11/glxclient.h
@@ -60,6 +60,7 @@
#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 )
@@ -71,7 +72,9 @@
#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;
@@ -79,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>
@@ -239,6 +245,7 @@ struct __GLXcontextRec {
* Screen number.
*/
GLint screen;
+ __GLXscreenConfigs *psc;
/**
* \c GL_TRUE if the context was created with ImportContext, which
@@ -349,6 +356,16 @@ struct __GLXcontextRec {
* Per context direct rendering interface functions and data.
*/
__DRIcontext driContext;
+
+ /**
+ * Pointer to the mode used to create this context.
+ */
+ const __GLcontextModes * mode;
+
+ /**
+ * XID for the server side drm_context_t
+ */
+ XID hwContextID;
#endif
/**
@@ -439,7 +456,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.
*/
@@ -456,6 +473,30 @@ typedef struct __GLXscreenConfigsRec {
* Per screen direct rendering interface functions and data.
*/
__DRIscreen driScreen;
+ __glxHashTable *drawHash;
+ Display *dpy;
+ int scr;
+
+#ifdef __DRI_COPY_SUB_BUFFER
+ __DRIcopySubBufferExtension *copySubBuffer;
+#endif
+
+#ifdef __DRI_SWAP_CONTROL
+ __DRIswapControlExtension *swapControl;
+#endif
+
+#ifdef __DRI_ALLOCATE
+ __DRIallocateExtension *allocate;
+#endif
+
+#ifdef __DRI_FRAME_TRACKING
+ __DRIframeTrackingExtension *frameTracking;
+#endif
+
+#ifdef __DRI_MEDIA_STREAM_COUNTER
+ __DRImediaStreamCounterExtension *msc;
+#endif
+
#endif
/**
@@ -475,7 +516,7 @@ typedef struct __GLXscreenConfigsRec {
GLboolean ext_list_first_time;
/*@}*/
-} __GLXscreenConfigs;
+};
/**
* Per display private data. One of these records exists for each display
@@ -528,6 +569,18 @@ struct __GLXdisplayPrivateRec {
#endif
};
+#ifdef GLX_DIRECT_RENDERING
+
+struct __GLXdrawableRec {
+ XID drawable;
+ __GLXscreenConfigs *psc;
+ __DRIdrawable driDrawable;
+};
+
+#endif
+
+
+
void __glXFreeContext(__GLXcontext*);
extern GLubyte *__glXFlushRenderBuffer(__GLXcontext*, GLubyte*);
@@ -687,7 +740,7 @@ 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(__DRIdrawable *draw,
+ int32_t * numerator, int32_t * denominator);
#endif /* !__GLX_client_h__ */
diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c
index f52b71ffcd..0a49e94586 100644
--- a/src/glx/x11/glxcmds.c
+++ b/src/glx/x11/glxcmds.c
@@ -61,41 +61,87 @@ 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;
+ __GLXdrawable *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->driDrawable.destroyDrawable)(&pdraw->driDrawable);
+ XF86DRIDestroyDrawable(dpy, sc->scr, draw);
+ Xfree(pdraw);
+ }
+ } while (__glxHashNext(sc->drawHash, &draw, (void *)&pdraw) == 1);
+ }
+
+ XSetErrorHandler(oldXErrorHandler);
+}
+
/**
* 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 )
{
__GLXdisplayPrivate * const priv = __glXInitialize(dpy);
+ __GLXdrawable * const pdraw;
+ const unsigned screen_count = ScreenCount(dpy);
+ unsigned i;
+ __GLXscreenConfigs *sc;
- 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;
-
- if ( pdraw != NULL ) {
- if ( scrn_num != NULL ) {
- *scrn_num = i;
- }
- return pdraw;
- }
+ if (priv == NULL || priv->driDisplay.private == NULL)
+ return NULL;
+
+ for (i = 0; i < screen_count; i++) {
+ sc = &priv->screenConfigs[i];
+ if (__glxHashLookup(sc->drawHash, drawable, (void *) &pdraw) == 0) {
+ if (scrn_num != NULL)
+ *scrn_num = i;
+ return &pdraw->driDrawable;
}
}
return NULL;
}
+
#endif
@@ -330,6 +376,7 @@ CreateContext(Display *dpy, XVisualInfo *vis,
int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen;
__GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
const __GLcontextModes * mode;
+ drm_context_t hwContext;
/* The value of fbconfig cannot change because it is tested
* later in the function.
@@ -348,18 +395,32 @@ CreateContext(Display *dpy, XVisualInfo *vis,
}
if (psc && psc->driScreen.private) {
- void * const shared = (shareList != NULL)
- ? shareList->driContext.private : NULL;
+ __DRIcontext *shared = (shareList != NULL)
+ ? &shareList->driContext : NULL;
+
+
+ if (!XF86DRICreateContextWithConfig(dpy, psc->scr,
+ mode->fbconfigID,
+ &gc->hwContextID, &hwContext))
+ /* gah, handle this better */
+ return NULL;
+
gc->driContext.private =
- (*psc->driScreen.createNewContext)( dpy, mode, renderType,
+ (*psc->driScreen.createNewContext)( &psc->driScreen,
+ mode, renderType,
shared,
+ hwContext,
&gc->driContext );
if (gc->driContext.private) {
gc->isDirect = GL_TRUE;
gc->screen = mode->screen;
+ gc->psc = psc;
gc->vid = mode->visualID;
gc->fbconfigID = mode->fbconfigID;
- gc->driContext.mode = mode;
+ gc->mode = mode;
+ }
+ else {
+ XF86DRIDestroyContext(dpy, psc->scr, gc->hwContextID);
}
}
}
@@ -469,10 +530,11 @@ DestroyContext(Display *dpy, GLXContext gc)
/* Destroy the direct rendering context */
if (gc->isDirect) {
if (gc->driContext.private) {
- (*gc->driContext.destroyContext)(dpy, gc->screen,
- gc->driContext.private);
+ (*gc->driContext.destroyContext)(&gc->driContext);
+ XF86DRIDestroyContext(dpy, gc->psc->scr, gc->hwContextID);
gc->driContext.private = NULL;
}
+ GarbageCollectDRIDrawables(dpy, gc->psc);
}
#endif
@@ -797,7 +859,7 @@ PUBLIC void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
__DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, NULL );
if ( pdraw != NULL ) {
- (*pdraw->swapBuffers)(dpy, pdraw->private);
+ (*pdraw->swapBuffers)(pdraw);
return;
}
#endif
@@ -1669,16 +1731,15 @@ static int __glXSwapIntervalSGI(int interval)
return GLX_BAD_VALUE;
}
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_SWAP_CONTROL
if ( gc->isDirect ) {
__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;
+ if (psc->swapControl != NULL && pdraw != NULL) {
+ psc->swapControl->setSwapInterval(pdraw, interval);
return 0;
}
else {
@@ -1716,7 +1777,7 @@ 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 ) {
@@ -1727,14 +1788,11 @@ static int __glXSwapIntervalMESA(unsigned int interval)
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
gc->screen );
- if ( (psc != NULL) && (psc->driScreen.private != NULL)
- && __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) {
+ if ( (psc != NULL) && (psc->driScreen.private != NULL) ) {
__DRIdrawable * const pdraw =
- (*psc->driScreen.getDrawable)(gc->currentDpy,
- gc->currentDrawable,
- psc->driScreen.private);
- if ( pdraw != NULL ) {
- pdraw->swap_interval = interval;
+ GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+ if (psc->swapControl != NULL && pdraw != NULL) {
+ psc->swapControl->setSwapInterval(pdraw, interval);
return 0;
}
}
@@ -1749,21 +1807,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 ) {
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
gc->screen );
- if ( (psc != NULL) && (psc->driScreen.private != NULL)
- && __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) {
+ if ( (psc != NULL) && (psc->driScreen.private != NULL) ) {
__DRIdrawable * const pdraw =
- (*psc->driScreen.getDrawable)(gc->currentDpy,
- gc->currentDrawable,
- psc->driScreen.private);
- if ( pdraw != NULL ) {
- return pdraw->swap_interval;
+ GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+ if (psc->swapControl != NULL && pdraw != NULL) {
+ return psc->swapControl->getSwapInterval(pdraw);
}
}
}
@@ -1780,15 +1835,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);
__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, GL_TRUE);
#else
(void) dpy;
(void) drawable;
@@ -1800,15 +1853,13 @@ 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);
- 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, GL_FALSE);
#else
(void) dpy;
(void) drawable;
@@ -1821,19 +1872,19 @@ 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);
__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, &sbc,
+ &missedFrames,
+ &lastMissedUsage,
+ usage);
}
#else
(void) dpy;
@@ -1849,18 +1900,16 @@ 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);
__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, sbc, missedFrames,
+ lastMissedUsage, &usage);
}
#else
(void) dpy;
@@ -1882,19 +1931,18 @@ 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 ) {
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
gc->screen );
- if ( __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit )
- && psc->driScreen.private && psc->driScreen.getMSC) {
+ if (psc->msc != NULL && psc->driScreen.private != NULL) {
int ret;
int64_t temp;
- ret = psc->driScreen.getMSC( psc->driScreen.private, & temp );
+ ret = psc->msc->getMSC(&psc->driScreen, &temp);
*count = (unsigned) temp;
return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
}
@@ -1907,7 +1955,7 @@ 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 )
@@ -1916,20 +1964,16 @@ static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count
if ( (gc != NULL) && gc->isDirect ) {
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
gc->screen );
- if ( __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit )
- && psc->driScreen.private ) {
+ if (psc->msc != NULL && psc->driScreen.private ) {
__DRIdrawable * const pdraw =
- (*psc->driScreen.getDrawable)(gc->currentDpy,
- gc->currentDrawable,
- psc->driScreen.private);
- if ( (pdraw != NULL) && (pdraw->waitForMSC != NULL) ) {
+ GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+ if (pdraw != NULL) {
int ret;
int64_t msc;
int64_t sbc;
- ret = (*pdraw->waitForMSC)( gc->currentDpy, pdraw->private,
- 0, divisor, remainder,
- & msc, & sbc );
+ ret = (*psc->msc->waitForMSC)(pdraw, 0,
+ divisor, remainder, &msc, &sbc);
*count = (unsigned) msc;
return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
}
@@ -2084,7 +2128,7 @@ 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 ) {
@@ -2093,11 +2137,10 @@ static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable,
__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, sbc) == 0)
+ && (__glXGetUST(ust) == 0) );
}
#else
(void) dpy;
@@ -2126,25 +2169,25 @@ 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)
+GLboolean __glXGetMscRateOML(__DRIdrawable *draw,
+ int32_t * numerator, int32_t * denominator)
{
#if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE )
+ __GLXdrawable *glxDraw =
+ containerOf(draw, __GLXdrawable, driDrawable);
+ __GLXscreenConfigs *psc = glxDraw->psc;
+ Display *dpy = psc->dpy;
__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 ) ) {
+ if (XF86VidModeQueryVersion( dpy, & i, & i ) &&
+ XF86VidModeGetModeLine(dpy, psc->scr, &dot_clock, &mode_line) ) {
unsigned n = dot_clock * 1000;
unsigned d = mode_line.vtotal * mode_line.htotal;
@@ -2186,13 +2229,11 @@ Bool __glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
*numerator = n;
*denominator = d;
- (void) drawable;
return True;
}
}
#else
- (void) dpy;
- (void) drawable;
+ (void) draw;
(void) numerator;
(void) denominator;
#endif
@@ -2204,7 +2245,7 @@ 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 );
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
@@ -2219,11 +2260,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, target_msc,
+ divisor, remainder);
+
#else
(void) dpy;
(void) drawable;
@@ -2240,7 +2280,7 @@ 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 );
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
@@ -2254,10 +2294,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, 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.
@@ -2282,7 +2321,7 @@ 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 );
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
@@ -2294,9 +2333,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, target_sbc, msc, sbc);
/* __glXGetUST returns zero on success and non-zero on failure.
* This function returns True on success and False on failure.
@@ -2324,16 +2362,14 @@ 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;
@@ -2349,14 +2385,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;
@@ -2368,14 +2402,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;
@@ -2448,13 +2480,13 @@ 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 );
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, x, y, width, height);
}
return;
@@ -2889,50 +2921,6 @@ int __glXGetInternalVersion(void)
}
-
-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
diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c
index 8fe10338a8..7b25ad717a 100644
--- a/src/glx/x11/glxext.c
+++ b/src/glx/x11/glxext.c
@@ -61,6 +61,7 @@
#include <inttypes.h>
#include <sys/mman.h>
#include "xf86dri.h"
+#include "xf86drm.h"
#include "sarea.h"
#include "dri_glx.h"
#endif
@@ -108,10 +109,6 @@ 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);
@@ -363,9 +360,9 @@ static void FreeScreenConfigs(__GLXdisplayPrivate *priv)
#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.destroyScreen)(&psc->driScreen);
psc->driScreen.private = NULL;
+ __glxHashDestroy(psc->drawHash);
#endif
}
XFree((char*) priv->screenConfigs);
@@ -694,21 +691,8 @@ filter_modes( __GLcontextModes ** server_modes,
return modes_count;
}
-
-/**
- * Implement \c __DRIinterfaceMethods::getProcAddress.
- */
-static __DRIfuncPtr get_proc_address( const char * proc_name )
-{
- if (strcmp( proc_name, "glxEnableExtension" ) == 0) {
- return (__DRIfuncPtr) __glXScrEnableExtension;
- }
-
- return NULL;
-}
-
#ifdef XDAMAGE_1_1_INTERFACE
-static GLboolean has_damage_post(__DRInativeDisplay *dpy)
+static GLboolean has_damage_post(Display *dpy)
{
static GLboolean inited = GL_FALSE;
static GLboolean has_damage;
@@ -730,8 +714,7 @@ static GLboolean has_damage_post(__DRInativeDisplay *dpy)
}
#endif /* XDAMAGE_1_1_INTERFACE */
-static void __glXReportDamage(__DRInativeDisplay *dpy, int screen,
- __DRIid drawable,
+static void __glXReportDamage(__DRIdrawable *driDraw,
int x, int y,
drm_clip_rect_t *rects, int num_rects,
GLboolean front_buffer)
@@ -741,6 +724,11 @@ static void __glXReportDamage(__DRInativeDisplay *dpy, int screen,
XserverRegion region;
int i;
int x_off, y_off;
+ __GLXdrawable *glxDraw =
+ containerOf(driDraw, __GLXdrawable, driDrawable);
+ __GLXscreenConfigs *psc = glxDraw->psc;
+ Display *dpy = psc->dpy;
+ Drawable drawable;
if (!has_damage_post(dpy))
return;
@@ -748,10 +736,11 @@ static void __glXReportDamage(__DRInativeDisplay *dpy, int screen,
if (front_buffer) {
x_off = x;
y_off = y;
- drawable = RootWindow(dpy, screen);
+ drawable = RootWindow(dpy, psc->scr);
} else{
x_off = 0;
y_off = 0;
+ drawable = glxDraw->drawable;
}
xrects = malloc(sizeof(XRectangle) * num_rects);
@@ -771,24 +760,35 @@ static void __glXReportDamage(__DRInativeDisplay *dpy, int screen,
#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)
+{
+ __GLXdrawable *glxDraw =
+ containerOf(drawable, __GLXdrawable, driDrawable);
+ __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);
+}
+
+
/**
* 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,
+ __glXDRIGetDrawableInfo,
__glXGetUST,
__glXGetMscRateOML,
@@ -816,7 +816,7 @@ static const __DRIinterfaceMethods interface_methods = {
* returned by the client-side driver.
*/
static void *
-CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc,
+CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
__DRIdisplay * driDpy,
PFNCREATENEWSCREENFUNC createNewScreen)
{
@@ -937,13 +937,11 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc,
if ( status == 0 ) {
__GLcontextModes * driver_modes = NULL;
- __GLXscreenConfigs *configs = psc->screenConfigs;
err_msg = "InitDriver";
err_extra = NULL;
- psp = (*createNewScreen)(dpy, scrn,
- psc,
- configs->configs,
+ psp = (*createNewScreen)(scrn,
+ &psc->driScreen,
& ddx_version,
& dri_version,
& drm_version,
@@ -954,8 +952,7 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc,
& interface_methods,
& driver_modes );
- filter_modes( & configs->configs,
- driver_modes );
+ filter_modes(&psc->configs, driver_modes);
_gl_context_modes_destroy( driver_modes );
}
}
@@ -999,6 +996,7 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc,
return psp;
}
+
#endif /* GLX_DIRECT_RENDERING */
@@ -1169,6 +1167,16 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
UnlockDisplay(dpy);
#ifdef GLX_DIRECT_RENDERING
+ psc->scr = i;
+ psc->dpy = dpy;
+ /* Create drawable hash */
+ psc->drawHash = __glxHashCreate();
+ if ( psc->drawHash == NULL ) {
+ SyncHandle();
+ FreeScreenConfigs(priv);
+ return GL_FALSE;
+ }
+
/* Initialize per screen dynamic client GLX extensions */
psc->ext_list_first_time = GL_TRUE;
/* Initialize the direct rendering per screen data and functions */
@@ -1179,11 +1187,12 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
if (priv->driDisplay.createNewScreen &&
priv->driDisplay.createNewScreen[i]) {
- psc->driScreen.screenConfigs = (void *)psc;
psc->driScreen.private =
- CallCreateNewScreen(dpy, i, & psc->driScreen,
+ CallCreateNewScreen(dpy, i, psc,
& priv->driDisplay,
priv->driDisplay.createNewScreen[i] );
+ if (psc->driScreen.private != NULL)
+ __glXScrEnableDRIExtension(psc);
}
}
#endif
@@ -1506,33 +1515,6 @@ PUBLIC GLXDrawable glXGetCurrentDrawable(void)
/************************************************************************/
-#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 );
@@ -1617,20 +1599,71 @@ static Bool SendMakeCurrentRequest(Display *dpy, CARD8 opcode,
#ifdef GLX_DIRECT_RENDERING
+static __DRIdrawable *
+FetchDRIDrawable( Display *dpy, GLXDrawable drawable, GLXContext gc)
+{
+ __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
+ __GLXdrawable *pdraw;
+ __GLXscreenConfigs *sc;
+ drm_drawable_t hwDrawable;
+ void *empty_attribute_list = NULL;
+
+ if (priv == NULL || priv->driDisplay.private == NULL)
+ return NULL;
+
+ sc = &priv->screenConfigs[gc->screen];
+ if (__glxHashLookup(sc->drawHash, drawable, (void *) &pdraw) == 0)
+ return &pdraw->driDrawable;
+
+ /* Allocate a new drawable */
+ pdraw = Xmalloc(sizeof(*pdraw));
+ if (!pdraw)
+ return NULL;
+
+ pdraw->drawable = drawable;
+ pdraw->psc = sc;
+
+ if (!XF86DRICreateDrawable(dpy, sc->scr, drawable, &hwDrawable))
+ return NULL;
+
+ /* Create a new drawable */
+ pdraw->driDrawable.private =
+ (*sc->driScreen.createNewDrawable)(&sc->driScreen,
+ gc->mode,
+ &pdraw->driDrawable,
+ hwDrawable,
+ GLX_WINDOW_BIT,
+ empty_attribute_list);
+
+ if (!pdraw->driDrawable.private) {
+ XF86DRIDestroyDrawable(dpy, sc->scr, drawable);
+ Xfree(pdraw);
+ return NULL;
+ }
+
+ if (__glxHashInsert(sc->drawHash, drawable, pdraw)) {
+ (*pdraw->driDrawable.destroyDrawable)(&pdraw->driDrawable);
+ XF86DRIDestroyDrawable(dpy, sc->scr, drawable);
+ Xfree(pdraw);
+ return NULL;
+ }
+
+ return &pdraw->driDrawable;
+}
+
static Bool BindContextWrapper( Display *dpy, GLXContext gc,
GLXDrawable draw, GLXDrawable read )
{
- return (*gc->driContext.bindContext)(dpy, gc->screen, draw, read,
- & gc->driContext);
+ __DRIdrawable *pdraw = FetchDRIDrawable(dpy, draw, gc);
+ __DRIdrawable *pread = FetchDRIDrawable(dpy, read, gc);
+
+ return (*gc->driContext.bindContext)(&gc->driContext, pdraw, pread);
}
static Bool UnbindContextWrapper( GLXContext gc )
{
- return (*gc->driContext.unbindContext)(gc->currentDpy, gc->screen,
- gc->currentDrawable,
- gc->currentReadable,
- & gc->driContext );
+ return (*gc->driContext.unbindContext)(&gc->driContext);
}
#endif /* GLX_DIRECT_RENDERING */
@@ -1742,7 +1775,10 @@ USED static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw,
if (oldGC->isDirect) {
if (oldGC->driContext.private) {
(*oldGC->driContext.destroyContext)
- (dpy, oldGC->screen, oldGC->driContext.private);
+ (&oldGC->driContext);
+ XF86DRIDestroyContext(oldGC->createDpy,
+ oldGC->psc->scr,
+ gc->hwContextID);
oldGC->driContext.private = NULL;
}
}
diff --git a/src/glx/x11/glxextensions.c b/src/glx/x11/glxextensions.c
index 1d99b61db0..84f556e0cc 100644
--- a/src/glx/x11/glxextensions.c
+++ b/src/glx/x11/glxextensions.c
@@ -356,28 +356,71 @@ __glXProcessServerString( const struct extension_info * ext,
}
}
+#ifdef GLX_DIRECT_RENDERING
-/**
- * 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 )
+__glXScrEnableDRIExtension(__GLXscreenConfigs *psc)
{
- __glXExtensionsCtr();
- __glXExtensionsCtrScreen(psc);
- set_glx_extension( known_glx_extensions, name, strlen( name ), GL_TRUE,
- psc->direct_support );
+ const __DRIextension **extensions;
+ int i;
+
+ __glXExtensionsCtr();
+ __glXExtensionsCtrScreen(psc);
+
+ extensions = psc->driScreen.getExtensions(&psc->driScreen);
+ for (i = 0; extensions[i]; i++) {
+#ifdef __DRI_COPY_SUB_BUFFER
+ if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
+ psc->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
+ SET_BIT(psc->direct_support, MESA_copy_sub_buffer_bit);
+ }
+#endif
+
+#ifdef __DRI_SWAP_CONTROL
+ if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
+ psc->swapControl = (__DRIswapControlExtension *) extensions[i];
+ SET_BIT(psc->direct_support, SGI_swap_control_bit);
+ SET_BIT(psc->direct_support, MESA_swap_control_bit);
+ }
+#endif
+
+#ifdef __DRI_ALLOCATE
+ if (strcmp(extensions[i]->name, __DRI_ALLOCATE) == 0) {
+ psc->allocate = (__DRIallocateExtension *) extensions[i];
+ SET_BIT(psc->direct_support, MESA_allocate_memory_bit);
+ }
+#endif
+
+#ifdef __DRI_FRAME_TRACKING
+ if (strcmp(extensions[i]->name, __DRI_FRAME_TRACKING) == 0) {
+ psc->frameTracking = (__DRIframeTrackingExtension *) extensions[i];
+ SET_BIT(psc->direct_support, MESA_swap_frame_usage_bit);
+ }
+#endif
+
+#ifdef __DRI_MEDIA_STREAM_COUNTER
+ if (strcmp(extensions[i]->name, __DRI_MEDIA_STREAM_COUNTER) == 0) {
+ psc->msc = (__DRImediaStreamCounterExtension *) extensions[i];
+ SET_BIT(psc->direct_support, SGI_video_sync_bit);
+ }
+#endif
+
+#ifdef __DRI_SWAP_BUFFER_COUNTER
+ /* No driver supports this at this time and the extension is
+ * not defined in dri_interface.h. Will enable
+ * GLX_OML_sync_control if implemented. */
+#endif
+
+#ifdef __DRI_READ_DRAWABLE
+ if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
+ SET_BIT(psc->direct_support, SGI_make_current_read_bit);
+ }
+#endif
+ /* Ignore unknown extensions */
+ }
}
+#endif
/**
* Initialize global extension support tables.
diff --git a/src/glx/x11/glxextensions.h b/src/glx/x11/glxextensions.h
index a4241b6b7f..144b02ad03 100644
--- a/src/glx/x11/glxextensions.h
+++ b/src/glx/x11/glxextensions.h
@@ -234,7 +234,11 @@ 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 );
+
+#ifdef GLX_DIRECT_RENDERING
+extern void __glXScrEnableDRIExtension( struct __GLXscreenConfigsRec *psc );
+#endif
+
extern void __glXCalculateUsableGLExtensions( struct __GLXcontextRec * gc,
const char * server_string, int major_version, int minor_version );
extern void __glXGetGLVersion( int * major_version, int * minor_version );
diff --git a/src/glx/x11/glxhash.c b/src/glx/x11/glxhash.c
new file mode 100644
index 0000000000..1b284c5f45
--- /dev/null
+++ b/src/glx/x11/glxhash.c
@@ -0,0 +1,411 @@
+/* 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"
+
+#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 entries;
+ 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;
+}
+
+__glxHashTable *__glxHashCreate(void)
+{
+ __glxHashTablePtr table;
+ int i;
+
+ table = HASH_ALLOC(sizeof(*table));
+ if (!table) return NULL;
+ table->magic = HASH_MAGIC;
+ table->entries = 0;
+ table->hits = 0;
+ table->partials = 0;
+ table->misses = 0;
+
+ for (i = 0; i < HASH_SIZE; i++) table->buckets[i] = NULL;
+ return table;
+}
+
+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;
+}
+
+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 */
+}
+
+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 */
+}
+
+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;
+}
+
+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;
+}
+
+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("Entries = %ld, hits = %ld, partials = %ld, misses = %ld\n",
+ table->entries, 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/xf86dri.h b/src/glx/x11/xf86dri.h
index 0a2bb24971..69a2d74fb2 100644
--- a/src/glx/x11/xf86dri.h
+++ b/src/glx/x11/xf86dri.h
@@ -94,14 +94,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/xf86dristr.h b/src/glx/x11/xf86dristr.h
index ac05b183b3..7e8bc557d3 100644
--- a/src/glx/x11/xf86dristr.h
+++ b/src/glx/x11/xf86dristr.h
@@ -50,9 +50,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* 4.0.0: Original
* 4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02
* 4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02
+ * 5.0.0: Drop XIDs from DRI interface.
*/
-#define XF86DRI_MAJOR_VERSION 4
-#define XF86DRI_MINOR_VERSION 1
+#define XF86DRI_MAJOR_VERSION 5
+#define XF86DRI_MINOR_VERSION 0
#define XF86DRI_PATCH_VERSION 0
typedef struct _XF86DRIQueryVersion {