Running Xgl on Mesa: Patches

To get Xgl and Mesa (inside Xnest) work together I made the following changes to CVS snapshots downloaded on April 29, 2006 of Xgl, Mesa and Xorg.

Patching Mesa

Mesa Change 1

This change is a real bugfix. It fixes a crash which occured due to an uninitialized function pointer.

Please note: This is already fixed in the current CVS version of Mesa.


--- src/mesa/drivers/x11/xm_tri.c	2006/05/15 08:28:11
+++ src/mesa/drivers/x11/xm_tri.c	2006/05/18 11:39:21
@@ -1609,22 +1609,28 @@
                   USE(flat_DITHER_triangle);
             case PF_Lookup:
                if (depth == 8)
                   USE(flat_LOOKUP8_triangle);
                else
                   return (swrast_tri_func) NULL;
             default:
                return (swrast_tri_func) NULL;
          }
       }
+      
+      /* CLI fix crash */
+      return (swrast_tri_func) NULL;
+   } else {
+       /* draw to pixmap */
+      return (swrast_tri_func) NULL;
    }
-
+      /* CLI fix crash end of change*/
 #else
    return (swrast_tri_func) NULL;
 #endif /* CHAN_BITS == 8 */
 }
 
 
 /* Override for the swrast tri-selection function.  Try to use one
  * of our internal tri functions, otherwise fall back to the
  * standard swrast functions.
  */

Mesa Change 2

This change is a hack which works around a bug and only works if Mesa is used inside an Xserver to implement GLX.

The following two diffs apply to the Xserver code:


--- GL/glx/glxutil.c	2006/05/19 12:23:58
+++ GL/glx/glxutil.c	2006/05/20 04:06:29
@@ -67,20 +67,26 @@
 
     __glXRefDrawable(glxc->drawPriv);
     
 
     glxc->nextReadPriv = glxc->readPriv->readGlxc;
     glxc->readPriv->readGlxc = glxc;
 
     __glXRefDrawable(glxc->readPriv);
 }
 
+/* hack: bypass function pointers in __GLXcontext which should have
+    been declared for these operations */
+extern void __glXSetDrawBufferToNull( __GLXcontext *baseContext );
+
+extern void __glXSetReadBufferToNull( __GLXcontext *baseContext );
+
 /*
 ** Deassociate a context from a drawable
 */
 void
 __glXDeassociateContext(__GLXcontext *glxc)
 {
     __GLXcontext *curr, *prev;
 
     prev = NULL;
     for ( curr = glxc->drawPriv->drawGlxc
@@ -88,38 +94,42 @@
 	  ; prev = curr, curr = curr->nextDrawPriv ) {
 	if (curr == glxc) {
 	    /* found context.  Deassociate. */
 	    if (prev == NULL) {
 		glxc->drawPriv->drawGlxc = curr->nextDrawPriv;
 	    } else {
 		prev->nextDrawPriv = curr->nextDrawPriv;
 	    }
 	    curr->nextDrawPriv = NULL;
 	    __glXUnrefDrawable(glxc->drawPriv);
+	    glxc->drawPriv = NULL;
+	    __glXSetDrawBufferToNull(glxc);
 	    break;
 	}
     }
 
 
     prev = NULL;
     for ( curr = glxc->readPriv->readGlxc
 	  ; curr != NULL 
 	  ; prev = curr, curr = curr->nextReadPriv ) {
 	if (curr == glxc) {
 	    /* found context.  Deassociate. */
 	    if (prev == NULL) {
 		glxc->readPriv->readGlxc = curr->nextReadPriv;
 	    } else {
 		prev->nextReadPriv = curr->nextReadPriv;
 	    }
 	    curr->nextReadPriv = NULL;
 	    __glXUnrefDrawable(glxc->readPriv);
+	    glxc->readPriv = NULL;
+	    __glXSetReadBufferToNull(glxc);
 	    break;
 	}
     }
 }
 
 /*****************************************************************************/
 /* Drawable private stuff */
 
 void
 __glXRefDrawable(__GLXdrawable *glxPriv)

--- GL/mesa/X/xf86glx.c	2006/05/19 12:24:18
+++ GL/mesa/X/xf86glx.c	2006/05/19 13:42:32
@@ -207,20 +207,34 @@
 {
     __GLXMESAcontext *context = (__GLXMESAcontext *) baseContext;
     __GLXMESAdrawable *drawPriv = (__GLXMESAdrawable *) context->base.drawPriv;
     __GLXMESAdrawable *readPriv = (__GLXMESAdrawable *) context->base.readPriv;
 
     return XMesaMakeCurrent2(context->xmesa,
 			     drawPriv->xm_buf,
 			     readPriv->xm_buf);
 }
 
+void
+__glXSetDrawBufferToNull( __GLXcontext *baseContext )
+{
+    __GLXMESAcontext *context = (__GLXMESAcontext *) baseContext;
+    XMesaSetDrawBufferToNull(context->xmesa);
+}
+
+void
+__glXSetReadBufferToNull( __GLXcontext *baseContext )
+{
+    __GLXMESAcontext *context = (__GLXMESAcontext *) baseContext;
+    XMesaSetReadBufferToNull(context->xmesa);
+}
+
 static int
 __glXMesaContextLoseCurrent(__GLXcontext *baseContext)
 {
     __GLXMESAcontext *context = (__GLXMESAcontext *) baseContext;
 
     return XMesaLoseCurrent(context->xmesa);
 }
 
 static int
 __glXMesaContextCopy(__GLXcontext *baseDst,

The following two diffs apply to Mesa:


--- src/mesa/drivers/x11/xm_api.c	2006/05/15 08:28:09
+++ src/mesa/drivers/x11/xm_api.c	2006/05/19 13:42:32
@@ -2092,20 +2092,33 @@
       /* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */
       drawBuffer->wasCurrent = GL_TRUE;
    }
    else {
       /* Detach */
       _mesa_make_current( NULL, NULL, NULL );
    }
    return GL_TRUE;
 }
 
+void XMesaSetDrawBufferToNull( XMesaContext c )
+{
+    if ( c ) {
+	c->mesa.DrawBuffer = NULL;
+    }
+}
+
+void XMesaSetReadBufferToNull( XMesaContext c )
+{
+    if ( c ) {
+	c->mesa.ReadBuffer = NULL;
+    }
+}
 
 /*
  * Unbind the context c from its buffer.
  */
 GLboolean XMesaUnbindContext( XMesaContext c )
 {
    /* A no-op for XFree86 integration purposes */
    return GL_TRUE;
 }
 

--- include/GL/xmesa.h	2006/05/15 08:15:39
+++ include/GL/xmesa.h	2006/05/19 13:42:31
@@ -219,20 +219,30 @@
 
 /*
  * Bind two buffers (read and draw) to a context and make the
  * context the current one.
  * New in Mesa 3.3
  */
 extern GLboolean XMesaMakeCurrent2( XMesaContext c,
                                     XMesaBuffer drawBuffer,
                                     XMesaBuffer readBuffer );
 
+/* 
+ * Set the draw buffer to NULL (because it was already deallocated)
+ */
+void XMesaSetDrawBufferToNull( XMesaContext c );
+
+/* 
+ * Set the read  buffer to NULL (because it was already deallocated)
+ */
+void XMesaSetReadBufferToNull( XMesaContext c );
+
 
 /*
  * Unbind the current context from its buffer.
  */
 extern GLboolean XMesaUnbindContext( XMesaContext c );
 
 
 /*
  * Return a handle to the current context.
  */


Tutorial | Features | Download | Get Free Trial | Buy | Support


DemoRecorder Box
Training of users is expensive ...
        if you do it manually
again and again.

You can save a whole lot of money ...
... if you do it once and record it
so your users can watch it again and again
--> without you lifting a finger
--> and without spending any more money.