DRI2: Drop sarea, implement swap buffers in the X server.
[mesa.git] / src / glx / x11 / glxcmds.c
index d4f579d01acd35f9d04ca87f4464eb68e54c1682..9197130dcaa13beba93845f121e5d06345aefc03 100644 (file)
  * 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
 
 
@@ -265,9 +312,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
@@ -313,6 +360,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;
@@ -326,41 +377,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
@@ -377,7 +423,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;
@@ -391,7 +441,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;
@@ -409,7 +463,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);
@@ -431,7 +489,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);
@@ -467,15 +525,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();
@@ -553,7 +611,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
@@ -589,7 +647,7 @@ PUBLIC void glXWaitX(void)
     __glXFlushRenderBuffer(gc, gc->pc);
 
 #ifdef GLX_DIRECT_RENDERING
-    if (gc->isDirect) {
+    if (gc->driContext) {
        XSync(dpy, False);
        return;
     }
@@ -619,7 +677,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;
     }
@@ -659,7 +717,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
@@ -731,7 +789,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
     }
@@ -794,10 +852,11 @@ 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) {
+       glFlush();          
+       (*pdraw->psc->driScreen->swapBuffers)(pdraw);
        return;
     }
 #endif
@@ -841,12 +900,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 ) {
@@ -1224,7 +1283,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)) ) {
@@ -1269,7 +1328,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
@@ -1448,13 +1507,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++;
@@ -1479,7 +1540,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;
     }
@@ -1488,13 +1553,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);
@@ -1592,6 +1657,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)
@@ -1616,8 +1682,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++;
+               }
            }
        }
     }
@@ -1650,18 +1718,10 @@ PUBLIC XVisualInfo *glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config)
 }
 
 
-/*
-** GLX_SGI_make_current_read
-*/
-
-PUBLIC GLX_ALIAS(GLXDrawable, glXGetCurrentReadDrawableSGI, (void), (),
-         glXGetCurrentReadDrawable)
-
-
 /*
 ** GLX_SGI_swap_control
 */
-PUBLIC int glXSwapIntervalSGI(int interval)
+static int __glXSwapIntervalSGI(int interval)
 {
    xGLXVendorPrivateReq *req;
    GLXContext gc = __glXGetCurrentContext();
@@ -1677,16 +1737,15 @@ PUBLIC 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 {
@@ -1708,7 +1767,7 @@ PUBLIC int glXSwapIntervalSGI(int interval)
    req->vendorCode = X_GLXvop_SwapIntervalSGI;
    req->contextTag = gc->currentContextTag;
 
-   interval_ptr = (CARD32 *) req + 1;
+   interval_ptr = (CARD32 *) (req + 1);
    *interval_ptr = interval;
 
    UnlockDisplay(dpy);
@@ -1722,27 +1781,24 @@ PUBLIC int glXSwapIntervalSGI(int interval)
 /*
 ** GLX_MESA_swap_control
 */
-PUBLIC int glXSwapIntervalMESA(unsigned 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;
         }
       }
@@ -1755,23 +1811,20 @@ PUBLIC int glXSwapIntervalMESA(unsigned int interval)
 }
  
 
-PUBLIC int glXGetSwapIntervalMESA(void)
+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);
         }
       }
    }
@@ -1785,18 +1838,16 @@ PUBLIC int glXGetSwapIntervalMESA(void)
 ** GLX_MESA_swap_frame_usage
 */
 
-PUBLIC GLint glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable)
+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;
@@ -1805,18 +1856,17 @@ PUBLIC GLint glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable)
 }
 
     
-PUBLIC GLint glXEndFrameTrackingMESA(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;
@@ -1825,23 +1875,24 @@ PUBLIC GLint glXEndFrameTrackingMESA(Display *dpy, GLXDrawable drawable)
 }
 
 
-PUBLIC GLint glXGetFrameUsageMESA(Display *dpy, GLXDrawable drawable,
-                                 GLfloat *usage)
+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;
@@ -1852,23 +1903,22 @@ PUBLIC GLint glXGetFrameUsageMESA(Display *dpy, GLXDrawable drawable,
 }
 
 
-PUBLIC GLint glXQueryFrameTrackingMESA(Display *dpy, GLXDrawable drawable,
-                                      int64_t *sbc, int64_t *missedFrames,
-                                      GLfloat *lastMissedUsage)
+static GLint __glXQueryFrameTrackingMESA(Display *dpy, GLXDrawable drawable,
+                                        int64_t *sbc, int64_t *missedFrames,
+                                        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;
@@ -1884,27 +1934,30 @@ PUBLIC GLint glXQueryFrameTrackingMESA(Display *dpy, GLXDrawable drawable,
 /*
 ** GLX_SGI_video_sync
 */
-PUBLIC int glXGetVideoSyncSGI(unsigned int *count)
+static int __glXGetVideoSyncSGI(unsigned int *count)
 {
    /* FIXME: Looking at the GLX_SGI_video_sync spec in the extension registry,
     * 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
@@ -1913,34 +1966,28 @@ PUBLIC int glXGetVideoSyncSGI(unsigned int *count)
    return GLX_BAD_CONTEXT;
 }
 
-PUBLIC int glXWaitVideoSyncSGI(int divisor, int remainder, 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
@@ -1950,33 +1997,6 @@ PUBLIC int glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
 }
 
 
-/*
-** GLX_SGIS_video_source
-*/
-#if defined(_VL_H)
-
-PUBLIC GLXVideoSourceSGIX glXCreateGLXVideoSourceSGIX(Display *dpy,
-                                     int screen, VLServer server, VLPath path,
-                                     int nodeClass, VLNode drainNode)
-{
-   (void) dpy;
-   (void) screen;
-   (void) server;
-   (void) path;
-   (void) nodeClass;
-   (void) drainNode;
-   return 0;
-}
-
-PUBLIC void glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
-{
-   (void) dpy;
-   (void) src;
-}
-
-#endif
-
-
 /*
 ** GLX_SGIX_fbconfig
 ** Many of these functions are aliased to GLX 1.3 entry points in the 
@@ -2081,100 +2101,11 @@ PUBLIC GLXFBConfigSGIX glXGetFBConfigFromVisualSGIX(Display *dpy,
 }
 
 
-/*
-** GLX_SGI_cushion
-*/
-PUBLIC void glXCushionSGI(Display *dpy, Window win, float cushion)
-{
-   (void) dpy;
-   (void) win;
-   (void) cushion;
-}
-
-
-/*
-** GLX_SGIX_video_resize
-*/
-PUBLIC int glXBindChannelToWindowSGIX(Display *dpy, int screen,
-                                     int channel , Window window)
-{
-   (void) dpy;
-   (void) screen;
-   (void) channel;
-   (void) window;
-   return 0;
-}
-
-PUBLIC int glXChannelRectSGIX(Display *dpy, int screen, int channel,
-                             int x, int y, int w, int h)
-{
-   (void) dpy;
-   (void) screen;
-   (void) channel;
-   (void) x;
-   (void) y;
-   (void) w;
-   (void) h;
-   return 0;
-}
-
-PUBLIC int glXQueryChannelRectSGIX(Display *dpy, int screen, int channel,
-                                  int *x, int *y, int *w, int *h)
-{
-   (void) dpy;
-   (void) screen;
-   (void) channel;
-   (void) x;
-   (void) y;
-   (void) w;
-   (void) h;
-   return 0;
-}
-
-int glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel,
-                             int *dx, int *dy, int *dw, int *dh)
-{
-   (void) dpy;
-   (void) screen;
-   (void) channel;
-   (void) dx;
-   (void) dy;
-   (void) dw;
-   (void) dh;
-   return 0;
-}
-
-PUBLIC int glXChannelRectSyncSGIX(Display *dpy, int screen,
-                                 int channel, GLenum synctype)
-{
-   (void) dpy;
-   (void) screen;
-   (void) channel;
-   (void) synctype;
-   return 0;
-}
-
-
-#if defined(_DM_BUFFER_H_)
-
-PUBLIC Bool glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer,
-                                     DMparams *params, DMbuffer dmbuffer)
-{
-   (void) dpy;
-   (void) pbuffer;
-   (void) params;
-   (void) dmbuffer;
-   return False;
-}
-
-#endif
-
-
 /*
 ** GLX_SGIX_swap_group
 */
-PUBLIC void glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable,
-                                GLXDrawable member)
+static void __glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable,
+                                  GLXDrawable member)
 {
    (void) dpy;
    (void) drawable;
@@ -2185,15 +2116,15 @@ PUBLIC void glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable,
 /*
 ** GLX_SGIX_swap_barrier
 */
-PUBLIC void glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable,
-                                  int barrier)
+static void __glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable,
+                                    int barrier)
 {
    (void) dpy;
    (void) drawable;
    (void) barrier;
 }
 
-PUBLIC Bool glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
+static Bool __glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
 {
    (void) dpy;
    (void) screen;
@@ -2202,40 +2133,25 @@ PUBLIC Bool glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
 }
 
 
-/*
-** GLX_SUN_get_transparent_index
-*/
-PUBLIC Status glXGetTransparentIndexSUN(Display *dpy, Window overlay,
-                                       Window underlay, long *pTransparent)
-{
-   (void) dpy;
-   (void) overlay;
-   (void) underlay;
-   (void) pTransparent;
-   return 0;
-}
-
-
 /*
 ** GLX_OML_sync_control
 */
-PUBLIC Bool glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable,
-                               int64_t *ust, int64_t *msc, int64_t *sbc)
+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;
@@ -2247,6 +2163,68 @@ PUBLIC 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.
@@ -2264,70 +2242,17 @@ PUBLIC Bool glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable,
  *       when GLX_OML_sync_control appears in the client extension string.
  */
 
-PUBLIC 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;
+    __GLXDRIdrawable *draw = GetGLXDRIDrawable(dpy, drawable, NULL);
 
-# 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;
+    if (draw == NULL)
+       return False;
 
-        (void) drawable;
-        return True;
-      }
-   }
+    return __driGetMscRateOML(draw->driDrawable, numerator, denominator, draw);
 #else
    (void) dpy;
    (void) drawable;
@@ -2338,13 +2263,13 @@ PUBLIC Bool glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
 }
 
 
-PUBLIC int64_t glXSwapBuffersMscOML(Display *dpy, GLXDrawable drawable,
-                                   int64_t target_msc, int64_t divisor,
-                                   int64_t remainder)
+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
@@ -2357,11 +2282,10 @@ PUBLIC 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;
@@ -2373,14 +2297,14 @@ PUBLIC int64_t glXSwapBuffersMscOML(Display *dpy, GLXDrawable drawable,
 }
 
 
-PUBLIC Bool glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
-                            int64_t target_msc, int64_t divisor,
-                            int64_t remainder, int64_t *ust,
-                            int64_t *msc, int64_t *sbc)
+static Bool __glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
+                              int64_t target_msc, int64_t divisor,
+                              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;
 
@@ -2392,10 +2316,9 @@ PUBLIC 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.
@@ -2416,13 +2339,13 @@ PUBLIC Bool glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
 }
 
 
-PUBLIC Bool glXWaitForSbcOML(Display * dpy, GLXDrawable drawable,
-                            int64_t target_sbc, int64_t *ust,
-                            int64_t *msc, int64_t *sbc )
+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;
 
@@ -2432,9 +2355,8 @@ PUBLIC 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.
@@ -2462,16 +2384,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;
@@ -2487,14 +2406,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;
@@ -2506,14 +2423,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;
@@ -2552,7 +2467,7 @@ PUBLIC GLuint glXGetMemoryOffsetMESA( Display *dpy, int scrn,
  *     glXDestroyPbuffer glXDestroyPixmap glXDestroyWindow
  *     glXDestroyGLXPbufferSGIX glXDestroyGLXVideoSourceSGIX
  */
-PUBLIC Bool glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
+static Bool __glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
 {
    (void) dpy;
    (void) d;
@@ -2569,51 +2484,124 @@ PUBLIC GLXPixmap glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visual,
    (void) cmap;
    return 0;
 }
+/*@}*/
 
 
-PUBLIC void glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable,
-                                int x, int y, int width, int height)
+/**
+ * GLX_MESA_copy_sub_buffer
+ */
+#define X_GLXvop_CopySubBufferMESA 5154 /* temporary */
+static void __glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable,
+                                  int x, int y, int width, int height)
 {
-   (void) dpy;
-   (void) drawable;
-   (void) x;
-   (void) y;
-   (void) width;
-   (void) height;
-}
+    xGLXVendorPrivateReq *req;
+    GLXContext gc;
+    GLXContextTag tag;
+    CARD32 *drawable_ptr;
+    INT32 *x_ptr, *y_ptr, *w_ptr, *h_ptr;
+    CARD8 opcode;
 
+#ifdef __DRI_COPY_SUB_BUFFER
+    int screen;
+    __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
+    if ( pdraw != NULL ) {
+       __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
+       if (psc->copySubBuffer != NULL) {
+           (*psc->copySubBuffer->copySubBuffer)(pdraw->driDrawable,
+                                                x, y, width, height);
+       }
 
-PUBLIC Bool glXSet3DfxModeMESA( int mode )
-{
-   (void) mode;
-   return GL_FALSE;
+       return;
+    }
+#endif
+
+    opcode = __glXSetupForCommand(dpy);
+    if (!opcode)
+       return;
+
+    /*
+    ** The calling thread may or may not have a current context.  If it
+    ** does, send the context tag so the server can do a flush.
+    */
+    gc = __glXGetCurrentContext();
+    if ((gc != NULL) && (dpy == gc->currentDpy) &&
+       ((drawable == gc->currentDrawable) ||
+        (drawable == gc->currentReadable)) ) {
+       tag = gc->currentContextTag;
+    } else {
+       tag = 0;
+    }
+
+    LockDisplay(dpy);
+    GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32) * 4,req);
+    req->reqType = opcode;
+    req->glxCode = X_GLXVendorPrivate;
+    req->vendorCode = X_GLXvop_CopySubBufferMESA;
+    req->contextTag = tag;
+
+    drawable_ptr = (CARD32 *) (req + 1);
+    x_ptr = (INT32 *) (drawable_ptr + 1);
+    y_ptr = (INT32 *) (drawable_ptr + 2);
+    w_ptr = (INT32 *) (drawable_ptr + 3);
+    h_ptr = (INT32 *) (drawable_ptr + 4);
+
+    *drawable_ptr = drawable;
+    *x_ptr = x;
+    *y_ptr = y;
+    *w_ptr = width;
+    *h_ptr = height;
+
+    UnlockDisplay(dpy);
+    SyncHandle();
 }
-/*@}*/
 
-PUBLIC Bool glXBindTexImageEXT(Display *dpy,
-                              GLXDrawable drawable,
-                              int buffer)
+
+/**
+ * GLX_EXT_texture_from_pixmap
+ */
+/*@{*/
+static void __glXBindTexImageEXT(Display *dpy,
+                                GLXDrawable drawable,
+                                int buffer,
+                                const int *attrib_list)
 {
     xGLXVendorPrivateReq *req;
     GLXContext gc = __glXGetCurrentContext();
     CARD32 *drawable_ptr;
     INT32 *buffer_ptr;
+    CARD32 *num_attrib_ptr;
+    CARD32 *attrib_ptr;
     CARD8 opcode;
+    unsigned int i;
 
     if (gc == NULL)
-       return False;
+       return;
 
+    i = 0;
+    if (attrib_list) {
+       while (attrib_list[i * 2] != None)
+           i++;
+    }
 #ifdef GLX_DIRECT_RENDERING
-    if (gc->isDirect)
-       return False;
+    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);
     if (!opcode)
-       return False;
+       return;
 
     LockDisplay(dpy);
-    GetReqExtra(GLXVendorPrivate, sizeof(CARD32)+sizeof(INT32),req);
+    GetReqExtra(GLXVendorPrivate, 12 + 8 * i,req);
     req->reqType = opcode;
     req->glxCode = X_GLXVendorPrivate;
     req->vendorCode = X_GLXvop_BindTexImageEXT;
@@ -2621,19 +2609,30 @@ PUBLIC Bool glXBindTexImageEXT(Display *dpy,
 
     drawable_ptr = (CARD32 *) (req + 1);
     buffer_ptr = (INT32 *) (drawable_ptr + 1);
+    num_attrib_ptr = (CARD32 *) (buffer_ptr + 1);
+    attrib_ptr = (CARD32 *) (num_attrib_ptr + 1);
 
     *drawable_ptr = drawable;
     *buffer_ptr = buffer;
+    *num_attrib_ptr = (CARD32) i;
+
+    i = 0;
+    if (attrib_list) {
+       while (attrib_list[i * 2] != None)
+       {
+           *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 0];
+           *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 1];
+           i++;
+       }
+    }
 
     UnlockDisplay(dpy);
     SyncHandle();
-
-    return True;
 }
 
-PUBLIC Bool glXReleaseTexImageEXT(Display *dpy,
-                                 GLXDrawable drawable,
-                                 int buffer)
+static void __glXReleaseTexImageEXT(Display *dpy,
+                                   GLXDrawable drawable,
+                                   int buffer)
 {
     xGLXVendorPrivateReq *req;
     GLXContext gc = __glXGetCurrentContext();
@@ -2642,16 +2641,16 @@ PUBLIC Bool glXReleaseTexImageEXT(Display *dpy,
     CARD8 opcode;
 
     if (gc == NULL)
-       return False;
+       return;
 
 #ifdef GLX_DIRECT_RENDERING
-    if (gc->isDirect)
-       return False;
+    if (gc->driContext)
+       return;
 #endif
 
     opcode = __glXSetupForCommand(dpy);
     if (!opcode)
-       return False;
+       return;
 
     LockDisplay(dpy);
     GetReqExtra(GLXVendorPrivate, sizeof(CARD32)+sizeof(INT32),req);
@@ -2668,9 +2667,8 @@ PUBLIC Bool glXReleaseTexImageEXT(Display *dpy,
 
     UnlockDisplay(dpy);
     SyncHandle();
-
-    return True;
 }
+/*@}*/
 
 /**
  * \c strdup is actually not a standard ANSI C or POSIX routine.
@@ -2678,7 +2676,7 @@ PUBLIC Bool glXReleaseTexImageEXT(Display *dpy,
  * 
  * \sa strdup
  */
-char *
+_X_HIDDEN char *
 __glXstrdup(const char *str)
 {
    char *copy;
@@ -2749,22 +2747,16 @@ static const struct name_address_pair GLX_functions[] = {
    GLX_FUNCTION( glXSelectEvent ),
 
    /*** GLX_SGI_swap_control ***/
-   GLX_FUNCTIONglXSwapIntervalSGI ),
+   GLX_FUNCTION2( glXSwapIntervalSGI, __glXSwapIntervalSGI ),
 
    /*** GLX_SGI_video_sync ***/
-   GLX_FUNCTIONglXGetVideoSyncSGI ),
-   GLX_FUNCTIONglXWaitVideoSyncSGI ),
+   GLX_FUNCTION2( glXGetVideoSyncSGI, __glXGetVideoSyncSGI ),
+   GLX_FUNCTION2( glXWaitVideoSyncSGI, __glXWaitVideoSyncSGI ),
 
    /*** GLX_SGI_make_current_read ***/
    GLX_FUNCTION2( glXMakeCurrentReadSGI, glXMakeContextCurrent ),
    GLX_FUNCTION2( glXGetCurrentReadDrawableSGI, glXGetCurrentReadDrawable ),
 
-   /*** GLX_SGIX_video_source ***/
-#if defined(_VL_H)
-   GLX_FUNCTION( glXCreateGLXVideoSourceSGIX ),
-   GLX_FUNCTION( glXDestroyGLXVideoSourceSGIX ),
-#endif
-
    /*** GLX_EXT_import_context ***/
    GLX_FUNCTION( glXFreeContextEXT ),
    GLX_FUNCTION( glXGetContextIDEXT ),
@@ -2787,30 +2779,12 @@ static const struct name_address_pair GLX_functions[] = {
    GLX_FUNCTION( glXSelectEventSGIX ),
    GLX_FUNCTION( glXGetSelectedEventSGIX ),
 
-   /*** GLX_SGI_cushion ***/
-   GLX_FUNCTION( glXCushionSGI ),
-
-   /*** GLX_SGIX_video_resize ***/
-   GLX_FUNCTION( glXBindChannelToWindowSGIX ),
-   GLX_FUNCTION( glXChannelRectSGIX ),
-   GLX_FUNCTION( glXQueryChannelRectSGIX ),
-   GLX_FUNCTION( glXQueryChannelDeltasSGIX ),
-   GLX_FUNCTION( glXChannelRectSyncSGIX ),
-
-   /*** GLX_SGIX_dmbuffer **/
-#if defined(_DM_BUFFER_H_)
-   GLX_FUNCTION( glXAssociateDMPbufferSGIX ),
-#endif
-
    /*** GLX_SGIX_swap_group ***/
-   GLX_FUNCTIONglXJoinSwapGroupSGIX ),
+   GLX_FUNCTION2( glXJoinSwapGroupSGIX, __glXJoinSwapGroupSGIX ),
 
    /*** GLX_SGIX_swap_barrier ***/
-   GLX_FUNCTION( glXBindSwapBarrierSGIX ),
-   GLX_FUNCTION( glXQueryMaxSwapBarriersSGIX ),
-
-   /*** GLX_SUN_get_transparent_index ***/
-   GLX_FUNCTION( glXGetTransparentIndexSUN ),
+   GLX_FUNCTION2( glXBindSwapBarrierSGIX, __glXBindSwapBarrierSGIX ),
+   GLX_FUNCTION2( glXQueryMaxSwapBarriersSGIX, __glXQueryMaxSwapBarriersSGIX ),
 
    /*** GLX_MESA_allocate_memory ***/
    GLX_FUNCTION( glXAllocateMemoryMESA ),
@@ -2818,26 +2792,23 @@ static const struct name_address_pair GLX_functions[] = {
    GLX_FUNCTION( glXGetMemoryOffsetMESA ),
 
    /*** GLX_MESA_copy_sub_buffer ***/
-   GLX_FUNCTIONglXCopySubBufferMESA ),
+   GLX_FUNCTION2( glXCopySubBufferMESA, __glXCopySubBufferMESA ),
 
    /*** GLX_MESA_pixmap_colormap ***/
    GLX_FUNCTION( glXCreateGLXPixmapMESA ),
 
    /*** GLX_MESA_release_buffers ***/
-   GLX_FUNCTION( glXReleaseBuffersMESA ),
-
-   /*** GLX_MESA_set_3dfx_mode ***/
-   GLX_FUNCTION( glXSet3DfxModeMESA ),
+   GLX_FUNCTION2( glXReleaseBuffersMESA, __glXReleaseBuffersMESA ),
 
    /*** GLX_MESA_swap_control ***/
-   GLX_FUNCTIONglXSwapIntervalMESA ),
-   GLX_FUNCTIONglXGetSwapIntervalMESA ),
+   GLX_FUNCTION2( glXSwapIntervalMESA, __glXSwapIntervalMESA ),
+   GLX_FUNCTION2( glXGetSwapIntervalMESA, __glXGetSwapIntervalMESA ),
 
    /*** GLX_MESA_swap_frame_usage ***/
-   GLX_FUNCTIONglXBeginFrameTrackingMESA ),
-   GLX_FUNCTIONglXEndFrameTrackingMESA ),
-   GLX_FUNCTIONglXGetFrameUsageMESA ),
-   GLX_FUNCTIONglXQueryFrameTrackingMESA ),
+   GLX_FUNCTION2( glXBeginFrameTrackingMESA, __glXBeginFrameTrackingMESA ),
+   GLX_FUNCTION2( glXEndFrameTrackingMESA, __glXEndFrameTrackingMESA ),
+   GLX_FUNCTION2( glXGetFrameUsageMESA, __glXGetFrameUsageMESA ),
+   GLX_FUNCTION2( glXQueryFrameTrackingMESA, __glXQueryFrameTrackingMESA ),
 
    /*** GLX_ARB_get_proc_address ***/
    GLX_FUNCTION( glXGetProcAddressARB ),
@@ -2846,15 +2817,15 @@ static const struct name_address_pair GLX_functions[] = {
    GLX_FUNCTION2( glXGetProcAddress, glXGetProcAddressARB ),
 
    /*** GLX_OML_sync_control ***/
-   GLX_FUNCTIONglXWaitForSbcOML ),
-   GLX_FUNCTIONglXWaitForMscOML ),
-   GLX_FUNCTIONglXSwapBuffersMscOML ),
-   GLX_FUNCTIONglXGetMscRateOML ),
-   GLX_FUNCTIONglXGetSyncValuesOML ),
+   GLX_FUNCTION2( glXWaitForSbcOML, __glXWaitForSbcOML ),
+   GLX_FUNCTION2( glXWaitForMscOML, __glXWaitForMscOML ),
+   GLX_FUNCTION2( glXSwapBuffersMscOML, __glXSwapBuffersMscOML ),
+   GLX_FUNCTION2( glXGetMscRateOML, __glXGetMscRateOML ),
+   GLX_FUNCTION2( glXGetSyncValuesOML, __glXGetSyncValuesOML ),
 
    /*** GLX_EXT_texture_from_pixmap ***/
-   GLX_FUNCTIONglXBindTexImageEXT ),
-   GLX_FUNCTIONglXReleaseTexImageEXT ),
+   GLX_FUNCTION2( glXBindTexImageEXT, __glXBindTexImageEXT ),
+   GLX_FUNCTION2( glXReleaseTexImageEXT, __glXReleaseTexImageEXT ),
 
 #ifdef GLX_DIRECT_RENDERING
    /*** DRI configuration ***/
@@ -2932,96 +2903,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.
-     */
-    return 20050727;
-}
-
-
-
-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
@@ -3036,7 +2917,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;