xserver: Branch 'master'

Kristian Høgsberg krh at kemper.freedesktop.org
Mon Mar 31 13:58:32 PDT 2008


 GL/glx/Makefile.am             |    2 
 GL/glx/glxcmds.c               |   51 ++--
 GL/glx/glxcontext.h            |    6 
 GL/glx/glxdrawable.h           |    2 
 GL/glx/glxdri.c                |  259 ++++++++++++-------------
 GL/glx/glxdri2.c               |  423 ++++++++++++++++++++++++++++-------------
 GL/glx/glxglcore.c             |   56 +++--
 GL/glx/glxscreens.c            |   55 +++--
 GL/glx/glxscreens.h            |   88 +++++++-
 GL/glx/glxutil.c               |    5 
 GL/glx/glxutil.h               |    2 
 GL/symlink-mesa.sh             |    2 
 configure.ac                   |    2 
 hw/xfree86/common/xf86Config.c |    1 
 hw/xfree86/dri2/Makefile.am    |    5 
 hw/xfree86/dri2/dri2.c         |  107 ++++++----
 hw/xfree86/dri2/dri2.h         |   16 -
 hw/xfree86/dri2/dri2ext.c      |  361 ++++++++++++++++++++++++++++++++++
 os/utils.c                     |    3 
 19 files changed, 1053 insertions(+), 393 deletions(-)

New commits:
commit c40e0b51f0d9ef5e1f30f233d7db1e6db9d6681b
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Wed Mar 26 19:28:09 2008 -0400

    Implement DRI2 direct rendering and update AIGLX to DRI interface changes.
    
    Get rid of glcontextmodes.[ch] from build, rename __GlcontextModes to
    __GLXcontext.  Drop all #includes of glcontextmodes.h and glcore.h.
    Drop the DRI context modes extension.
    
    Add protocol code to DRI2 module and load DRI2 extension by default.

diff --git a/GL/glx/Makefile.am b/GL/glx/Makefile.am
index 377d760..1d4719c 100644
--- a/GL/glx/Makefile.am
+++ b/GL/glx/Makefile.am
@@ -31,8 +31,6 @@ INCLUDES = \
 
 nodist_libglx_la_SOURCES = indirect_size.h \
 			   glapi.c \
-			   glcontextmodes.c \
-			   glcontextmode.h \
 			   glthread.c \
 			   indirect_dispatch.c \
 			   indirect_dispatch.h \
diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index 3b79cca..36aae61 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -50,7 +50,6 @@
 #include <windowstr.h>
 #include "glxutil.h"
 #include "glxext.h"
-#include "glcontextmodes.h"
 #include "glapitable.h"
 #include "glapi.h"
 #include "glthread.h"
@@ -83,9 +82,9 @@ validGlxScreen(ClientPtr client, int screen, __GLXscreen **pGlxScreen, int *err)
 
 static int
 validGlxFBConfig(ClientPtr client, __GLXscreen *pGlxScreen, XID id,
-		 __GLcontextModes **config, int *err)
+		 __GLXconfig **config, int *err)
 {
-    __GLcontextModes *m;
+    __GLXconfig *m;
 
     for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next)
 	if (m->fbconfigID == id) {
@@ -101,7 +100,7 @@ validGlxFBConfig(ClientPtr client, __GLXscreen *pGlxScreen, XID id,
 
 static int
 validGlxVisual(ClientPtr client, __GLXscreen *pGlxScreen, XID id,
-	       __GLcontextModes **config, int *err)
+	       __GLXconfig **config, int *err)
 {
     int i;
 
@@ -118,7 +117,7 @@ validGlxVisual(ClientPtr client, __GLXscreen *pGlxScreen, XID id,
 }
 
 static int
-validGlxFBConfigForWindow(ClientPtr client, __GLcontextModes *config,
+validGlxFBConfigForWindow(ClientPtr client, __GLXconfig *config,
 			  DrawablePtr pDraw, int *err)
 {
     ScreenPtr pScreen = pDraw->pScreen;
@@ -135,7 +134,7 @@ validGlxFBConfigForWindow(ClientPtr client, __GLcontextModes *config,
     }
 
     /* FIXME: What exactly should we check here... */
-    if (pVisual->class != _gl_convert_to_x_visual_type(config->visualType) ||
+    if (pVisual->class != glxConvertToXVisualType(config->visualType) ||
 	!(config->drawableType & GLX_WINDOW_BIT)) {
 	client->errorValue = pDraw->id;
 	*err = BadMatch;
@@ -161,7 +160,7 @@ static void __glXdirectContextDestroy(__GLXcontext *context)
 }
 
 static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen,
-					      __GLcontextModes *modes,
+					      __GLXconfig *modes,
 					      __GLXcontext *shareContext)
 {
     __GLXcontext *context;
@@ -186,7 +185,7 @@ static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen,
 
 static int
 DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
-		GLXContextID shareList, __GLcontextModes *config,
+		GLXContextID shareList, __GLXconfig *config,
 		__GLXscreen *pGlxScreen, GLboolean isDirect)
 {
     ClientPtr client = cl->client;
@@ -248,7 +247,7 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
     ** a GL core that needs windowing information (e.g., Mesa).
     */
     glxc->pGlxScreen = pGlxScreen;
-    glxc->modes = config;
+    glxc->config = config;
 
     /*
     ** Register this context as a resource.
@@ -276,7 +275,7 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
 int __glXDisp_CreateContext(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
-    __GLcontextModes *config;
+    __GLXconfig *config;
     __GLXscreen *pGlxScreen;
     int err;
 
@@ -292,7 +291,7 @@ int __glXDisp_CreateContext(__GLXclientState *cl, GLbyte *pc)
 int __glXDisp_CreateNewContext(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
-    __GLcontextModes *config;
+    __GLXconfig *config;
     __GLXscreen *pGlxScreen;
     int err;
 
@@ -309,7 +308,7 @@ int __glXDisp_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateContextWithConfigSGIXReq *req = 
 	(xGLXCreateContextWithConfigSGIXReq *) pc;
-    __GLcontextModes *config;
+    __GLXconfig *config;
     __GLXscreen *pGlxScreen;
     int err;
 
@@ -462,7 +461,7 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
      * GLXPixmap and we just return the __GLXdrawable.  */
     pGlxDraw = (__GLXdrawable *) LookupIDByType(drawId, __glXDrawableRes);
     if (pGlxDraw != NULL) {
-	if (glxc != NULL && pGlxDraw->modes != glxc->modes) {
+	if (glxc != NULL && pGlxDraw->config != glxc->config) {
 	    client->errorValue = drawId;
 	    *error = BadMatch;
 	    return NULL;
@@ -497,12 +496,12 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
      * the context screen and that the context fbconfig is compatible
      * with the window visual. */
     if (pDraw->pScreen != glxc->pGlxScreen->pScreen ||
-	!validGlxFBConfigForWindow(client, glxc->modes, pDraw, error))
+	!validGlxFBConfigForWindow(client, glxc->config, pDraw, error))
 	return NULL;
 
     pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen,
 						pDraw, GLX_DRAWABLE_WINDOW,
-						drawId, glxc->modes);
+						drawId, glxc->config);
 
     /* since we are creating the drawablePrivate, drawId should be new */
     if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) {
@@ -878,7 +877,7 @@ int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
     ClientPtr client = cl->client;
     xGLXGetVisualConfigsReply reply;
     __GLXscreen *pGlxScreen;
-    __GLcontextModes *modes;
+    __GLXconfig *modes;
     CARD32 buf[__GLX_TOTAL_CONFIG];
     int p, i, err;
     __GLX_DECLARE_SWAP_VARIABLES;
@@ -907,7 +906,7 @@ int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
 
 	p = 0;
 	buf[p++] = modes->visualID;
-	buf[p++] = _gl_convert_to_x_visual_type( modes->visualType );
+	buf[p++] = glxConvertToXVisualType( modes->visualType );
 	buf[p++] = modes->rgbMode;
 
 	buf[p++] = modes->redBits;
@@ -980,7 +979,7 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen)
     __GLXscreen *pGlxScreen;
     CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH];
     int p, err;
-    __GLcontextModes *modes;
+    __GLXconfig *modes;
     __GLX_DECLARE_SWAP_VARIABLES;
     __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
 
@@ -1062,7 +1061,7 @@ int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
 }
 
 static int 
-DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLcontextModes *config,
+DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config,
 		    DrawablePtr pDraw, XID glxDrawableId, int type)
 {
     __GLXdrawable *pGlxDraw;
@@ -1086,7 +1085,7 @@ DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLcontextModes
 }
 
 static int
-DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLcontextModes *config,
+DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config,
 		  XID drawableId, XID glxDrawableId)
 {
     DrawablePtr pDraw;
@@ -1144,7 +1143,7 @@ determineTextureTarget(XID glxDrawableID, CARD32 *attribs, CARD32 numAttribs)
 int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
-    __GLcontextModes *config;
+    __GLXconfig *config;
     __GLXscreen *pGlxScreen;
     int err;
 
@@ -1160,7 +1159,7 @@ int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
 int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
-    __GLcontextModes *config;
+    __GLXconfig *config;
     __GLXscreen *pGlxScreen;
     int err;
 
@@ -1184,7 +1183,7 @@ int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateGLXPixmapWithConfigSGIXReq *req = 
 	(xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
-    __GLcontextModes *config;
+    __GLXconfig *config;
     __GLXscreen *pGlxScreen;
     int err;
 
@@ -1246,7 +1245,7 @@ static int
 DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
 		int width, int height, XID glxDrawableId)
 {
-    __GLcontextModes	*config;
+    __GLXconfig	*config;
     __GLXscreen		*pGlxScreen;
     PixmapPtr		 pPixmap;
     int			 err;
@@ -1359,7 +1358,7 @@ int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
 int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
 {
     xGLXCreateWindowReq	*req = (xGLXCreateWindowReq *) pc;
-    __GLcontextModes	*config;
+    __GLXconfig	*config;
     __GLXscreen		*pGlxScreen;
     ClientPtr		 client = cl->client;
     DrawablePtr		 pDraw;
@@ -1473,7 +1472,7 @@ DoQueryContext(__GLXclientState *cl, GLXContextID gcId)
     *pSendBuf++ = GLX_SHARE_CONTEXT_EXT;
     *pSendBuf++ = (int)(ctx->share_id);
     *pSendBuf++ = GLX_VISUAL_ID_EXT;
-    *pSendBuf++ = (int)(ctx->modes->visualID);
+    *pSendBuf++ = (int)(ctx->config->visualID);
     *pSendBuf++ = GLX_SCREEN_EXT;
     *pSendBuf++ = (int)(ctx->pGlxScreen->pScreen->myNum);
 
diff --git a/GL/glx/glxcontext.h b/GL/glx/glxcontext.h
index 4c36801..18d3c6f 100644
--- a/GL/glx/glxcontext.h
+++ b/GL/glx/glxcontext.h
@@ -40,8 +40,6 @@
 **
 */
 
-#include "GL/internal/glcore.h"
-
 typedef struct __GLXtextureFromPixmap __GLXtextureFromPixmap;
 struct __GLXtextureFromPixmap {
     int (*bindTexImage)		(__GLXcontext  *baseContext,
@@ -77,9 +75,9 @@ struct __GLXcontext {
     __GLXcontext *nextReadPriv;
 
     /*
-    ** mode struct for this context
+    ** config struct for this context
     */
-    __GLcontextModes *modes;
+    __GLXconfig *config;
 
     /*
     ** Pointer to screen info data for this context.  This is set
diff --git a/GL/glx/glxdrawable.h b/GL/glx/glxdrawable.h
index f62d1ee..98e301b 100644
--- a/GL/glx/glxdrawable.h
+++ b/GL/glx/glxdrawable.h
@@ -74,7 +74,7 @@ struct __GLXdrawable {
     /*
     ** Configuration of the visual to which this drawable was created.
     */
-    __GLcontextModes *modes;
+    __GLXconfig *config;
 
     /*
     ** Lists of contexts bound to this drawable.  There are two lists here.
diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c
index 1e17911..ffa9a0b 100644
--- a/GL/glx/glxdri.c
+++ b/GL/glx/glxdri.c
@@ -52,7 +52,6 @@
 #define DRI_NEW_INTERFACE_ONLY
 #include "glxserver.h"
 #include "glxutil.h"
-#include "glcontextmodes.h"
 
 #include "g_disptab.h"
 #include "glapitable.h"
@@ -61,26 +60,26 @@
 #include "dispatch.h"
 #include "extension_string.h"
 
-#define containerOf(ptr, type, member)			\
-    (type *)( (char *)ptr - offsetof(type,member) )
-
 typedef struct __GLXDRIscreen   __GLXDRIscreen;
 typedef struct __GLXDRIcontext  __GLXDRIcontext;
 typedef struct __GLXDRIdrawable __GLXDRIdrawable;
+typedef struct __GLXDRIconfig	__GLXDRIconfig;
 
 struct __GLXDRIscreen {
     __GLXscreen		 base;
-    __DRIscreen		 driScreen;
+    __DRIscreen		*driScreen;
     void		*driver;
 
     xf86EnterVTProc	*enterVT;
     xf86LeaveVTProc	*leaveVT;
 
-    __DRIcopySubBufferExtension *copySubBuffer;
-    __DRIswapControlExtension *swapControl;
+    const __DRIcoreExtension *core;
+    const __DRIlegacyExtension *legacy;
+    const __DRIcopySubBufferExtension *copySubBuffer;
+    const __DRIswapControlExtension *swapControl;
 
 #ifdef __DRI_TEX_OFFSET
-    __DRItexOffsetExtension *texOffset;
+    const __DRItexOffsetExtension *texOffset;
     DRITexOffsetStartProcPtr texOffsetStart;
     DRITexOffsetFinishProcPtr texOffsetFinish;
     __GLXDRIdrawable *texOffsetOverride[16];
@@ -92,13 +91,13 @@ struct __GLXDRIscreen {
 
 struct __GLXDRIcontext {
     __GLXcontext base;
-    __DRIcontext driContext;
+    __DRIcontext *driContext;
     XID hwContextID;
 };
 
 struct __GLXDRIdrawable {
     __GLXdrawable base;
-    __DRIdrawable driDrawable;
+    __DRIdrawable *driDrawable;
 
     /* Pulled in from old __GLXpixmap */
 #ifdef __DRI_TEX_OFFSET
@@ -109,7 +108,10 @@ struct __GLXDRIdrawable {
 #endif
 };
 
-static const char CREATE_NEW_SCREEN_FUNC[] = __DRI_CREATE_NEW_SCREEN_STRING;
+struct __GLXDRIconfig {
+    __GLXconfig config;
+    __DRIconfig *driConfig;
+};
 
 static void
 __glXDRIleaveServer(GLboolean rendering)
@@ -151,7 +153,7 @@ __glXDRIleaveServer(GLboolean rendering)
 		__GLXDRIdrawable *pGlxPix = texOffsetOverride[j];
 
 		if (pGlxPix && pGlxPix->texname) {
-		    screen->texOffset->setTexOffset(&pGlxPix->ctx->driContext,
+		    screen->texOffset->setTexOffset(pGlxPix->ctx->driContext,
 						    pGlxPix->texname,
 						    pGlxPix->offset,
 						    pGlxPix->base.pDraw->depth,
@@ -219,24 +221,24 @@ static void
 __glXDRIdrawableDestroy(__GLXdrawable *drawable)
 {
     __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
-
+    __GLXDRIscreen *screen;
     int i;
 
     for (i = 0; i < screenInfo.numScreens; i++) {
-	__glXDRIdoReleaseTexImage((__GLXDRIscreen *)
-				  glxGetScreen(screenInfo.screens[i]),
-				  private);
+	screen = (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]);
+	__glXDRIdoReleaseTexImage(screen, private);
     }
 
-    (*private->driDrawable.destroyDrawable)(&private->driDrawable);
-
     /* If the X window was destroyed, the dri DestroyWindow hook will
      * aready have taken care of this, so only call if pDraw isn't NULL. */
     if (drawable->pDraw != NULL) {
-	    __glXenterServer(GL_FALSE);
-	    DRIDestroyDrawable(drawable->pDraw->pScreen,
-			       serverClient, drawable->pDraw);
-	    __glXleaveServer(GL_FALSE);
+	screen = (__GLXDRIscreen *) glxGetScreen(drawable->pDraw->pScreen);
+	(*screen->core->destroyDrawable)(private->driDrawable);
+
+	__glXenterServer(GL_FALSE);
+	DRIDestroyDrawable(drawable->pDraw->pScreen,
+			   serverClient, drawable->pDraw);
+	__glXleaveServer(GL_FALSE);
     }
 
     xfree(private);
@@ -255,8 +257,10 @@ static GLboolean
 __glXDRIdrawableSwapBuffers(__GLXdrawable *basePrivate)
 {
     __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
+    __GLXDRIscreen *screen =
+	(__GLXDRIscreen *) glxGetScreen(basePrivate->pDraw->pScreen);
 
-    (*private->driDrawable.swapBuffers)(&private->driDrawable);
+    (*screen->core->swapBuffers)(private->driDrawable);
 
     return TRUE;
 }
@@ -266,11 +270,11 @@ static int
 __glXDRIdrawableSwapInterval(__GLXdrawable *baseDrawable, int interval)
 {
     __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseDrawable;
-    __GLXDRIscreen *screen = (__GLXDRIscreen *)
-	glxGetScreen(baseDrawable->pDraw->pScreen);
+    __GLXDRIscreen *screen =
+	(__GLXDRIscreen *) glxGetScreen(baseDrawable->pDraw->pScreen);
 
     if (screen->swapControl)
-	screen->swapControl->setSwapInterval(&draw->driDrawable, interval);
+	screen->swapControl->setSwapInterval(draw->driDrawable, interval);
 
     return 0;
 }
@@ -285,20 +289,21 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate,
 	glxGetScreen(basePrivate->pDraw->pScreen);
 
     if (screen->copySubBuffer)
-	screen->copySubBuffer->copySubBuffer(&private->driDrawable,
-					     x, y, w, h);
+	screen->copySubBuffer->copySubBuffer(private->driDrawable, x, y, w, h);
 }
 
 static void
 __glXDRIcontextDestroy(__GLXcontext *baseContext)
 {
     __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
     Bool retval;
 
-    context->driContext.destroyContext(&context->driContext);
+    screen->core->destroyContext(context->driContext);
 
     __glXenterServer(GL_FALSE);
-    retval = DRIDestroyContext(baseContext->pGlxScreen->pScreen, context->hwContextID);
+    retval = DRIDestroyContext(baseContext->pGlxScreen->pScreen,
+			       context->hwContextID);
     __glXleaveServer(GL_FALSE);
 
     __glXContextDestroy(&context->base);
@@ -309,20 +314,22 @@ static int
 __glXDRIcontextMakeCurrent(__GLXcontext *baseContext)
 {
     __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
     __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
     __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
 
-    return (*context->driContext.bindContext)(&context->driContext,
-					      &draw->driDrawable,
-					      &read->driDrawable);
+    return (*screen->core->bindContext)(context->driContext,
+					draw->driDrawable,
+					read->driDrawable);
 }					      
 
 static int
 __glXDRIcontextLoseCurrent(__GLXcontext *baseContext)
 {
     __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
 
-    return (*context->driContext.unbindContext)(&context->driContext);
+    return (*screen->core->unbindContext)(context->driContext);
 }
 
 static int
@@ -331,13 +338,10 @@ __glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc,
 {
     __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst;
     __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen;
 
-    /* FIXME: We will need to add DRIcontext::copyContext for this. */
-
-    (void) dst;
-    (void) src;
-
-    return FALSE;
+    return (*screen->core->copyContext)(dst->driContext,
+					src->driContext, mask);
 }
 
 static int
@@ -346,10 +350,11 @@ __glXDRIcontextForceCurrent(__GLXcontext *baseContext)
     __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
     __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
     __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
 
-    return (*context->driContext.bindContext)(&context->driContext,
-					      &draw->driDrawable,
-					      &read->driDrawable);
+    return (*screen->core->bindContext)(context->driContext,
+					draw->driDrawable,
+					read->driDrawable);
 }
 
 static void
@@ -392,10 +397,8 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
     int		bpp, override = 0, texname;
     GLenum	format, type;
     ScreenPtr pScreen = glxPixmap->pDraw->pScreen;
-    __GLXDRIdrawable *driDraw =
-	    containerOf(glxPixmap, __GLXDRIdrawable, base);
-    __GLXDRIscreen * const screen =
-	    (__GLXDRIscreen *) glxGetScreen(pScreen);
+    __GLXDRIdrawable *driDraw = (__GLXDRIdrawable *) glxPixmap;
+    __GLXDRIscreen * const screen = (__GLXDRIscreen *) glxGetScreen(pScreen);
 
     CALL_GetIntegerv(GET_DISPATCH(), (glxPixmap->target == GL_TEXTURE_2D ?
 				      GL_TEXTURE_BINDING_2D :
@@ -439,7 +442,7 @@ alreadyin:
 
 	driDraw->texname = texname;
 
-	screen->texOffset->setTexOffset(&driDraw->ctx->driContext, texname, 0,
+	screen->texOffset->setTexOffset(driDraw->ctx->driContext, texname, 0,
 					pixmap->drawable.depth,
 					pixmap->devKind);
     }
@@ -568,9 +571,11 @@ __glXDRIreleaseTexImage(__GLXcontext *baseContext,
 			int buffer,
 			__GLXdrawable *pixmap)
 {
-    __glXDRIdoReleaseTexImage((__GLXDRIscreen *)
-			      glxGetScreen(pixmap->pDraw->pScreen),
-			      containerOf(pixmap, __GLXDRIdrawable, base));
+    __GLXDRIscreen *screen =
+	(__GLXDRIscreen *) glxGetScreen(pixmap->pDraw->pScreen);
+    __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) pixmap;
+
+    __glXDRIdoReleaseTexImage(screen, drawable);
 
     return Success;
 }
@@ -585,7 +590,7 @@ __glXDRIscreenDestroy(__GLXscreen *baseScreen)
 {
     __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
 
-    screen->driScreen.destroyScreen(&screen->driScreen);
+    screen->core->destroyScreen(screen->driScreen);
 
     dlclose(screen->driver);
 
@@ -596,11 +601,12 @@ __glXDRIscreenDestroy(__GLXscreen *baseScreen)
 
 static __GLXcontext *
 __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
-			    __GLcontextModes *modes,
+			    __GLXconfig *glxConfig,
 			    __GLXcontext *baseShareContext)
 {
     __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
     __GLXDRIcontext *context, *shareContext;
+    __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
     VisualPtr visual;
     int i;
     GLboolean retval;
@@ -610,7 +616,7 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
 
     shareContext = (__GLXDRIcontext *) baseShareContext;
     if (shareContext)
-	driShare = &shareContext->driContext;
+	driShare = shareContext->driContext;
     else
 	driShare = NULL;
 
@@ -632,7 +638,7 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
     /* Find the requested X visual */
     visual = pScreen->visuals;
     for (i = 0; i < pScreen->numVisuals; i++, visual++)
-	if (visual->vid == modes->visualID)
+	if (visual->vid == glxConfig->visualID)
 	    break;
     if (i == pScreen->numVisuals)
 	return GL_FALSE;
@@ -644,15 +650,15 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
 			      context->hwContextID, &hwContext);
     __glXleaveServer(GL_FALSE);
 
-    context->driContext.private =
-	screen->driScreen.createNewContext(&screen->driScreen,
-					   modes,
-					   0, /* render type */
-					   driShare,
-					   hwContext,
-					   &context->driContext);
+    context->driContext =
+	screen->legacy->createNewContext(screen->driScreen,
+					 config->driConfig,
+					 0, /* render type */
+					 driShare,
+					 hwContext,
+					 context);
 
-    if (context->driContext.private == NULL) {
+    if (context->driContext == NULL) {
     	__glXenterServer(GL_FALSE);
 	retval = DRIDestroyContext(baseScreen->pScreen, context->hwContextID);
     	__glXleaveServer(GL_FALSE);
@@ -668,9 +674,10 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
 			     DrawablePtr pDraw,
 			     int type,
 			     XID drawId,
-			     __GLcontextModes *modes)
+			     __GLXconfig *glxConfig)
 {
     __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
+    __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
     __GLXDRIdrawable *private;
     GLboolean retval;
     drm_drawable_t hwDrawable;
@@ -682,7 +689,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
     memset(private, 0, sizeof *private);
 
     if (!__glXDrawableInit(&private->base, screen,
-			   pDraw, type, drawId, modes)) {
+			   pDraw, type, drawId, glxConfig)) {
         xfree(private);
 	return NULL;
     }
@@ -700,13 +707,12 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
     /* The last argument is 'attrs', which is used with pbuffers which
      * we currently don't support. */
 
-    private->driDrawable.private =
-	(driScreen->driScreen.createNewDrawable)(&driScreen->driScreen,
-						 modes,
-						 &private->driDrawable,
-						 hwDrawable, 0, 0, NULL);
+    private->driDrawable =
+	(driScreen->legacy->createNewDrawable)(driScreen->driScreen,
+					       config->driConfig,
+					       hwDrawable, 0, NULL, private);
 
-    if (private->driDrawable.private == NULL) {
+    if (private->driDrawable == NULL) {
 	__glXenterServer(GL_FALSE);
 	DRIDestroyDrawable(screen->pScreen, serverClient, pDraw);
 	__glXleaveServer(GL_FALSE);
@@ -723,10 +729,10 @@ getDrawableInfo(__DRIdrawable *driDrawable,
 		int *x, int *y, int *width, int *height,
 		int *numClipRects, drm_clip_rect_t **ppClipRects,
 		int *backX, int *backY,
-		int *numBackClipRects, drm_clip_rect_t **ppBackClipRects)
+		int *numBackClipRects, drm_clip_rect_t **ppBackClipRects,
+		void *data)
 {
-    __GLXDRIdrawable *drawable = containerOf(driDrawable,
-					     __GLXDRIdrawable, driDrawable);
+    __GLXDRIdrawable *drawable = data;
     ScreenPtr pScreen;
     drm_clip_rect_t *pClipRects, *pBackClipRects;
     GLboolean retval;
@@ -810,10 +816,10 @@ getUST(int64_t *ust)
 static void __glXReportDamage(__DRIdrawable *driDraw,
 			      int x, int y,
 			      drm_clip_rect_t *rects, int num_rects,
-			      GLboolean front_buffer)
+			      GLboolean front_buffer,
+			      void *data)
 {
-    __GLXDRIdrawable *drawable =
-	    containerOf(driDraw, __GLXDRIdrawable, driDrawable);
+    __GLXDRIdrawable *drawable = data;
     DrawablePtr pDraw = drawable->base.pDraw;
     RegionRec region;
 
@@ -827,13 +833,6 @@ static void __glXReportDamage(__DRIdrawable *driDraw,
     __glXleaveServer(GL_FALSE);
 }
 
-/* Table of functions that we export to the driver. */
-static const __DRIcontextModesExtension contextModesExtension = {
-    { __DRI_CONTEXT_MODES, __DRI_CONTEXT_MODES_VERSION },
-    _gl_context_modes_create,
-    _gl_context_modes_destroy,
-};
-
 static const __DRIsystemTimeExtension systemTimeExtension = {
     { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION },
     getUST,
@@ -851,7 +850,6 @@ static const __DRIdamageExtension damageExtension = {
 };
 
 static const __DRIextension *loader_extensions[] = {
-    &contextModesExtension.base,
     &systemTimeExtension.base,
     &getDrawableInfoExtension.base,
     &damageExtension.base,
@@ -897,7 +895,8 @@ initializeExtensions(__GLXDRIscreen *screen)
     const __DRIextension **extensions;
     int i;
 
-    extensions = screen->driScreen.getExtensions(&screen->driScreen);
+    extensions = screen->core->getExtensions(screen->driScreen);
+
     for (i = 0; extensions[i]; i++) {
 #ifdef __DRI_COPY_SUB_BUFFER
 	if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
@@ -931,12 +930,12 @@ initializeExtensions(__GLXDRIscreen *screen)
     }
 }
     
-#define COPY_SUB_BUFFER_INTERNAL_VERSION 20060314
+extern __GLXconfig *
+glxConvertConfigs(const __DRIcoreExtension *core, const __DRIconfig **configs);
 
 static __GLXscreen *
 __glXDRIscreenProbe(ScreenPtr pScreen)
 {
-    PFNCREATENEWSCREENFUNC createNewScreen;
     drm_handle_t hSAREA;
     drmAddress pSAREA = NULL;
     char *BusID;
@@ -953,11 +952,13 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     drm_handle_t  hFB;
     int        junk;
     __GLXDRIscreen *screen;
-    void *dev_priv = NULL;
     char filename[128];
     Bool isCapable;
     size_t buffer_size;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    const __DRIconfig **driConfigs;
+    const __DRIextension **extensions;
+    int i;
 
     if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") ||
 	!DRIQueryDirectRenderingCapable(pScreen, &isCapable) ||
@@ -985,9 +986,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     dri_version.minor = XF86DRI_MINOR_VERSION;
     dri_version.patch = XF86DRI_PATCH_VERSION;
 
-    framebuffer.base = NULL;
-    framebuffer.dev_priv = NULL;
-
     if (!DRIOpenConnection(pScreen, &hSAREA, &BusID)) {
 	LogMessage(X_ERROR, "AIGLX error: DRIOpenConnection failed\n");
 	goto handle_error;
@@ -1046,11 +1044,30 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
         goto handle_error;
     }
 
-    createNewScreen = dlsym(screen->driver, CREATE_NEW_SCREEN_FUNC);
-    if (createNewScreen == NULL) {
-	LogMessage(X_ERROR, "AIGLX error: dlsym for %s failed (%s)\n",
-		   CREATE_NEW_SCREEN_FUNC, dlerror());
-      goto handle_error;
+    extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS);
+    if (extensions == NULL) {
+	LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n",
+		   driverName, dlerror());
+	goto handle_error;
+    }
+    
+    for (i = 0; extensions[i]; i++) {
+	if (strcmp(extensions[i]->name, __DRI_CORE) == 0 &&
+	    extensions[i]->version >= __DRI_CORE_VERSION) {
+		screen->core = (__DRIcoreExtension *) extensions[i];
+	}
+
+	if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0 &&
+	    extensions[i]->version >= __DRI_LEGACY_VERSION) {
+		screen->legacy = (__DRIlegacyExtension *) extensions[i];
+	}
+    }
+
+    if (screen->core == NULL || screen->legacy == NULL) {
+	LogMessage(X_ERROR,
+		   "AIGLX error: %s does not export required DRI extension\n",
+		   driverName);
+	goto handle_error;
     }
 
     /*
@@ -1066,19 +1083,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 	goto handle_error;
     }
 
-    /* Sigh... the DRI interface is broken; the DRI driver will free
-     * the dev private pointer using _mesa_free() on screen destroy,
-     * but we can't use _mesa_malloc() here.  In fact, the DRI driver
-     * shouldn't free data it didn't allocate itself, but what can you
-     * do... */
-    dev_priv = xalloc(framebuffer.dev_priv_size);
-    if (dev_priv == NULL) {
-	LogMessage(X_ERROR, "AIGLX error: dev_priv allocation failed");
-	goto handle_error;
-    }
-    memcpy(dev_priv, framebuffer.dev_priv, framebuffer.dev_priv_size);
-    framebuffer.dev_priv = dev_priv;
-
     framebuffer.width = pScreen->width;
     framebuffer.height = pScreen->height;
 
@@ -1101,28 +1105,30 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 	goto handle_error;
     }
     
-    screen->driScreen.private =
-	(*createNewScreen)(pScreen->myNum,
-			   &screen->driScreen,
-			   &ddx_version,
-			   &dri_version,
-			   &drm_version,
-			   &framebuffer,
-			   pSAREA,
-			   fd,
-			   loader_extensions,
-			   &screen->base.fbconfigs);
-
-    if (screen->driScreen.private == NULL) {
+    screen->driScreen =
+	(*screen->legacy->createNewScreen)(pScreen->myNum,
+					   &ddx_version,
+					   &dri_version,
+					   &drm_version,
+					   &framebuffer,
+					   pSAREA,
+					   fd,
+					   loader_extensions,
+					   &driConfigs,
+					   screen);
+
+    screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs);
+
+    if (screen->driScreen == NULL) {
 	LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed");
 	goto handle_error;
     }
 
+    initializeExtensions(screen);
+
     DRIGetTexOffsetFuncs(pScreen, &screen->texOffsetStart,
 			 &screen->texOffsetFinish);
 
-    initializeExtensions(screen);
-
     __glXScreenInit(&screen->base, pScreen);
 
     buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
@@ -1155,9 +1161,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     if (framebuffer.base != NULL)
 	drmUnmap((drmAddress)framebuffer.base, framebuffer.size);
 
-    if (dev_priv != NULL)
-	xfree(dev_priv);
-
     if (fd >= 0)
 	drmCloseOnce(fd);
 
diff --git a/GL/glx/glxdri2.c b/GL/glx/glxdri2.c
index fecfb19..40590c1 100644
--- a/GL/glx/glxdri2.c
+++ b/GL/glx/glxdri2.c
@@ -35,20 +35,18 @@
 #include <drm.h>
 #include <GL/gl.h>
 #include <GL/internal/dri_interface.h>
+#include <GL/glxtokens.h>
 
 #include <windowstr.h>
 #include <os.h>
 
 #define _XF86DRI_SERVER_
 #include <xf86drm.h>
-#include <xf86dristr.h>
-#include <xf86str.h>
 #include <xf86.h>
 #include <dri2.h>
 
 #include "glxserver.h"
 #include "glxutil.h"
-#include "glcontextmodes.h"
 
 #include "g_disptab.h"
 #include "glapitable.h"
@@ -57,53 +55,56 @@
 #include "dispatch.h"
 #include "extension_string.h"
 
-#define containerOf(ptr, type, member)			\
-    (type *)( (char *)ptr - offsetof(type,member) )
-
 typedef struct __GLXDRIscreen   __GLXDRIscreen;
 typedef struct __GLXDRIcontext  __GLXDRIcontext;
 typedef struct __GLXDRIdrawable __GLXDRIdrawable;
+typedef struct __GLXDRIconfig	__GLXDRIconfig;
 
 struct __GLXDRIscreen {
     __GLXscreen		 base;
-    __DRIscreen		 driScreen;
+    __DRIscreen		*driScreen;
     void		*driver;
     int			 fd;
 
     xf86EnterVTProc	*enterVT;
     xf86LeaveVTProc	*leaveVT;
 
-    __DRIcopySubBufferExtension *copySubBuffer;
-    __DRIswapControlExtension *swapControl;
-    __DRItexBufferExtension *texBuffer;
+    const __DRIcoreExtension *core;
+    const __DRIcopySubBufferExtension *copySubBuffer;
+    const __DRIswapControlExtension *swapControl;
+    const __DRItexBufferExtension *texBuffer;
 
     unsigned char glx_enable_bits[__GLX_EXT_BYTES];
 };
 
 struct __GLXDRIcontext {
-    __GLXcontext base;
-    __DRIcontext driContext;
-    drm_context_t hwContext;
+    __GLXcontext	 base;
+    __DRIcontext	*driContext;
 };
 
 struct __GLXDRIdrawable {
-    __GLXdrawable base;
-    __DRIdrawable driDrawable;
+    __GLXdrawable	 base;
+    __DRIdrawable	*driDrawable;
+    __GLXDRIscreen	*screen;
 };
 
-static const char CREATE_NEW_SCREEN_FUNC[] = __DRI2_CREATE_NEW_SCREEN_STRING;
+struct __GLXDRIconfig {
+    __GLXconfig config;
+    const __DRIconfig *driConfig;
+};
 
 static void
 __glXDRIdrawableDestroy(__GLXdrawable *drawable)
 {
     __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
-
-    (*private->driDrawable.destroyDrawable)(&private->driDrawable);
+    const __DRIcoreExtension *core = private->screen->core;
+    
+    (*core->destroyDrawable)(private->driDrawable);
 
     /* If the X window was destroyed, the dri DestroyWindow hook will
      * aready have taken care of this, so only call if pDraw isn't NULL. */
     if (drawable->pDraw != NULL)
-	DRI2DestroyDrawable(drawable->pDraw->pScreen, drawable->pDraw);
+	DRI2DestroyDrawable(drawable->pDraw);
 
     xfree(private);
 }
@@ -118,25 +119,25 @@ __glXDRIdrawableResize(__GLXdrawable *glxPriv)
 }
 
 static GLboolean
-__glXDRIdrawableSwapBuffers(__GLXdrawable *basePrivate)
+__glXDRIdrawableSwapBuffers(__GLXdrawable *drawable)
 {
-    __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
+    __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
+    const __DRIcoreExtension *core = private->screen->core;
 
-    (*private->driDrawable.swapBuffers)(&private->driDrawable);
+    (*core->swapBuffers)(private->driDrawable);
 
     return TRUE;
 }
 
 
 static int
-__glXDRIdrawableSwapInterval(__GLXdrawable *baseDrawable, int interval)
+__glXDRIdrawableSwapInterval(__GLXdrawable *drawable, int interval)
 {
-    __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseDrawable;
-    __GLXDRIscreen *screen = (__GLXDRIscreen *)
-	glxGetScreen(baseDrawable->pDraw->pScreen);
+    __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
+    const __DRIswapControlExtension *swapControl = private->screen->swapControl;
 
-    if (screen->swapControl)
-	screen->swapControl->setSwapInterval(&draw->driDrawable, interval);
+    if (swapControl)
+	swapControl->setSwapInterval(private->driDrawable, interval);
 
     return 0;
 }
@@ -147,22 +148,20 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate,
 			       int x, int y, int w, int h)
 {
     __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
-    __GLXDRIscreen *screen = (__GLXDRIscreen *)
-	glxGetScreen(basePrivate->pDraw->pScreen);
+    const __DRIcopySubBufferExtension *copySubBuffer =
+	    private->screen->copySubBuffer;
 
-    if (screen->copySubBuffer)
-	screen->copySubBuffer->copySubBuffer(&private->driDrawable,
-					     x, y, w, h);
+    if (copySubBuffer)
+	(*copySubBuffer->copySubBuffer)(private->driDrawable, x, y, w, h);
 }
 
 static void
 __glXDRIcontextDestroy(__GLXcontext *baseContext)
 {
     __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
-    __GLXDRIscreen *screen = (__GLXDRIscreen *) baseContext->pGlxScreen;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
 
-    context->driContext.destroyContext(&context->driContext);
-    drmDestroyContext(screen->fd, context->hwContext);
+    (*screen->core->destroyContext)(context->driContext);
     __glXContextDestroy(&context->base);
     xfree(context);
 }
@@ -173,18 +172,20 @@ __glXDRIcontextMakeCurrent(__GLXcontext *baseContext)
     __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
     __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
     __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
 
-    return (*context->driContext.bindContext)(&context->driContext,
-					      &draw->driDrawable,
-					      &read->driDrawable);
+    return (*screen->core->bindContext)(context->driContext,
+					draw->driDrawable,
+					read->driDrawable);
 }					      
 
 static int
 __glXDRIcontextLoseCurrent(__GLXcontext *baseContext)
 {
     __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
 
-    return (*context->driContext.unbindContext)(&context->driContext);
+    return (*screen->core->unbindContext)(context->driContext);
 }
 
 static int
@@ -193,13 +194,10 @@ __glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc,
 {
     __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst;
     __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen;
 
-    /* FIXME: We will need to add DRIcontext::copyContext for this. */
-
-    (void) dst;
-    (void) src;
-
-    return FALSE;
+    return (*screen->core->copyContext)(dst->driContext,
+					src->driContext, mask);
 }
 
 static int
@@ -208,10 +206,11 @@ __glXDRIcontextForceCurrent(__GLXcontext *baseContext)
     __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
     __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
     __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
 
-    return (*context->driContext.bindContext)(&context->driContext,
-					      &draw->driDrawable,
-					      &read->driDrawable);
+    return (*screen->core->bindContext)(context->driContext,
+					draw->driDrawable,
+					read->driDrawable);
 }
 
 #ifdef __DRI_TEX_BUFFER
@@ -221,19 +220,16 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
 		     int buffer,
 		     __GLXdrawable *glxPixmap)
 {
-    ScreenPtr pScreen = glxPixmap->pDraw->pScreen;
-    __GLXDRIscreen * const screen = (__GLXDRIscreen *) glxGetScreen(pScreen);
-    PixmapPtr pixmap;
-    __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
     __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) glxPixmap;
+    const __DRItexBufferExtension *texBuffer = drawable->screen->texBuffer;
+    __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
 
-    if (screen->texBuffer == NULL)
+    if (texBuffer == NULL)
         return Success;
 
-    pixmap = (PixmapPtr) glxPixmap->pDraw;
-    screen->texBuffer->setTexBuffer(&context->driContext,
-				    glxPixmap->target,
-				    &drawable->driDrawable);
+    texBuffer->setTexBuffer(context->driContext,
+			    glxPixmap->target,
+			    drawable->driDrawable);
 
     return Success;
 }
@@ -277,7 +273,7 @@ __glXDRIscreenDestroy(__GLXscreen *baseScreen)
 {
     __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
 
-    screen->driScreen.destroyScreen(&screen->driScreen);
+    (*screen->core->destroyScreen)(screen->driScreen);
 
     dlclose(screen->driver);
 
@@ -288,16 +284,18 @@ __glXDRIscreenDestroy(__GLXscreen *baseScreen)
 
 static __GLXcontext *
 __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
-			    __GLcontextModes *modes,
+			    __GLXconfig *glxConfig,
 			    __GLXcontext *baseShareContext)
 {
     __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
     __GLXDRIcontext *context, *shareContext;
+    __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
+    const __DRIcoreExtension *core = screen->core;
     __DRIcontext *driShare;
 
     shareContext = (__GLXDRIcontext *) baseShareContext;
     if (shareContext)
-	driShare = &shareContext->driContext;
+	driShare = shareContext->driContext;
     else
 	driShare = NULL;
 
@@ -313,16 +311,9 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
     context->base.forceCurrent      = __glXDRIcontextForceCurrent;
     context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
 
-    if (drmCreateContext(screen->fd, &context->hwContext))
-	    return GL_FALSE;
-
-    context->driContext.private =
-	screen->driScreen.createNewContext(&screen->driScreen,
-					   modes,
-					   0, /* render type */
-					   driShare,
-					   context->hwContext,
-					   &context->driContext);
+    context->driContext =
+	(*core->createNewContext)(screen->driScreen,
+				  config->driConfig, driShare, context);
 
     return &context->base;
 }
@@ -332,13 +323,13 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
 			     DrawablePtr pDraw,
 			     int type,
 			     XID drawId,
-			     __GLcontextModes *modes)
+			     __GLXconfig *glxConfig)
 {
     __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
+    __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
     __GLXDRIdrawable *private;
     GLboolean retval;
-    drm_drawable_t hwDrawable;
-    unsigned int head;
+    unsigned int handle, head;
 
     private = xalloc(sizeof *private);
     if (private == NULL)
@@ -346,8 +337,9 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
 
     memset(private, 0, sizeof *private);
 
+    private->screen = driScreen;
     if (!__glXDrawableInit(&private->base, screen,
-			   pDraw, type, drawId, modes)) {
+			   pDraw, type, drawId, glxConfig)) {
         xfree(private);
 	return NULL;
     }
@@ -357,14 +349,12 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
     private->base.swapBuffers   = __glXDRIdrawableSwapBuffers;
     private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
 
-    retval = DRI2CreateDrawable(screen->pScreen, pDraw,
-				&hwDrawable, &head);
+    retval = DRI2CreateDrawable(pDraw, &handle, &head);
 
-    private->driDrawable.private =
-	(driScreen->driScreen.createNewDrawable)(&driScreen->driScreen,
-						 modes,
-						 &private->driDrawable,
-						 hwDrawable, head, 0, NULL);
+    private->driDrawable =
+	(*driScreen->core->createNewDrawable)(driScreen->driScreen, 
+					      config->driConfig,
+					      handle, head, private);
 
     return &private->base;
 }
@@ -385,44 +375,43 @@ getUST(int64_t *ust)
     }
 }
 
-static void __glXReportDamage(__DRIdrawable *driDraw,
-			      int x, int y,
-			      drm_clip_rect_t *rects, int num_rects,
-			      GLboolean front_buffer)
+static const __DRIsystemTimeExtension systemTimeExtension = {
+    { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION },
+    getUST,
+    NULL,
+};
+
+static void dri2ReemitDrawableInfo(__DRIdrawable *draw, unsigned int *tail,
+				   void *loaderPrivate)
 {
-    __GLXDRIdrawable *drawable =
-	    containerOf(driDraw, __GLXDRIdrawable, driDrawable);
+    __GLXDRIdrawable *pdraw = loaderPrivate;
+
+    DRI2ReemitDrawableInfo(pdraw->base.pDraw, tail);
+}
+
+static void dri2PostDamage(__DRIdrawable *draw,
+			   struct drm_clip_rect *rects,
+			   int numRects, void *loaderPrivate)
+{ 
+    __GLXDRIdrawable *drawable = loaderPrivate;
     DrawablePtr pDraw = drawable->base.pDraw;
     RegionRec region;
 
-    REGION_INIT(pDraw->pScreen, &region, (BoxPtr) rects, num_rects);
+    REGION_INIT(pDraw->pScreen, &region, (BoxPtr) rects, numRects);
     REGION_TRANSLATE(pScreen, &region, pDraw->x, pDraw->y);
     DamageDamageRegion(pDraw, &region);
     REGION_UNINIT(pDraw->pScreen, &region);
 }
 
-/* Table of functions that we export to the driver. */
-static const __DRIcontextModesExtension contextModesExtension = {
-    { __DRI_CONTEXT_MODES, __DRI_CONTEXT_MODES_VERSION },
-    _gl_context_modes_create,
-    _gl_context_modes_destroy,
-};
-
-static const __DRIsystemTimeExtension systemTimeExtension = {
-    { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION },
-    getUST,
-    NULL,
-};
-
-static const __DRIdamageExtension damageExtension = {
-    { __DRI_DAMAGE, __DRI_DAMAGE_VERSION },
-    __glXReportDamage,
+static const __DRIloaderExtension loaderExtension = {
+    { __DRI_LOADER, __DRI_LOADER_VERSION },
+    dri2ReemitDrawableInfo,
+    dri2PostDamage
 };
 
 static const __DRIextension *loader_extensions[] = {
-    &contextModesExtension.base,
     &systemTimeExtension.base,
-    &damageExtension.base,
+    &loaderExtension.base,
     NULL
 };
 
@@ -463,11 +452,13 @@ initializeExtensions(__GLXDRIscreen *screen)
     const __DRIextension **extensions;
     int i;
 
-    extensions = screen->driScreen.getExtensions(&screen->driScreen);
+    extensions = screen->core->getExtensions(screen->driScreen);
+
     for (i = 0; extensions[i]; i++) {
 #ifdef __DRI_COPY_SUB_BUFFER
 	if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
-	    screen->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
+	    screen->copySubBuffer =
+		(const __DRIcopySubBufferExtension *) extensions[i];
 	    __glXEnableExtension(screen->glx_enable_bits,
 				 "GLX_MESA_copy_sub_buffer");
 	    
@@ -477,7 +468,8 @@ initializeExtensions(__GLXDRIscreen *screen)
 
 #ifdef __DRI_SWAP_CONTROL
 	if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
-	    screen->swapControl = (__DRIswapControlExtension *) extensions[i];
+	    screen->swapControl =
+		(const __DRIswapControlExtension *) extensions[i];
 	    __glXEnableExtension(screen->glx_enable_bits,
 				 "GLX_SGI_swap_control");
 	    __glXEnableExtension(screen->glx_enable_bits,
@@ -489,7 +481,8 @@ initializeExtensions(__GLXDRIscreen *screen)
 
 #ifdef __DRI_TEX_BUFFER
 	if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
-	    screen->texBuffer = (__DRItexBufferExtension *) extensions[i];
+	    screen->texBuffer =
+		(const __DRItexBufferExtension *) extensions[i];
 	    /* GLX_EXT_texture_from_pixmap is always enabled. */
 	    LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n");
 	}
@@ -498,27 +491,176 @@ initializeExtensions(__GLXDRIscreen *screen)
     }
 }
     
+#define __ATTRIB(attrib, field) \
+    { attrib, offsetof(__GLXconfig, field) }
+
+static const struct { unsigned int attrib, offset; } attribMap[] = {
+    __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE,			rgbBits),
+    __ATTRIB(__DRI_ATTRIB_LEVEL,			level),
+    __ATTRIB(__DRI_ATTRIB_RED_SIZE,			redBits),
+    __ATTRIB(__DRI_ATTRIB_GREEN_SIZE,			greenBits),
+    __ATTRIB(__DRI_ATTRIB_BLUE_SIZE,			blueBits),
+    __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE,			alphaBits),
+    __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE,			depthBits),
+    __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE,			stencilBits),
+    __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE,		accumRedBits),
+    __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE,		accumGreenBits),
+    __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE,		accumBlueBits),
+    __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE,		accumAlphaBits),
+    __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS,		sampleBuffers),
+    __ATTRIB(__DRI_ATTRIB_SAMPLES,			samples),
+    __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER,		doubleBufferMode),
+    __ATTRIB(__DRI_ATTRIB_STEREO,			stereoMode),
+    __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS,			numAuxBuffers),
+    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE,		transparentPixel),
+    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE,	transparentPixel),
+    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE,	transparentRed),
+    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE,	transparentGreen),
+    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE,	transparentBlue),
+    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE,	transparentAlpha),
+    __ATTRIB(__DRI_ATTRIB_FLOAT_MODE,			floatMode),
+    __ATTRIB(__DRI_ATTRIB_RED_MASK,			redMask),
+    __ATTRIB(__DRI_ATTRIB_GREEN_MASK,			greenMask),
+    __ATTRIB(__DRI_ATTRIB_BLUE_MASK,			blueMask),
+    __ATTRIB(__DRI_ATTRIB_ALPHA_MASK,			alphaMask),
+    __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH,		maxPbufferWidth),
+    __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT,		maxPbufferHeight),
+    __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS,		maxPbufferPixels),
+    __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH,	optimalPbufferWidth),
+    __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT,	optimalPbufferHeight),
+    __ATTRIB(__DRI_ATTRIB_SWAP_METHOD,			swapMethod),
+    __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB,		bindToTextureRgb),
+    __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA,		bindToTextureRgba),
+    __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE,	bindToMipmapTexture),
+    __ATTRIB(__DRI_ATTRIB_YINVERTED,			yInverted),
+};
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+
+static void
+setScalar(__GLXconfig *config, unsigned int attrib, unsigned int value)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(attribMap); i++)
+	if (attribMap[i].attrib == attrib) {
+	    *(unsigned int *) ((char *) config + attribMap[i].offset) = value;
+	    return;
+	}
+}
+
+static __GLXconfig *
+createModeFromConfig(const __DRIcoreExtension *core,
+		     const __DRIconfig *driConfig,
+		     unsigned int visualType)
+{
+    __GLXDRIconfig *config;
+    unsigned int attrib, value;
+    int i;
+
+    config = xalloc(sizeof *config);
+
+    config->driConfig = driConfig;
+
+    i = 0;
+    while (core->indexConfigAttrib(driConfig, i++, &attrib, &value)) {
+	switch (attrib) {
+	case __DRI_ATTRIB_RENDER_TYPE:
+	    if (value & __DRI_ATTRIB_RGBA_BIT) {
+		config->config.renderType |= GLX_RGBA_BIT;
+		config->config.rgbMode = GL_TRUE;
+	    } else if (value & __DRI_ATTRIB_COLOR_INDEX_BIT) {
+		config->config.renderType |= GLX_COLOR_INDEX_BIT;
+		config->config.rgbMode = GL_FALSE;
+	    } else {
+		config->config.renderType = 0;
+		config->config.rgbMode = GL_FALSE;
+	    }
+	    break;
+	case __DRI_ATTRIB_CONFIG_CAVEAT:
+	    if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
+		config->config.visualRating = GLX_NON_CONFORMANT_CONFIG;
+	    else if (value & __DRI_ATTRIB_SLOW_BIT)
+		config->config.visualRating = GLX_SLOW_CONFIG;
+	    else
+		config->config.visualRating = GLX_NONE;
+	    break;
+	case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS:
+	    config->config.bindToTextureTargets = 0;
+	    if (value & __DRI_ATTRIB_TEXTURE_1D_BIT)
+		config->config.bindToTextureTargets |= GLX_TEXTURE_1D_BIT_EXT;
+	    if (value & __DRI_ATTRIB_TEXTURE_2D_BIT)
+		config->config.bindToTextureTargets |= GLX_TEXTURE_2D_BIT_EXT;
+	    if (value & __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT)
+		config->config.bindToTextureTargets |= GLX_TEXTURE_RECTANGLE_BIT_EXT;
+	    break;	
+	default:
+	    setScalar(&config->config, attrib, value);
+	    break;
+	}
+    }
+
+    config->config.next = NULL;
+    config->config.xRenderable = GL_TRUE;
+    config->config.visualType = visualType;
+    config->config.drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
+
+    return &config->config;
+}
+
+__GLXconfig *
+glxConvertConfigs(const __DRIcoreExtension *core, const __DRIconfig **configs);
+
+__GLXconfig *
+glxConvertConfigs(const __DRIcoreExtension *core, const __DRIconfig **configs)
+{
+    __GLXconfig head, *tail;
+    int i;
+
+    tail = &head;
+    head.next = NULL;
+
+    for (i = 0; configs[i]; i++) {
+	tail->next = createModeFromConfig(core,
+					  configs[i], GLX_TRUE_COLOR);
+	if (tail->next == NULL)
+	    break;
+
+	tail = tail->next;
+    }
+
+    for (i = 0; configs[i]; i++) {
+	tail->next = createModeFromConfig(core,
+					  configs[i], GLX_DIRECT_COLOR);
+	if (tail->next == NULL)
+	    break;
+
+	tail = tail->next;
+    }
+
+    return head.next;
+}
+
 static __GLXscreen *
 __glXDRIscreenProbe(ScreenPtr pScreen)
 {
-    __DRI2_CREATE_NEW_SCREEN_FUNC *createNewScreen;
     const char *driverName;
     __GLXDRIscreen *screen;
     char filename[128];
     size_t buffer_size;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     unsigned int sareaHandle;
+    const __DRIextension **extensions;
+    const __DRIconfig **driConfigs;
+    int i;
 
     screen = xalloc(sizeof *screen);
     if (screen == NULL)
-      return NULL;
+	return NULL;
     memset(screen, 0, sizeof *screen);
 
     if (!xf86LoaderCheckSymbol("DRI2Connect") ||
-	!DRI2Connect(pScreen,
-		     &screen->fd,
-		     &driverName,
-		     &sareaHandle)) {
+	!DRI2Connect(pScreen, &screen->fd, &driverName, &sareaHandle)) {
 	LogMessage(X_INFO,
 		   "AIGLX: Screen %d is not DRI2 capable\n", pScreen->myNum);
 	return NULL;
@@ -532,8 +674,8 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 
     __glXInitExtensionEnableBits(screen->glx_enable_bits);
 
-    snprintf(filename, sizeof filename, "%s/%s_dri.so",
-             dri_driver_path, driverName);
+    snprintf(filename, sizeof filename,
+	     "%s/%s_dri.so", dri_driver_path, driverName);
 
     screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
     if (screen->driver == NULL) {
@@ -542,28 +684,43 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
         goto handle_error;
     }
 
-    createNewScreen = dlsym(screen->driver, CREATE_NEW_SCREEN_FUNC);
-    if (createNewScreen == NULL) {
-	LogMessage(X_ERROR, "AIGLX error: dlsym for %s failed (%s)\n",
-		   CREATE_NEW_SCREEN_FUNC, dlerror());
-      goto handle_error;
+    extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS);
+    if (extensions == NULL) {
+	LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n",
+		   driverName, dlerror());
+	goto handle_error;
     }
     
-    screen->driScreen.private =
-	(*createNewScreen)(pScreen->myNum,
-			   &screen->driScreen,
-			   screen->fd,
-			   sareaHandle,
-			   loader_extensions,
-			   &screen->base.fbconfigs);
-
-    if (screen->driScreen.private == NULL) {
+    for (i = 0; extensions[i]; i++) {
+        if (strcmp(extensions[i]->name, __DRI_CORE) == 0 &&
+	    extensions[i]->version >= __DRI_CORE_VERSION) {
+		screen->core = (const __DRIcoreExtension *) extensions[i];
+	}
+    }
+
+    if (screen->core == NULL) {
+	LogMessage(X_ERROR, "AIGLX error: %s exports no DRI extension\n",
+		   driverName);
+	goto handle_error;
+    }
+
+    screen->driScreen =
+	(*screen->core->createNewScreen)(pScreen->myNum,
+					 screen->fd,
+					 sareaHandle,
+					 loader_extensions,
+					 &driConfigs,
+					 screen);
+
+    if (screen->driScreen == NULL) {
 	LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed");
 	goto handle_error;
     }
 
     initializeExtensions(screen);
 
+    screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs);
+
     __glXScreenInit(&screen->base, pScreen);
 
     buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
diff --git a/GL/glx/glxglcore.c b/GL/glx/glxglcore.c
index 0750e12..bbfa02b 100644
--- a/GL/glx/glxglcore.c
+++ b/GL/glx/glxglcore.c
@@ -46,7 +46,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <glxcontext.h>
 #include <glxutil.h>
 
-#include "glcontextmodes.h"
 #include "os.h"
 
 typedef struct __GLXMESAscreen   __GLXMESAscreen;
@@ -120,7 +119,7 @@ static __GLXdrawable *
 __glXMesaScreenCreateDrawable(__GLXscreen *screen,
 			      DrawablePtr pDraw, int type,
 			      XID drawId,
-			      __GLcontextModes *modes)
+			      __GLXconfig *modes)
 {
     __GLXMESAdrawable *glxPriv;
     XMesaVisual xm_vis;
@@ -217,7 +216,7 @@ __glXMesaContextForceCurrent(__GLXcontext *baseContext)
 
 static __GLXcontext *
 __glXMesaScreenCreateContext(__GLXscreen *screen,
-			     __GLcontextModes *modes,
+			     __GLXconfig *config,
 			     __GLXcontext *baseShareContext)
 {
     __GLXMESAcontext *context;
@@ -232,7 +231,7 @@ __glXMesaScreenCreateContext(__GLXscreen *screen,
     memset(context, 0, sizeof *context);
 
     context->base.pGlxScreen = screen;
-    context->base.modes      = modes;
+    context->base.config     = config;
 
     context->base.destroy        = __glXMesaContextDestroy;
     context->base.makeCurrent    = __glXMesaContextMakeCurrent;
@@ -240,10 +239,10 @@ __glXMesaScreenCreateContext(__GLXscreen *screen,
     context->base.copy           = __glXMesaContextCopy;
     context->base.forceCurrent   = __glXMesaContextForceCurrent;
 
-    xm_vis = find_mesa_visual(screen, modes->fbconfigID);
+    xm_vis = find_mesa_visual(screen, config->fbconfigID);
     if (!xm_vis) {
 	ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n",
-	       modes->visualID);
+	       config->visualID);
 	xfree(context);
 	return NULL;
     }
@@ -282,11 +281,11 @@ static XMesaVisual
 find_mesa_visual(__GLXscreen *screen, XID fbconfigID)
 {
     __GLXMESAscreen *mesaScreen = (__GLXMESAscreen *) screen;
-    const __GLcontextModes *modes;
+    const __GLXconfig *config;
     unsigned i = 0;
 
-    for (modes = screen->fbconfigs; modes != NULL; modes = modes->next) {
- 	if (modes->fbconfigID == fbconfigID)
+    for (config = screen->fbconfigs; config != NULL; config = config->next) {
+ 	if (config->fbconfigID == fbconfigID)
 	    return mesaScreen->xm_vis[i];
 	i++;
     }
@@ -298,18 +297,31 @@ const static int numBack = 2;
 const static int numDepth = 2;
 const static int numStencil = 2;
 
-static __GLcontextModes *
+static const int glx_visual_types[] = {
+    GLX_STATIC_GRAY,
+    GLX_GRAY_SCALE,
+    GLX_STATIC_COLOR,
+    GLX_PSEUDO_COLOR,
+    GLX_TRUE_COLOR,
+    GLX_DIRECT_COLOR
+};
+
+static __GLXconfig *
 createFBConfigsForVisual(__GLXscreen *screen, ScreenPtr pScreen,
-			 VisualPtr visual, __GLcontextModes *config)
+			 VisualPtr visual, __GLXconfig *tail)
 {
     int back, depth, stencil;
+    __GLXconfig *config;
 
     /* FIXME: Ok, I'm making all this up... anybody has a better idea? */
 
     for (back = numBack - 1; back >= 0; back--)
 	for (depth = 0; depth < numDepth; depth++)
 	    for (stencil = 0; stencil < numStencil; stencil++) {
-		config->visualType = _gl_convert_from_x_visual_type(visual->class);
+		config->next = xalloc(sizeof *config);
+		config = config->next;
+
+		config->visualType = glx_visual_types[visual->class];
 		config->xRenderable = GL_TRUE;
 		config->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
 		config->rgbMode = (visual->class >= TrueColor);
@@ -333,35 +345,35 @@ createFBConfigsForVisual(__GLXscreen *screen, ScreenPtr pScreen,
 		config->alphaMask = 0;
 		config->rgbBits = config->rgbMode ? visual->nplanes : 0;
 		config->indexBits = config->colorIndexMode ? visual->nplanes : 0;
-		config = config->next;
 	    }
 
-    return config;
+    return tail;
 }
 
 static void
 createFBConfigs(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
 {
-    __GLcontextModes *configs;
+    __GLXconfig head, *tail;
     int i;
 
     /* We assume here that each existing visual correspond to a
      * different visual class.  Note, this runs before COMPOSITE adds
      * its visual, so it's not entirely crazy. */
     pGlxScreen->numFBConfigs = pScreen->numVisuals * numBack * numDepth * numStencil;
-    pGlxScreen->fbconfigs = _gl_context_modes_create(pGlxScreen->numFBConfigs,
-						     sizeof *configs);
-
-    configs = pGlxScreen->fbconfigs;
+    
+    head.next = NULL;
+    tail = &head;
     for (i = 0; i < pScreen->numVisuals; i++)
-	configs = createFBConfigsForVisual(pGlxScreen, pScreen,
-					   &pScreen->visuals[i], configs);
+	tail = createFBConfigsForVisual(pGlxScreen, pScreen,
+					&pScreen->visuals[i], tail);
+
+    pGlxScreen->fbconfigs = head.next;
 }
 
 static void
 createMesaVisuals(__GLXMESAscreen *pMesaScreen)
 {
-    __GLcontextModes *config;
+    __GLXconfig *config;
     ScreenPtr pScreen;
     VisualPtr visual = NULL;
     int i, j;
diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c
index 6575b27..b49a775 100644
--- a/GL/glx/glxscreens.c
+++ b/GL/glx/glxscreens.c
@@ -37,6 +37,7 @@
 #include <dix-config.h>
 #endif
 
+#include <GL/glxtokens.h>
 #include <string.h>
 #include <windowstr.h>
 #include <os.h>
@@ -46,7 +47,6 @@
 #include "glxserver.h"
 #include "glxutil.h"
 #include "glxext.h"
-#include "glcontextmodes.h"
 
 static DevPrivateKey glxScreenPrivateKey = &glxScreenPrivateKey;
 
@@ -280,10 +280,23 @@ void GlxSetVisualConfigs(int nconfigs,
      * call it. */
 }
 
+GLint glxConvertToXVisualType(int visualType)
+{
+    static const int x_visual_types[] = {
+	TrueColor,   DirectColor,
+	PseudoColor, StaticColor,
+	GrayScale,   StaticGray
+    };
+
+    return ( (unsigned) (visualType - GLX_TRUE_COLOR) < 6 )
+	? x_visual_types[ visualType - GLX_TRUE_COLOR ] : -1;
+}
+
+
 static void
 filterOutNativeConfigs(__GLXscreen *pGlxScreen)
 {
-    __GLcontextModes *m, *next, *native_modes, **last;
+    __GLXconfig *m, *next, **last;
     ScreenPtr pScreen = pGlxScreen->pScreen;
     int i, depth;
 
@@ -305,12 +318,12 @@ filterOutNativeConfigs(__GLXscreen *pGlxScreen)
 }
 
 static XID
-findVisualForConfig(ScreenPtr pScreen, __GLcontextModes *m)
+findVisualForConfig(ScreenPtr pScreen, __GLXconfig *m)
 {
     int i;
 
     for (i = 0; i < pScreen->numVisuals; i++) {
-	if (_gl_convert_to_x_visual_type(m->visualType) == pScreen->visuals[i].class)
+	if (glxConvertToXVisualType(m->visualType) == pScreen->visuals[i].class)
 	    return pScreen->visuals[i].vid;
     }
 
@@ -405,10 +418,10 @@ findFirstSet(unsigned int v)
 }
 
 static void
-initGlxVisual(VisualPtr visual, __GLcontextModes *config)
+initGlxVisual(VisualPtr visual, __GLXconfig *config)
 {
     config->visualID = visual->vid;
-    visual->class = _gl_convert_to_x_visual_type(config->visualType);
+    visual->class = glxConvertToXVisualType(config->visualType);
     visual->bitsPerRGBValue = config->redBits;
     visual->ColormapEntries = 1 << config->redBits;
     visual->nplanes = config->redBits + config->greenBits + config->blueBits;
@@ -426,15 +439,15 @@ typedef struct {
     GLboolean depthBuffer;
 } FBConfigTemplateRec, *FBConfigTemplatePtr;
 
-static __GLcontextModes *
+static __GLXconfig *
 pickFBConfig(__GLXscreen *pGlxScreen, FBConfigTemplatePtr template, int class)
 {
-    __GLcontextModes *config;
+    __GLXconfig *config;
 
     for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) {
 	if (config->visualRating != GLX_NONE)
 	    continue;
-	if (_gl_convert_to_x_visual_type(config->visualType) != class)
+	if (glxConvertToXVisualType(config->visualType) != class)
 	    continue;
 	if ((config->doubleBufferMode > 0) != template->doubleBuffer)
 	    continue;
@@ -450,32 +463,36 @@ pickFBConfig(__GLXscreen *pGlxScreen, FBConfigTemplatePtr template, int class)
 static void
 addMinimalSet(__GLXscreen *pGlxScreen)
 {
-    __GLcontextModes *config;
+    __GLXconfig *config;
     VisualPtr visuals;
-    int i;
+    int i, j;
     FBConfigTemplateRec best = { GL_TRUE, GL_TRUE };
     FBConfigTemplateRec minimal = { GL_FALSE, GL_FALSE };
 
     pGlxScreen->visuals = xcalloc(pGlxScreen->pScreen->numVisuals,
-				  sizeof (__GLcontextModes *));
+				  sizeof (__GLXconfig *));
     if (pGlxScreen->visuals == NULL) {
 	ErrorF("Failed to allocate for minimal set of GLX visuals\n");
 	return;
     }
 
-    pGlxScreen->numVisuals = pGlxScreen->pScreen->numVisuals;
     visuals = pGlxScreen->pScreen->visuals;
-    for (i = 0; i < pGlxScreen->numVisuals; i++) {
+    for (i = 0, j = 0; i < pGlxScreen->pScreen->numVisuals; i++) {
 	if (visuals[i].nplanes == 32)
 	    config = pickFBConfig(pGlxScreen, &minimal, visuals[i].class);
 	else
 	    config = pickFBConfig(pGlxScreen, &best, visuals[i].class);
 	if (config == NULL)
 	    config = pGlxScreen->fbconfigs;
-	pGlxScreen->visuals[i] = config;
-	config->visualID = visuals[i].vid;
+	if (config == NULL)
+	    continue;
+
+	pGlxScreen->visuals[j] = config;
+	config->visualID = visuals[j].vid;
+	j++;
     }
 
+    pGlxScreen->numVisuals = j;
 }
 
 static void
@@ -487,12 +504,12 @@ addTypicalSet(__GLXscreen *pGlxScreen)
 static void
 addFullSet(__GLXscreen *pGlxScreen)
 {
-    __GLcontextModes *config;
+    __GLXconfig *config;
     VisualPtr visuals;
     int i, depth;
 
     pGlxScreen->visuals =
-	xcalloc(pGlxScreen->numFBConfigs, sizeof (__GLcontextModes *));
+	xcalloc(pGlxScreen->numFBConfigs, sizeof (__GLXconfig *));
     if (pGlxScreen->visuals == NULL) {
 	ErrorF("Failed to allocate for full set of GLX visuals\n");
 	return;
@@ -522,7 +539,7 @@ void GlxSetVisualConfig(int config)
 
 void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
 {
-    __GLcontextModes *m;
+    __GLXconfig *m;
     int i;
 
     pGlxScreen->pScreen       = pScreen;
diff --git a/GL/glx/glxscreens.h b/GL/glx/glxscreens.h
index f1eef91..39d162d 100644
--- a/GL/glx/glxscreens.h
+++ b/GL/glx/glxscreens.h
@@ -40,8 +40,6 @@
 **
 */
 
-#include "GL/internal/glcore.h"
-
 typedef struct {
     void * (* queryHyperpipeNetworkFunc)(int, int *, int *);
     void * (* queryHyperpipeConfigFunc)(int, int, int *, int *);
@@ -57,6 +55,84 @@ typedef struct {
 void __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs);
 void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs);
 
+typedef struct __GLXconfig __GLXconfig;
+struct __GLXconfig {
+    __GLXconfig *next;
+    GLboolean rgbMode;
+    GLboolean floatMode;
+    GLboolean colorIndexMode;
+    GLuint doubleBufferMode;
+    GLuint stereoMode;
+
+    GLboolean haveAccumBuffer;
+    GLboolean haveDepthBuffer;
+    GLboolean haveStencilBuffer;
+
+    GLint redBits, greenBits, blueBits, alphaBits;	/* bits per comp */
+    GLuint redMask, greenMask, blueMask, alphaMask;
+    GLint rgbBits;		/* total bits for rgb */
+    GLint indexBits;		/* total bits for colorindex */
+
+    GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits;
+    GLint depthBits;
+    GLint stencilBits;
+
+    GLint numAuxBuffers;
+
+    GLint level;
+
+    GLint pixmapMode;
+
+    /* GLX */
+    GLint visualID;
+    GLint visualType;     /**< One of the GLX X visual types. (i.e., 
+			   * \c GLX_TRUE_COLOR, etc.)
+			   */
+
+    /* EXT_visual_rating / GLX 1.2 */
+    GLint visualRating;
+
+    /* EXT_visual_info / GLX 1.2 */
+    GLint transparentPixel;
+				/*    colors are floats scaled to ints */
+    GLint transparentRed, transparentGreen, transparentBlue, transparentAlpha;
+    GLint transparentIndex;
+
+    /* ARB_multisample / SGIS_multisample */
+    GLint sampleBuffers;
+    GLint samples;
+
+    /* SGIX_fbconfig / GLX 1.3 */
+    GLint drawableType;
+    GLint renderType;
+    GLint xRenderable;
+    GLint fbconfigID;
+
+    /* SGIX_pbuffer / GLX 1.3 */
+    GLint maxPbufferWidth;
+    GLint maxPbufferHeight;
+    GLint maxPbufferPixels;
+    GLint optimalPbufferWidth;   /* Only for SGIX_pbuffer. */
+    GLint optimalPbufferHeight;  /* Only for SGIX_pbuffer. */
+
+    /* SGIX_visual_select_group */
+    GLint visualSelectGroup;
+
+    /* OML_swap_method */
+    GLint swapMethod;
+
+    GLint screen;
+
+    /* EXT_texture_from_pixmap */
+    GLint bindToTextureRgb;
+    GLint bindToTextureRgba;
+    GLint bindToMipmapTexture;
+    GLint bindToTextureTargets;
+    GLint yInverted;
+};
+
+GLint glxConvertToXVisualType(int visualType);
+
 /*
 ** Screen dependent data.  These methods are the interface between the DIX
 ** and DDX layers of the GLX server extension.  The methods provide an
@@ -67,14 +143,14 @@ struct __GLXscreen {
     void          (*destroy)       (__GLXscreen *screen);
 
     __GLXcontext *(*createContext) (__GLXscreen *screen,
-				    __GLcontextModes *modes,
+				    __GLXconfig *modes,
 				    __GLXcontext *shareContext);
 
     __GLXdrawable *(*createDrawable)(__GLXscreen *context,
 				     DrawablePtr pDraw,
 				     int type,
 				     XID drawId,
-				     __GLcontextModes *modes);
+				     __GLXconfig *modes);
     int            (*swapInterval)  (__GLXdrawable *drawable,
 				     int interval);
 
@@ -84,11 +160,11 @@ struct __GLXscreen {
     ScreenPtr pScreen;
 
     /* Linked list of valid fbconfigs for this screen. */
-    __GLcontextModes *fbconfigs;
+    __GLXconfig *fbconfigs;
     int numFBConfigs;
 
     /* Subset of fbconfigs that are exposed as GLX visuals. */
-    __GLcontextModes **visuals;
+    __GLXconfig **visuals;
     GLint numVisuals;
 
     char *GLextensions;
diff --git a/GL/glx/glxutil.c b/GL/glx/glxutil.c
index f531ed9..11e9f89 100644
--- a/GL/glx/glxutil.c
+++ b/GL/glx/glxutil.c
@@ -49,7 +49,6 @@
 #include "glxutil.h"
 #include "GL/internal/glcore.h"
 #include "GL/glxint.h"
-#include "glcontextmodes.h"
 
 /************************************************************************/
 /* Context stuff */
@@ -140,13 +139,13 @@ __glXUnrefDrawable(__GLXdrawable *glxPriv)
 GLboolean
 __glXDrawableInit(__GLXdrawable *drawable,
 		  __GLXscreen *screen, DrawablePtr pDraw, int type,
-		  XID drawId, __GLcontextModes *modes)
+		  XID drawId, __GLXconfig *config)
 {
     drawable->pDraw = pDraw;
     drawable->type = type;
     drawable->drawId = drawId;
     drawable->refCount = 1;
-    drawable->modes = modes;
+    drawable->config = config;
     drawable->eventMask = 0;
 
     return GL_TRUE;
diff --git a/GL/glx/glxutil.h b/GL/glx/glxutil.h
index 6534c3f..00c7b20 100644
--- a/GL/glx/glxutil.h
+++ b/GL/glx/glxutil.h
@@ -51,7 +51,7 @@ extern void __glXUnrefDrawable(__GLXdrawable *glxPriv);
 extern GLboolean __glXDrawableInit(__GLXdrawable *drawable,
 				   __GLXscreen *screen,
 				   DrawablePtr pDraw, int type, XID drawID,
-				   __GLcontextModes *modes);
+				   __GLXconfig *config);
 
 /* context helper routines */
 extern __GLXcontext *__glXLookupContextByTag(__GLXclientState*, GLXContextTag);
diff --git a/GL/symlink-mesa.sh b/GL/symlink-mesa.sh
index af9adbd..47afdcd 100755
--- a/GL/symlink-mesa.sh
+++ b/GL/symlink-mesa.sh
@@ -227,8 +227,6 @@ symlink_glx() {
     dst_dir glx
 
     action indirect_size.h
-    action glcontextmodes.c
-    action glcontextmodes.h
     action indirect_dispatch.c
     action indirect_dispatch.h
     action indirect_dispatch_swap.c
diff --git a/configure.ac b/configure.ac
index 959f0ae..e72e3b9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -860,7 +860,7 @@ AM_CONDITIONAL(DRI2, test "x$DRI2" = xyes)
 if test "x$DRI2" = xyes; then
 	# FIXME: Bump the versions once we have releases of these.
 	AC_DEFINE(DRI2, 1, [Build DRI2 extension])
-	PKG_CHECK_MODULES([DRIPROTO], [xf86driproto >= 2.0.3])
+	PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 1.0.0])
 	PKG_CHECK_MODULES([LIBDRM], [libdrm >= 2.3.1])
 fi
 
diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 4a4aabc..8de7426 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -121,6 +121,7 @@ static ModuleDefault ModuleDefaults[] = {
     {.name = "freetype", .toLoad = TRUE,    .load_opt=NULL},
     {.name = "record",   .toLoad = TRUE,    .load_opt=NULL},
     {.name = "dri",      .toLoad = TRUE,    .load_opt=NULL},
+    {.name = "dri2",     .toLoad = TRUE,    .load_opt=NULL},
     {.name = NULL,       .toLoad = FALSE,   .load_opt=NULL}
 };
 
diff --git a/hw/xfree86/dri2/Makefile.am b/hw/xfree86/dri2/Makefile.am
index be3cea4..844c912 100644
--- a/hw/xfree86/dri2/Makefile.am
+++ b/hw/xfree86/dri2/Makefile.am
@@ -2,7 +2,7 @@ libdri2_la_LTLIBRARIES = libdri2.la
 libdri2_la_CFLAGS = \
 	-DHAVE_XORG_CONFIG_H \
 	-I at MESA_SOURCE@/include \
-	@DIX_CFLAGS@ @DRIPROTO_CFLAGS@ @LIBDRM_CFLAGS@ \
+	@DIX_CFLAGS@ @DRI2PROTO_CFLAGS@ @LIBDRM_CFLAGS@ \
 	-I$(top_srcdir)/hw/xfree86/common \
 	-I$(top_srcdir)/hw/xfree86/os-support/bus
 
@@ -10,6 +10,7 @@ libdri2_la_LDFLAGS = -module -avoid-version @LIBDRM_LIBS@
 libdri2_ladir = $(moduledir)/extensions
 libdri2_la_SOURCES = \
 	dri2.c \
-	dri2.h
+	dri2.h \
+	dri2ext.c
 
 sdk_HEADERS = dri2.h
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index d527387..74aef71 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -38,6 +38,8 @@
 #include "xf86Module.h"
 #include "scrnintstr.h"
 #include "windowstr.h"
+#include "region.h" 
+#include "damage.h" 
 #include "dri2.h"
 #include <GL/internal/dri_sarea.h>
 
@@ -48,8 +50,9 @@ static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKey;
 static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKey;
 
 typedef struct _DRI2DrawablePriv {
-    drm_drawable_t		 drawable;
-    unsigned int		 handle;
+    unsigned int		 refCount;
+    unsigned int		 boHandle;
+    unsigned int		 dri2Handle;
 } DRI2DrawablePrivRec, *DRI2DrawablePrivPtr;
 
 typedef struct _DRI2Screen {
@@ -58,6 +61,7 @@ typedef struct _DRI2Screen {
     void			*sarea;
     unsigned int		 sareaSize;
     const char			*driverName;
+    unsigned int		 nextHandle;
 
     __DRIEventBuffer		*buffer;
     int				 locked;
@@ -147,7 +151,7 @@ DRI2PostDrawableConfig(DrawablePtr pDraw)
 
     e = DRI2ScreenAllocEvent(ds, size);
     e->event_header = DRI2_EVENT_HEADER(DRI2_EVENT_DRAWABLE_CONFIG, size);
-    e->drawable = pPriv->drawable;
+    e->drawable = pPriv->dri2Handle;
     e->x = pDraw->x - pPixmap->screen_x;
     e->y = pDraw->y - pPixmap->screen_y;
     e->width = pDraw->width;
@@ -164,7 +168,7 @@ DRI2PostDrawableConfig(DrawablePtr pDraw)
 }
 
 static void
-DRI2PostBufferAttach(DrawablePtr pDraw)
+DRI2PostBufferAttach(DrawablePtr pDraw, Bool force)
 {
     ScreenPtr			 pScreen = pDraw->pScreen;
     DRI2ScreenPtr		 ds = DRI2GetScreen(pScreen);
@@ -173,7 +177,8 @@ DRI2PostBufferAttach(DrawablePtr pDraw)
     PixmapPtr			 pPixmap;
     __DRIBufferAttachEvent	*e;
     size_t			 size;
-    unsigned int		 handle, flags;
+    unsigned int		 flags;
+    unsigned int		 boHandle;
 
     if (pDraw->type == DRAWABLE_WINDOW) {
 	pWin = (WindowPtr) pDraw;
@@ -187,22 +192,20 @@ DRI2PostBufferAttach(DrawablePtr pDraw)
     if (!pPriv)
 	return;
 
-    size = sizeof *e;
-
-    handle = ds->getPixmapHandle(pPixmap, &flags);
-    if (handle == 0 || handle == pPriv->handle)
+    boHandle = ds->getPixmapHandle(pPixmap, &flags);
+    if (boHandle == pPriv->boHandle && !force)
 	return;
 
+    pPriv->boHandle = boHandle;
+    size = sizeof *e;
     e = DRI2ScreenAllocEvent(ds, size);
     e->event_header = DRI2_EVENT_HEADER(DRI2_EVENT_BUFFER_ATTACH, size);
-    e->drawable = pPriv->drawable;
+    e->drawable = pPriv->dri2Handle;
     e->buffer.attachment = DRI_DRAWABLE_BUFFER_FRONT_LEFT;
-    e->buffer.handle = handle;
+    e->buffer.handle = pPriv->boHandle;
     e->buffer.pitch = pPixmap->devKind;
     e->buffer.cpp = pPixmap->drawable.bitsPerPixel / 8;
     e->buffer.flags = flags;
-
-    pPriv->handle = handle;
 }
 
 static void
@@ -223,7 +226,7 @@ DRI2ClipNotify(WindowPtr pWin, int dx, int dy)
     }
 
     DRI2PostDrawableConfig(&pWin->drawable);
-    DRI2PostBufferAttach(&pWin->drawable);
+    DRI2PostBufferAttach(&pWin->drawable, FALSE);
 }
 
 static void
@@ -262,10 +265,10 @@ DRI2CloseScreen(ScreenPtr pScreen)
 }
 
 Bool
-DRI2CreateDrawable(ScreenPtr pScreen, DrawablePtr pDraw,
-		   drm_drawable_t *pDrmDrawable, unsigned int *head)
+DRI2CreateDrawable(DrawablePtr pDraw,
+		   unsigned int *handle, unsigned int *head)
 {
-    DRI2ScreenPtr	ds = DRI2GetScreen(pScreen);
+    DRI2ScreenPtr	ds = DRI2GetScreen(pDraw->pScreen);
     WindowPtr		pWin;
     PixmapPtr		pPixmap;
     DRI2DrawablePrivPtr pPriv;
@@ -283,47 +286,66 @@ DRI2CreateDrawable(ScreenPtr pScreen, DrawablePtr pDraw,
     }
 
     pPriv = dixLookupPrivate(devPrivates, key);
-    if (pPriv == NULL) {
+    if (pPriv != NULL) {
+	pPriv->refCount++;
+    } else {
 	pPriv = xalloc(sizeof *pPriv);
-	if (drmCreateDrawable(ds->fd, &pPriv->drawable))
-	    return FALSE;
-
+	pPriv->refCount = 1;
+	pPriv->boHandle = 0;
+	pPriv->dri2Handle = ds->nextHandle++;
 	dixSetPrivate(devPrivates, key, pPriv);
     }
 
-    *pDrmDrawable = pPriv->drawable;
-
+    *handle = pPriv->dri2Handle;
     *head = ds->buffer->head;
+
     DRI2PostDrawableConfig(pDraw);
-    DRI2PostBufferAttach(pDraw);
+    DRI2PostBufferAttach(pDraw, TRUE);
     DRI2ScreenCommitEvents(ds);
 
     return TRUE;
 }
 
 void
-DRI2DestroyDrawable(ScreenPtr pScreen, DrawablePtr pDraw)
+DRI2DestroyDrawable(DrawablePtr pDraw)
 {
-    DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
-    PixmapPtr pPixmap;
-    WindowPtr pWin;
-    DRI2DrawablePrivPtr pPriv;
+    PixmapPtr		  pPixmap;
+    WindowPtr		  pWin;
+    DRI2DrawablePrivPtr   pPriv;
+    DevPrivateKey	  key;
+    PrivateRec		**devPrivates;
 
     if (pDraw->type == DRAWABLE_WINDOW) {
 	pWin = (WindowPtr) pDraw;
-	pPriv = dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
-	dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
+	devPrivates = &pWin->devPrivates;
+	key = dri2WindowPrivateKey;
     } else {
 	pPixmap = (PixmapPtr) pDraw;
-	pPriv = dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
-	dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
+	devPrivates = &pPixmap->devPrivates;
+	key = dri2PixmapPrivateKey;
     }
 
+    pPriv = dixLookupPrivate(devPrivates, key);
     if (pPriv == NULL)
 	return;
     
-    drmDestroyDrawable(ds->fd, pPriv->drawable);
-    xfree(pPriv);
+    pPriv->refCount--;
+    if (pPriv->refCount == 0) {
+	dixSetPrivate(devPrivates, key, NULL);
+	xfree(pPriv);
+    }
+}
+
+void
+DRI2ReemitDrawableInfo(DrawablePtr pDraw, unsigned int *head)
+{
+    DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+
+    *head = ds->buffer->head;
+
+    DRI2PostDrawableConfig(pDraw);
+    DRI2PostBufferAttach(pDraw, TRUE);
+    DRI2ScreenCommitEvents(ds);
 }
 
 Bool
@@ -409,8 +431,9 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
     if (!ds)
 	return NULL;
 
-    ds->fd = info->fd;
+    ds->fd			= info->fd;
     ds->driverName		= info->driverName;
+    ds->nextHandle		= 1;
 
     ds->getPixmapHandle		= info->getPixmapHandle;
     ds->beginClipNotify		= info->beginClipNotify;
@@ -434,9 +457,21 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
     return p;
 }
 
+extern ExtensionModule dri2ExtensionModule;
+
 static pointer
 DRI2Setup(pointer module, pointer opts, int *errmaj, int *errmin)
 {
+    static Bool setupDone = FALSE;
+
+    if (!setupDone) {
+	setupDone = TRUE;
+	LoadExtension(&dri2ExtensionModule, FALSE);
+    } else {
+	if (errmaj)
+	    *errmaj = LDR_ONCEONLY;
+    }
+
     return (pointer) 1;
 }
 
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index 126087a..85b3da4 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -66,14 +66,16 @@ unsigned int DRI2GetPixmapHandle(PixmapPtr pPixmap,
 void DRI2Lock(ScreenPtr pScreen);
 void DRI2Unlock(ScreenPtr pScreen);
 
-Bool DRI2CreateDrawable(ScreenPtr	 pScreen,
-			DrawablePtr	 pDraw,
-			drm_drawable_t	*pDrmDrawable,
-			unsigned int    *head);
+Bool DRI2CreateDrawable(DrawablePtr pDraw,
+			unsigned int *handle,
+			unsigned int *head);
 
-void DRI2DestroyDrawable(ScreenPtr	pScreen,
-			 DrawablePtr	pDraw);
+void DRI2DestroyDrawable(DrawablePtr pDraw);
 
-void DRI2ExtensionInit(void);
+void DRI2ReemitDrawableInfo(DrawablePtr pDraw,
+			    unsigned int *head);
+
+Bool DRI2PostDamage(DrawablePtr pDrawable,
+		    struct drm_clip_rect *rects, int numRects);
 
 #endif
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
new file mode 100644
index 0000000..ca2e029
--- /dev/null
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -0,0 +1,361 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Soft-
+ * ware"), to deal in the Software without restriction, including without
+ * limitation the rights to use, copy, modify, merge, publish, distribute,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, provided that the above copyright
+ * notice(s) and this permission notice appear in all copies of the Soft-
+ * ware and that both the above copyright notice(s) and this permission
+ * notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
+ * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
+ * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
+ * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
+ * MANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder shall
+ * not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization of
+ * the copyright holder.
+ *
+ * Authors:
+ *   Kristian Høgsberg (krh at redhat.com)
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#define NEED_REPLIES
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "dixstruct.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "extnsionst.h"
+#include "xf86drm.h"
+#include "dri2proto.h"
+#include "dri2.h"
+
+/* The only xf86 include */
+#include "xf86Module.h"
+
+static ExtensionEntry	*dri2Extension;
+static RESTYPE		 dri2DrawableRes;
+
+static Bool
+validScreen(ClientPtr client, int screen, ScreenPtr *pScreen)
+{
+    if (screen >= screenInfo.numScreens) {
+	client->errorValue = screen;
+	return FALSE;
+    }
+
+    *pScreen = screenInfo.screens[screen];
+
+    return TRUE;
+}
+
+static Bool
+validDrawable(ClientPtr client, XID drawable,
+	      DrawablePtr *pDrawable, int *status)
+{
+    *status = dixLookupDrawable(pDrawable, drawable, client, 0, DixReadAccess);
+    if (*status != Success) {
+	client->errorValue = drawable;
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
+static int
+ProcDRI2QueryVersion(ClientPtr client)
+{
+    REQUEST(xDRI2QueryVersionReq);
+    xDRI2QueryVersionReply rep;
+    int n;
+
+    if (client->swapped)
+	swaps(&stuff->length, n);
+
+    REQUEST_SIZE_MATCH(xDRI2QueryVersionReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.majorVersion = DRI2_MAJOR;
+    rep.minorVersion = DRI2_MINOR;
+
+    if (client->swapped) {
+    	swaps(&rep.sequenceNumber, n);
+    	swapl(&rep.length, n);
+	swapl(&rep.majorVersion, n);
+	swapl(&rep.minorVersion, n);
+    }
+
+    WriteToClient(client, sizeof(xDRI2QueryVersionReply), &rep);
+
+    return client->noClientException;
+}
+
+static int
+ProcDRI2Connect(ClientPtr client)
+{
+    REQUEST(xDRI2ConnectReq);
+    xDRI2ConnectReply rep;
+    ScreenPtr pScreen;
+    int fd;
+    const char *driverName;
+    char *busId;
+    unsigned int sareaHandle;
+
+    REQUEST_SIZE_MATCH(xDRI2ConnectReq);
+    if (!validScreen(client, stuff->screen, &pScreen))
+	return BadValue;
+    
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.driverNameLength = 0;
+    rep.busIdLength = 0;
+    rep.sareaHandle = 0;
+
+    if (!DRI2Connect(pScreen, &fd, &driverName, &sareaHandle))
+	goto fail;
+
+    busId = drmGetBusid(fd);
+    if (busId == NULL)
+	goto fail;
+
+    rep.driverNameLength = strlen(driverName);
+    rep.busIdLength = strlen(busId);
+    rep.sareaHandle = sareaHandle;
+    rep.length = (rep.driverNameLength + 3) / 4 + (rep.busIdLength + 3) / 4;
+
+ fail:
+    WriteToClient(client, sizeof(xDRI2ConnectReply), &rep);
+    WriteToClient(client, rep.driverNameLength, driverName);
+    WriteToClient(client, rep.busIdLength, busId);
+    drmFreeBusid(busId);
+
+    return client->noClientException;
+}
+
+static int
+ProcDRI2AuthConnection(ClientPtr client)
+{
+    REQUEST(xDRI2AuthConnectionReq);
+    xDRI2AuthConnectionReply rep;
+    ScreenPtr pScreen;
+
+    REQUEST_SIZE_MATCH(xDRI2AuthConnectionReq);
+    if (!validScreen(client, stuff->screen, &pScreen))
+	return BadValue;
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.authenticated = 1;
+
+    if (!DRI2AuthConnection(pScreen, stuff->magic)) {
+        ErrorF("DRI2: Failed to authenticate %lu\n",
+	       (unsigned long) stuff->magic);
+	rep.authenticated = 0;
+    }
+
+    WriteToClient(client, sizeof(xDRI2AuthConnectionReply), &rep);
+
+    return client->noClientException;
+}
+
+static int
+ProcDRI2CreateDrawable(ClientPtr client)
+{
+    REQUEST(xDRI2CreateDrawableReq);
+    xDRI2CreateDrawableReply rep;
+    DrawablePtr pDrawable;
+    unsigned int handle, head;
+    int status;
+
+    REQUEST_SIZE_MATCH(xDRI2CreateDrawableReq);
+
+    if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
+	return status;
+
+    if (!DRI2CreateDrawable(pDrawable, &handle, &head))
+	return BadMatch;
+
+    if (!AddResource(stuff->drawable, dri2DrawableRes, pDrawable)) {
+	DRI2DestroyDrawable(pDrawable);
+	return BadAlloc;
+    }
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.handle = handle;
+    rep.head = head;
+
+    WriteToClient(client, sizeof(xDRI2CreateDrawableReply), &rep);
+
+    return client->noClientException;
+}
+
+static int
+ProcDRI2DestroyDrawable(ClientPtr client)
+{
+    REQUEST(xDRI2DestroyDrawableReq);
+    DrawablePtr pDrawable;
+    int status;
+
+    REQUEST_SIZE_MATCH(xDRI2DestroyDrawableReq);
+    if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
+	return status;
+
+    FreeResourceByType(stuff->drawable, dri2DrawableRes, FALSE);
+
+    return client->noClientException;
+}
+
+static int
+ProcDRI2ReemitDrawableInfo(ClientPtr client)
+{
+    REQUEST(xDRI2ReemitDrawableInfoReq);
+    xDRI2ReemitDrawableInfoReply rep;
+    DrawablePtr pDrawable;
+    unsigned int head;
+    int status;
+
+    REQUEST_SIZE_MATCH(xDRI2ReemitDrawableInfoReq);
+    if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
+	return status;
+
+    DRI2ReemitDrawableInfo(pDrawable, &head);
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.head = head;
+
+    WriteToClient(client, sizeof(xDRI2ReemitDrawableInfoReply), &rep);
+
+    return client->noClientException;
+}
+
+static int
+ProcDRI2Dispatch (ClientPtr client)
+{
+    REQUEST(xReq);
+    
+    switch (stuff->data) {
+    case X_DRI2QueryVersion:
+	return ProcDRI2QueryVersion(client);
+    }
+
+    if (!LocalClient(client))
+	return BadRequest;
+
+    switch (stuff->data) {
+    case X_DRI2Connect:
+	return ProcDRI2Connect(client);
+    case X_DRI2AuthConnection:
+	return ProcDRI2AuthConnection(client);
+    case X_DRI2CreateDrawable:
+	return ProcDRI2CreateDrawable(client);
+    case X_DRI2DestroyDrawable:
+	return ProcDRI2DestroyDrawable(client);
+    case X_DRI2ReemitDrawableInfo:
+	return ProcDRI2ReemitDrawableInfo(client);
+    default:
+	return BadRequest;
+    }
+}
+
+static int
+SProcDRI2Connect(ClientPtr client)
+{
+    REQUEST(xDRI2ConnectReq);
+    xDRI2ConnectReply rep;
+    int n;
+
+    /* If the client is swapped, it's not local.  Talk to the hand. */
+
+    swaps(&stuff->length, n);
+    if (sizeof(*stuff) / 4 != client->req_len)
+	return BadLength;
+
+    rep.sequenceNumber = client->sequence;
+    swaps(&rep.sequenceNumber, n);
+    rep.length = 0;
+    rep.driverNameLength = 0;
+    rep.busIdLength = 0;
+    rep.sareaHandle = 0;
+
+    return client->noClientException;
+}
+
+static int
+SProcDRI2Dispatch (ClientPtr client)
+{
+    REQUEST(xReq);
+
+    /*
+     * Only local clients are allowed DRI access, but remote clients
+     * still need these requests to find out cleanly.
+     */
+    switch (stuff->data)
+    {
+    case X_DRI2QueryVersion:
+	return ProcDRI2QueryVersion(client);
+    case X_DRI2Connect:
+	return SProcDRI2Connect(client);
+    default:
+	return BadRequest;
+    }
+}
+
+static void
+DRI2ResetProc (ExtensionEntry *extEntry)
+{
+}
+
+static int DRI2DrawableGone(pointer p, XID id)
+{
+    DrawablePtr pDrawable = p;
+
+    DRI2DestroyDrawable(pDrawable);
+
+    return Success;
+}
+
+static void
+DRI2ExtensionInit(void)
+{
+    dri2Extension = AddExtension(DRI2_NAME,
+				 DRI2NumberEvents,
+				 DRI2NumberErrors,
+				 ProcDRI2Dispatch,
+				 SProcDRI2Dispatch,
+				 DRI2ResetProc,
+				 StandardMinorOpcode);
+
+    dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone);
+}
+
+extern Bool noDRI2Extension;
+
+_X_HIDDEN ExtensionModule dri2ExtensionModule = {
+    DRI2ExtensionInit,
+    DRI2_NAME,
+    &noDRI2Extension,
+    NULL,
+    NULL
+};
diff --git a/os/utils.c b/os/utils.c
index 57293ab..d785d46 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -239,6 +239,9 @@ _X_EXPORT int selinuxEnforcingState = SELINUX_MODE_DEFAULT;
 #ifdef XV
 _X_EXPORT Bool noXvExtension = FALSE;
 #endif
+#ifdef DRI2
+_X_EXPORT Bool noDRI2Extension = FALSE;
+#endif
 
 #define X_INCLUDE_NETDB_H
 #include <X11/Xos_r.h>


More information about the xorg-commit mailing list