Here is a patch that enables SGI_make_current_read for the MGA driver. I have only tested this with progs/xdemos/wincopy, and it works as expected. It should be fairly trivial for people to make similar patches for the other drivers. Drivers that support pageflipping will be a bit more tricky, but that shouldn't be a significant problem.

Assuming everyone likes this patch, I'll commit it tomorrow.

HOWEVER, the wincopy demo runs about as fast with this patch as with indirect, software rasterization. The software path for glCopyPixels is *death*. Could people who are working on drivers *please* implement screen-to-screen blits for at least the common, easy cases of glCopyPixels? I understand that glCopyPixels isn't a common performance critical path, but the a lot of the code used to accelerate that should be re-usable for accelerating glCopyTexImage and some other pbuffer related functionality when the time comes.

Index: lib/GL/mesa/src/drv/mga/mga_xmesa.c
===================================================================
RCS file: /cvs/dri/xc/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v
retrieving revision 1.62
diff -u -d -r1.62 mga_xmesa.c
--- lib/GL/mesa/src/drv/mga/mga_xmesa.c 25 Oct 2003 16:11:46 -0000      1.62
+++ lib/GL/mesa/src/drv/mga/mga_xmesa.c 29 Oct 2003 18:40:09 -0000
@@ -129,6 +129,7 @@
            (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
         }
 
+        (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" );
         (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
       }
    }
@@ -377,7 +378,6 @@
    mmesa->mgaScreen = mgaScreen;
    mmesa->driScreen = sPriv;
    mmesa->sarea = (void *)saPriv;
-   mmesa->glBuffer = NULL;
 
    /* Parse configuration files */
    driParseConfigFiles (&mmesa->optionCache, &mgaScreen->optionCache,
@@ -655,6 +655,8 @@
         mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK); 
       }
 
+      mmesa->driReadable = driReadPriv;
+
       _mesa_make_current2(mmesa->glCtx,
                           (GLframebuffer *) driDrawPriv->driverPrivate,
                           (GLframebuffer *) driReadPriv->driverPrivate);
Index: lib/GL/mesa/src/drv/mga/mgacontext.h
===================================================================
RCS file: /cvs/dri/xc/xc/lib/GL/mesa/src/drv/mga/mgacontext.h,v
retrieving revision 1.30
diff -u -d -r1.30 mgacontext.h
--- lib/GL/mesa/src/drv/mga/mgacontext.h        25 Oct 2003 16:11:46 -0000      1.30
+++ lib/GL/mesa/src/drv/mga/mgacontext.h        29 Oct 2003 18:40:09 -0000
@@ -298,11 +298,19 @@
 
    /* Mirrors of some DRI state.
     */
-   GLframebuffer *glBuffer;
    drmContext hHWContext;
    drmLock *driHwLock;
    int driFd;
    __DRIdrawablePrivate *driDrawable;
+   __DRIdrawablePrivate *driReadable;
+
+   /**
+    * Drawable used by Mesa for software fallbacks for reading and
+    * writing.  It is set by Mesa's \c SetBuffer callback, and will always be
+    * either \c mga_context_t::driDrawable or \c mga_context_t::driReadable.
+    */
+   __DRIdrawablePrivate *mesa_drawable;
+
    __DRIscreenPrivate *driScreen;
    struct mga_screen_private_s *mgaScreen;
    MGASAREAPrivPtr sarea;
Index: lib/GL/mesa/src/drv/mga/mgaspan.c
===================================================================
RCS file: /cvs/dri/xc/xc/lib/GL/mesa/src/drv/mga/mgaspan.c,v
retrieving revision 1.31
diff -u -d -r1.31 mgaspan.c
--- lib/GL/mesa/src/drv/mga/mgaspan.c   30 Apr 2003 01:50:42 -0000      1.31
+++ lib/GL/mesa/src/drv/mga/mgaspan.c   29 Oct 2003 18:40:09 -0000
@@ -37,7 +37,7 @@
 
 
 #define LOCAL_VARS                                     \
-   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;   \
+   __DRIdrawablePrivate *dPriv = mmesa->mesa_drawable; \
    mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;     \
    __DRIscreenPrivate *sPriv = mmesa->driScreen;       \
    GLuint pitch = mgaScreen->frontPitch;               \
@@ -56,7 +56,7 @@
 
 
 #define LOCAL_DEPTH_VARS                                               \
-   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;                   \
+   __DRIdrawablePrivate *dPriv = mmesa->mesa_drawable;                 \
    mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;                     \
    __DRIscreenPrivate *sPriv = mmesa->driScreen;                       \
    GLuint pitch = mgaScreen->frontPitch;                               \
@@ -242,20 +242,22 @@
                            GLuint bufferBit)
 {
    mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+   unsigned int   offset;
 
-   if (bufferBit == FRONT_LEFT_BIT) 
-   {
-      mmesa->drawOffset = mmesa->mgaScreen->frontOffset;
-      mmesa->readOffset = mmesa->mgaScreen->frontOffset;
-   } 
-   else if (bufferBit == BACK_LEFT_BIT)
-   {
-      mmesa->drawOffset = mmesa->mgaScreen->backOffset;
-      mmesa->readOffset = mmesa->mgaScreen->backOffset;
-   }
-   else {
-      assert(0);
-   }
+   assert( (bufferBit == FRONT_LEFT_BIT) || (bufferBit == BACK_LEFT_BIT) );
+
+   offset = (bufferBit == FRONT_LEFT_BIT)
+       ? mmesa->mgaScreen->frontOffset
+       : mmesa->mgaScreen->backOffset;
+
+   mmesa->drawOffset = offset;
+   mmesa->readOffset = offset;
+
+   assert( (buffer == mmesa->driDrawable->driverPrivate)
+          || (buffer == mmesa->driReadable->driverPrivate) );
+
+   mmesa->mesa_drawable = (buffer == mmesa->driDrawable->driverPrivate)
+       ? mmesa->driDrawable : mmesa->driReadable;
 }
 
 void mgaDDInitSpanFuncs( GLcontext *ctx )

Reply via email to