Enable GLX_SGI_make_current_read for tdfx.
authorIan Romanick <idr@us.ibm.com>
Tue, 14 Nov 2006 00:10:34 +0000 (00:10 +0000)
committerIan Romanick <idr@us.ibm.com>
Tue, 14 Nov 2006 00:10:34 +0000 (00:10 +0000)
Implement GLX_SGI_make_current_read for tdfx.  Remove annoying debug
printf in tdfxSwapBuffers.  Updated a comment in drirenderbuffer.h to
note that the tdfx driver uses a flag that was previously only used by
s3v.

This code was tested with glxgears, wincopy, and manywin.

src/mesa/drivers/dri/common/drirenderbuffer.h
src/mesa/drivers/dri/tdfx/tdfx_context.c
src/mesa/drivers/dri/tdfx/tdfx_context.h
src/mesa/drivers/dri/tdfx/tdfx_lock.c
src/mesa/drivers/dri/tdfx/tdfx_pixels.c
src/mesa/drivers/dri/tdfx/tdfx_screen.c
src/mesa/drivers/dri/tdfx/tdfx_span.c

index cd73b78..747f92f 100644 (file)
@@ -52,8 +52,11 @@ typedef struct {
     */
    GLboolean depthHasSurface;
 
-   /* XXX this is for s3v only.  A handy flag to know if this is the back
-    * color buffer.
+   /**
+    * A handy flag to know if this is the back color buffer.
+    * 
+    * \note
+    * This is currently only used by s3v and tdfx.
     */
    GLboolean backBuffer;
 } driRenderbuffer;
index e9c07bd..bd9dade 100644 (file)
@@ -657,8 +657,10 @@ tdfxMakeCurrent( __DRIcontextPrivate *driContextPriv,
       GLcontext *newCtx = newFx->glCtx;
       GET_CURRENT_CONTEXT(curCtx);
 
-      if ( newFx->driDrawable != driDrawPriv ) {
+      if ((newFx->driDrawable != driDrawPriv)
+         || (newFx->driReadable != driReadPriv)) {
         newFx->driDrawable = driDrawPriv;
+        newFx->driReadable = driReadPriv;
         newFx->dirty = ~0;
       }
       else {
@@ -676,6 +678,11 @@ tdfxMakeCurrent( __DRIcontextPrivate *driContextPriv,
         newFx->dirty = ~0;
       }
 
+      driUpdateFramebufferSize(newCtx, driDrawPriv);
+      if (driDrawPriv != driReadPriv) {
+        driUpdateFramebufferSize(newCtx, driReadPriv);
+      }
+
       if ( !newFx->Glide.Initialized ) {
         if ( !tdfxInitContext( driDrawPriv, newFx ) )
            return GL_FALSE;
@@ -700,7 +707,6 @@ tdfxMakeCurrent( __DRIcontextPrivate *driContextPriv,
         UNLOCK_HARDWARE( newFx );
       }
 
-       driUpdateFramebufferSize(newCtx, driDrawPriv);
       _mesa_make_current( newCtx,
                           (GLframebuffer *) driDrawPriv->driverPrivate,
                           (GLframebuffer *) driReadPriv->driverPrivate );
index b8349fe..89a7a9d 100644 (file)
@@ -895,7 +895,17 @@ struct tdfx_context {
    /* stuff added for DRI */
    __DRIscreenPrivate *driScreen;
    __DRIcontextPrivate *driContext;
-   __DRIdrawablePrivate *driDrawable;
+
+   /**
+    * DRI drawable bound to this context for drawing.
+    */
+   __DRIdrawablePrivate        *driDrawable;
+
+   /**
+    * DRI drawable bound to this context for reading.
+    */
+   __DRIdrawablePrivate        *driReadable;
+
    drm_context_t hHWContext;
    drm_hw_lock_t *driHwLock;
    int driFd;
index ae3ba1a..a20c91d 100644 (file)
 void tdfxGetLock( tdfxContextPtr fxMesa )
 {
     __DRIcontextPrivate *cPriv = fxMesa->driContext;
-    __DRIdrawablePrivate *dPriv = cPriv->driDrawablePriv;
-    __DRIscreenPrivate *sPriv = dPriv->driScreenPriv;
+    __DRIdrawablePrivate *const drawable = cPriv->driDrawablePriv;
+    __DRIdrawablePrivate *const readable = cPriv->driReadablePriv;
+    __DRIscreenPrivate *sPriv = drawable->driScreenPriv;
     TDFXSAREAPriv *saPriv = (TDFXSAREAPriv *) (((char *) sPriv->pSAREA) +
                                        fxMesa->fxScreen->sarea_priv_offset);
-    unsigned int stamp = dPriv->lastStamp;
+    unsigned int stamp = drawable->lastStamp;
 
     drmGetLock( fxMesa->driFd, fxMesa->hHWContext, 0 );
 
-    /* This macro will update dPriv's cliprects if needed */
-    DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv );
+    /* This macro will update drawable's cliprects if needed */
+    DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable);
+    if (drawable != readable) {
+       DRI_VALIDATE_DRAWABLE_INFO(sPriv, readable);
+    }
 
     if ( saPriv->fifoOwner != fxMesa->hHWContext ) {
         fxMesa->Glide.grDRIImportFifo( saPriv->fifoPtr, saPriv->fifoRead );
@@ -83,10 +87,15 @@ void tdfxGetLock( tdfxContextPtr fxMesa )
     }
 #endif
 
-    if ( *dPriv->pStamp != stamp || saPriv->ctxOwner != fxMesa->hHWContext ) {
+    if ((*drawable->pStamp != stamp)
+       || (saPriv->ctxOwner != fxMesa->hHWContext)) {
+       driUpdateFramebufferSize(fxMesa->glCtx, drawable);
+       if (drawable != readable) {
+          driUpdateFramebufferSize(fxMesa->glCtx, readable);
+       }
+
        tdfxUpdateClipping(fxMesa->glCtx);
        tdfxUploadClipping(fxMesa);
-       driUpdateFramebufferSize(fxMesa->glCtx, dPriv);
     }
 
     DEBUG_LOCK();
index 1a5a2b1..732270b 100644 (file)
@@ -496,9 +496,9 @@ tdfx_readpixels_R5G6B5(GLcontext * ctx, GLint x, GLint y,
    {
       tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
       GrLfbInfo_t info;
-
-      const GLint winX = fxMesa->x_offset;
-      const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
+      __DRIdrawablePrivate *const readable = fxMesa->driReadable;
+      const GLint winX = readable->x;
+      const GLint winY = readable->y + readable->h - 1;
       const GLint scrX = winX + x;
       const GLint scrY = winY - y;
 
@@ -554,9 +554,9 @@ tdfx_readpixels_R8G8B8A8(GLcontext * ctx, GLint x, GLint y,
    {
       tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
       GrLfbInfo_t info;
-
-      const GLint winX = fxMesa->x_offset;
-      const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
+      __DRIdrawablePrivate *const readable = fxMesa->driReadable;
+      const GLint winX = readable->x;
+      const GLint winY = readable->y + readable->h - 1;
       const GLint scrX = winX + x;
       const GLint scrY = winY - y;
 
index 5e3d07f..646f512 100644 (file)
@@ -73,6 +73,9 @@ tdfxCreateScreen( __DRIscreenPrivate *sPriv )
 {
    tdfxScreenPrivate *fxScreen;
    TDFXDRIPtr fxDRIPriv = (TDFXDRIPtr) sPriv->pDevPriv;
+   PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
+     (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension"));
+   void *const psc = sPriv->psc->screenConfigs;
 
    if (sPriv->devPrivSize != sizeof(TDFXDRIRec)) {
       fprintf(stderr,"\nERROR!  sizeof(TDFXDRIRec) does not match passed size from device driver\n");
@@ -113,6 +116,10 @@ tdfxCreateScreen( __DRIscreenPrivate *sPriv )
       return GL_FALSE;
    }
 
+   if (glx_enable_extension != NULL) {
+      (*glx_enable_extension)(psc, "GLX_SGI_make_current_read");
+   }
+
    return GL_TRUE;
 }
 
@@ -180,6 +187,7 @@ tdfxCreateBuffer( __DRIscreenPrivate *driScrnPriv,
                                  driDrawPriv);
          tdfxSetSpanFunctions(backRb, mesaVis);
          _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
+        backRb->backBuffer = GL_TRUE;
       }
 
       if (mesaVis->depthBits == 16) {
@@ -265,7 +273,9 @@ tdfxSwapBuffers( __DRIdrawablePrivate *driDrawPriv )
             return;
         LOCK_HARDWARE( fxMesa );
         fxMesa->Glide.grSstSelect( fxMesa->Glide.Board );
+#ifdef DEBUG
          printf("SwapBuf SetState 1\n");
+#endif
         fxMesa->Glide.grGlideSetState(fxMesa->Glide.State );
       }
    }
@@ -325,7 +335,9 @@ tdfxSwapBuffers( __DRIdrawablePrivate *driDrawPriv )
       if (ctx->DriverCtx != fxMesa) {
          fxMesa = TDFX_CONTEXT(ctx);
         fxMesa->Glide.grSstSelect( fxMesa->Glide.Board );
+#ifdef DEBUG
          printf("SwapBuf SetState 2\n");
+#endif
         fxMesa->Glide.grGlideSetState(fxMesa->Glide.State );
       }
       UNLOCK_HARDWARE( fxMesa );
index ee5eb45..d9d52d2 100644 (file)
 
 
 #define LOCAL_VARS                                                     \
-   __DRIdrawablePrivate *dPriv = fxMesa->driDrawable;                  \
-   tdfxScreenPrivate *fxPriv = fxMesa->fxScreen;                       \
-   GLboolean isFront = (ctx->DrawBuffer->_ColorDrawBufferMask[0]       \
-                      == BUFFER_BIT_FRONT_LEFT);                       \
-   GLuint pitch = isFront ? (fxMesa->screen_width * BYTESPERPIXEL)     \
-                          : info.strideInBytes;                                \
-   GLuint height = fxMesa->height;                                     \
+   driRenderbuffer *drb = (driRenderbuffer *) rb;                      \
+   __DRIdrawablePrivate *const dPriv = drb->dPriv;                     \
+   GLuint pitch = drb->backBuffer ? info.strideInBytes                 \
+     : (drb->pitch * drb->cpp);                                                \
+   const GLuint bottom = dPriv->h - 1;                                 \
    char *buf = (char *)((char *)info.lfbPtr +                          \
-                        dPriv->x * fxPriv->cpp +                       \
-                        dPriv->y * pitch);                             \
+                        (dPriv->x * drb->cpp) +                        \
+                        (dPriv->y * pitch));                           \
    GLuint p;                                                           \
    (void) buf; (void) p;
 
 
-#define Y_FLIP(_y)             (height - _y - 1)
+#define Y_FLIP(_y)             (bottom - _y)
 
 
 #define HW_WRITE_LOCK()                                                        \
    UNLOCK_HARDWARE( fxMesa );                                          \
    LOCK_HARDWARE( fxMesa );                                            \
    info.size = sizeof(GrLfbInfo_t);                                    \
-   if ( fxMesa->Glide.grLfbLock( GR_LFB_WRITE_ONLY,                    \
-                   fxMesa->DrawBuffer, LFB_MODE,                       \
-                  GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) )             \
-   {
+   if (fxMesa->Glide.grLfbLock(GR_LFB_WRITE_ONLY, fxMesa->DrawBuffer,  \
+                              LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, \
+                              &info)) {
 
 #define HW_WRITE_UNLOCK()                                              \
       fxMesa->Glide.grLfbUnlock( GR_LFB_WRITE_ONLY, fxMesa->DrawBuffer );\