Reorganized combiners. Added optimized span functions.
authorDaniel Borca <dborca@users.sourceforge.net>
Thu, 9 Oct 2003 15:12:20 +0000 (15:12 +0000)
committerDaniel Borca <dborca@users.sourceforge.net>
Thu, 9 Oct 2003 15:12:20 +0000 (15:12 +0000)
12 files changed:
src/mesa/drivers/glide/fx.rc [new file with mode: 0644]
src/mesa/drivers/glide/fxapi.c
src/mesa/drivers/glide/fxdd.c
src/mesa/drivers/glide/fxddspan.c
src/mesa/drivers/glide/fxddtex.c
src/mesa/drivers/glide/fxdrv.h
src/mesa/drivers/glide/fxglidew.h
src/mesa/drivers/glide/fxsetup.c
src/mesa/drivers/glide/fxtexman.c
src/mesa/drivers/glide/fxtris.c
src/mesa/drivers/glide/fxvb.c
src/mesa/drivers/glide/fxvbtmp.h

diff --git a/src/mesa/drivers/glide/fx.rc b/src/mesa/drivers/glide/fx.rc
new file mode 100644 (file)
index 0000000..c90e8c5
--- /dev/null
@@ -0,0 +1,39 @@
+#include <windows.h>
+
+#define PRODNAME                "Mesa 5.1"
+#define CONTACTSTR              "http://www.mesa3d.org"
+#define HWSTR                   "3dfx Voodoo Banshee, Velocity 100/200, Voodoo3, Voodoo4, Voodoo5"
+#define COPYRIGHTSTR            "Copyright \251 Brian E. Paul"
+
+#define VERSIONSTR              "5.1.0.1"
+#define MANVERSION              5
+#define MANREVISION             1
+#define BUILD_NUMBER            1
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION MANVERSION, MANREVISION, 0, BUILD_NUMBER
+ PRODUCTVERSION MANVERSION, MANREVISION, 0, BUILD_NUMBER
+ FILEFLAGSMASK 0x0030003FL
+
+ FILEOS VOS_DOS_WINDOWS32
+ FILETYPE VFT_DRV
+ FILESUBTYPE VFT2_DRV_INSTALLABLE
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904E4"
+        BEGIN
+            VALUE "FileDescription", PRODNAME
+            VALUE "FileVersion", VERSIONSTR
+            VALUE "LegalCopyright", COPYRIGHTSTR
+            VALUE "ProductName", PRODNAME
+            VALUE "Graphics Subsystem", HWSTR
+            VALUE "Contact", CONTACTSTR
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        /* the following line should be extended for localized versions */
+        VALUE "Translation", 0x409, 1252
+    END
+END
index 89b4a38a620a884e7c1f249f5687601e6e523a3e..28b9059c1957ef628e7b3ea7f568aa01b3a6f900 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fxapi.c,v 1.38 2003/10/02 17:36:44 brianp Exp $ */
+/* $Id: fxapi.c,v 1.39 2003/10/09 15:12:21 dborca Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -520,17 +520,20 @@ fxMesaCreateContext(GLuint win,
 
    fxInitPixelTables(fxMesa, useBGR);
 
-   fxMesa->width = FX_grSstScreenWidth();
-   fxMesa->height = FX_grSstScreenHeight();
+   /* screen */
+   fxMesa->screen_width = FX_grSstScreenWidth();
+   fxMesa->screen_height = FX_grSstScreenHeight();
 
+   /* window inside screen */
+   fxMesa->width = fxMesa->screen_width;
+   fxMesa->height = fxMesa->screen_height;
+
+   /* scissor inside window */
    fxMesa->clipMinX = 0;
    fxMesa->clipMaxX = fxMesa->width;
    fxMesa->clipMinY = 0;
    fxMesa->clipMaxY = fxMesa->height;
 
-   fxMesa->screen_width = fxMesa->width;
-   fxMesa->screen_height = fxMesa->height;
-
    if (verbose) {
       char buf[80];
 
index 09844a6e2a895126d30274f2d7e183e37efe51b6..a8109273db7c7f61a3bc0d565f5d9d568279c841 100644 (file)
@@ -2,7 +2,7 @@
  * fxDDReadPixels888 does not convert 8A8R8G8B into 5R5G5B
  */
 
-/* $Id: fxdd.c,v 1.100 2003/10/02 17:36:44 brianp Exp $ */
+/* $Id: fxdd.c,v 1.101 2003/10/09 15:12:21 dborca Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -130,6 +130,21 @@ fxInitPixelTables(fxMesaContext fxMesa, GLboolean bgrOrder)
 }
 
 
+/*
+ * Disable color by masking out R, G, B, A
+ */
+static void fxDisableColor (fxMesaContext fxMesa)
+{
+ if (fxMesa->colDepth != 16) {
+    /* 32bpp mode or 15bpp mode */
+    fxMesa->Glide.grColorMaskExt(FXFALSE, FXFALSE, FXFALSE, FXFALSE);
+ } else {
+    /* 16 bpp mode */
+    grColorMask(FXFALSE, FXFALSE);
+ }
+}
+
+
 /**********************************************************************/
 /*****                 Miscellaneous functions                    *****/
 /**********************************************************************/
@@ -190,25 +205,31 @@ static void fxDDClear( GLcontext *ctx,
               __FUNCTION__, (int) x, (int) y, (int) width, (int) height );
    }
 
-/*jejeje*/
    /* Need this check to respond to glScissor and clipping updates */
+   /* should also take care of FX_NEW_COLOR_MASK, FX_NEW_STENCIL, depth? */
    if (fxMesa->new_state & FX_NEW_SCISSOR) {
-      extern void fxSetupScissor(GLcontext * ctx);
       fxSetupScissor(ctx);
+      fxMesa->new_state &= ~FX_NEW_SCISSOR;
    }
 
    /* we can't clear accum buffers */
    mask &= ~(DD_ACCUM_BIT);
 
+   /*
+    * As per GL spec, stencil masking should be obeyed when clearing
+    */
    if (mask & DD_STENCIL_BIT) {
       if (!fxMesa->haveHwStencil || fxMesa->unitsState.stencilWriteMask != 0xff) {
          /* Napalm seems to have trouble with stencil write masks != 0xff */
          /* do stencil clear in software */
-         mask &= ~(DD_STENCIL_BIT);
          softwareMask |= DD_STENCIL_BIT;
+         mask &= ~(DD_STENCIL_BIT);
       }
    }
 
+   /*
+    * As per GL spec, color masking should be obeyed when clearing
+    */
    if (ctx->Visual.greenBits != 8 && ctx->Visual.greenBits != 5) {
       /* can only do color masking if running in 24/32bpp on Napalm */
       if (ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP] ||
@@ -252,7 +273,7 @@ static void fxDDClear( GLcontext *ctx,
       switch (mask & ~DD_STENCIL_BIT) {
       case DD_BACK_LEFT_BIT | DD_DEPTH_BIT:
         /* back buffer & depth */
-        fxColorMask(fxMesa, GL_TRUE); /* work around Voodoo3 bug */
+        /* FX_grColorMaskv_NoLock(ctx, true4); */ /* work around Voodoo3 bug */
         grDepthMask(FXTRUE);
         grRenderBuffer(GR_BUFFER_BACKBUFFER);
         if (stencil_size > 0) {
@@ -264,7 +285,7 @@ static void fxDDClear( GLcontext *ctx,
             grBufferClear(fxMesa->clearC,
                           fxMesa->clearA,
                           clearD);
-        if (!ctx->Depth.Mask || !ctx->Depth.Test) {
+        if (!fxMesa->unitsState.depthTestEnabled) {
             grDepthMask(FXFALSE);
         }
         break;
@@ -276,7 +297,7 @@ static void fxDDClear( GLcontext *ctx,
         /* clear depth */
         grDepthMask(FXTRUE);
         grRenderBuffer(GR_BUFFER_BACKBUFFER);
-        fxColorMask(fxMesa, GL_FALSE);
+         fxDisableColor(fxMesa);
         if (stencil_size > 0)
             fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
                                            fxMesa->clearA,
@@ -286,7 +307,7 @@ static void fxDDClear( GLcontext *ctx,
                           fxMesa->clearA,
                           clearD);
         /* clear front */
-        fxColorMask(fxMesa, GL_TRUE);
+        fxSetupColorMask(ctx);
         grRenderBuffer(GR_BUFFER_FRONTBUFFER);
         if (stencil_size > 0)
             fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
@@ -296,7 +317,7 @@ static void fxDDClear( GLcontext *ctx,
             grBufferClear(fxMesa->clearC,
                           fxMesa->clearA,
                           clearD);
-        if (!ctx->Depth.Mask || !ctx->Depth.Test) {
+        if (!fxMesa->unitsState.depthTestEnabled) {
             grDepthMask(FXFALSE);
         }
         break;
@@ -312,7 +333,7 @@ static void fxDDClear( GLcontext *ctx,
             grBufferClear(fxMesa->clearC,
                           fxMesa->clearA,
                           clearD);
-        if (ctx->Depth.Mask && ctx->Depth.Test) {
+        if (fxMesa->unitsState.depthTestEnabled) {
             grDepthMask(FXTRUE);
         }
         break;
@@ -328,7 +349,7 @@ static void fxDDClear( GLcontext *ctx,
             grBufferClear(fxMesa->clearC,
                           fxMesa->clearA,
                           clearD);
-        if (ctx->Depth.Mask && ctx->Depth.Test) {
+        if (fxMesa->unitsState.depthTestEnabled) {
             grDepthMask(FXTRUE);
         }
         break;
@@ -353,7 +374,7 @@ static void fxDDClear( GLcontext *ctx,
             grBufferClear(fxMesa->clearC,
                           fxMesa->clearA,
                           clearD);
-        if (ctx->Depth.Mask && ctx->Depth.Test) {
+        if (fxMesa->unitsState.depthTestEnabled) {
             grDepthMask(FXTRUE);
         }
         break;
@@ -380,14 +401,14 @@ static void fxDDClear( GLcontext *ctx,
             grBufferClear(fxMesa->clearC,
                           fxMesa->clearA,
                           clearD);
-        if (!ctx->Depth.Mask || !ctx->Depth.Mask) {
+        if (!fxMesa->unitsState.depthTestEnabled) {
             grDepthMask(FXFALSE);
         }
         break;
       case DD_DEPTH_BIT:
         /* just the depth buffer */
         grRenderBuffer(GR_BUFFER_BACKBUFFER);
-        fxColorMask(fxMesa, GL_FALSE);
+         fxDisableColor(fxMesa);
         grDepthMask(FXTRUE);
         if (stencil_size > 0)
             fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
@@ -397,11 +418,13 @@ static void fxDDClear( GLcontext *ctx,
             grBufferClear(fxMesa->clearC,
                           fxMesa->clearA,
                           clearD);
-        fxColorMask(fxMesa, GL_TRUE);
-        if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT)
+        fxSetupColorMask(ctx);
+        if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT) {
             grRenderBuffer(GR_BUFFER_FRONTBUFFER);
-        if (!ctx->Depth.Test || !ctx->Depth.Mask)
+         }
+        if (!fxMesa->unitsState.depthTestEnabled) {
            grDepthMask(FXFALSE);
+         }
         break;
       default:
          /* clear no color buffers or depth buffer but might clear stencil */
@@ -409,16 +432,17 @@ static void fxDDClear( GLcontext *ctx,
             /* XXX need this RenderBuffer call to work around Glide bug */
             grRenderBuffer(GR_BUFFER_BACKBUFFER);
             grDepthMask(FXFALSE);
-            fxColorMask(fxMesa, GL_FALSE);
+            fxDisableColor(fxMesa);
             fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
                                            fxMesa->clearA,
                                            clearD, clearS);
-            if (ctx->Depth.Mask && ctx->Depth.Test) {
+            if (fxMesa->unitsState.depthTestEnabled) {
                grDepthMask(FXTRUE);
             }
-            fxColorMask(fxMesa, GL_TRUE);
-            if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT)
+            fxSetupColorMask(ctx);
+            if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT) {
                grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+            }
          }
       }
    }
@@ -456,7 +480,7 @@ fxDDSetDrawBuffer(GLcontext * ctx, GLenum mode)
       grRenderBuffer(fxMesa->currentFB);
    }
    else if (mode == GL_NONE) {
-      fxColorMask(fxMesa, GL_FALSE);
+      fxDisableColor(fxMesa);
    }
    else {
       /* we'll need a software fallback */
@@ -1015,16 +1039,17 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
 
    fxMesa->unitsState.stencilWriteMask = 0xff;
 
-   fxColorMask(fxMesa, GL_TRUE);
-   if (fxMesa->haveDoubleBuffer) {
-      fxMesa->currentFB = GR_BUFFER_BACKBUFFER;
-      grRenderBuffer(GR_BUFFER_BACKBUFFER);
-   }
-   else {
-      fxMesa->currentFB = GR_BUFFER_FRONTBUFFER;
-      grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+   if (fxMesa->colDepth != 16) {
+      /* 32bpp mode or 15bpp mode */
+      fxMesa->Glide.grColorMaskExt(FXTRUE, FXTRUE, FXTRUE, fxMesa->haveHwAlpha);
+   } else {
+      /* 16 bpp mode */
+      grColorMask(FXTRUE, fxMesa->haveHwAlpha);
    }
 
+   fxMesa->currentFB = fxMesa->haveDoubleBuffer ? GR_BUFFER_BACKBUFFER : GR_BUFFER_FRONTBUFFER;
+   grRenderBuffer(fxMesa->currentFB);
+
    fxMesa->state = MALLOC(FX_grGetInteger(GR_GLIDE_STATE_SIZE));
    fxMesa->fogTable = (GrFog_t *) MALLOC(FX_grGetInteger(GR_FOG_TABLE_ENTRIES) *
                             sizeof(GrFog_t));
@@ -1212,6 +1237,7 @@ fx_check_IsInHardware(GLcontext * ctx)
         return FX_FALLBACK_TEXTURE_1D_3D;
 
       if (ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_2D_BIT) {
+#if 0
         if (ctx->Texture.Unit[0].EnvMode == GL_BLEND &&
             (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_2D_BIT ||
              ctx->Texture.Unit[0].EnvColor[0] != 0 ||
@@ -1220,13 +1246,16 @@ fx_check_IsInHardware(GLcontext * ctx)
              ctx->Texture.Unit[0].EnvColor[3] != 1)) {
            return FX_FALLBACK_TEXTURE_ENV;
         }
+#endif
         if (ctx->Texture.Unit[0]._Current->Image[0]->Border > 0)
            return FX_FALLBACK_TEXTURE_BORDER;
       }
 
       if (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_2D_BIT) {
+#if 0
         if (ctx->Texture.Unit[1].EnvMode == GL_BLEND)
            return FX_FALLBACK_TEXTURE_ENV;
+#endif
         if (ctx->Texture.Unit[1]._Current->Image[0]->Border > 0)
            return FX_FALLBACK_TEXTURE_BORDER;
       }
@@ -1264,10 +1293,12 @@ fx_check_IsInHardware(GLcontext * ctx)
         return FX_FALLBACK_TEXTURE_MULTI;
       }
 
+#if 0
       if ((ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_2D_BIT) &&
          (ctx->Texture.Unit[0].EnvMode == GL_BLEND)) {
         return FX_FALLBACK_TEXTURE_ENV;
       }
+#endif
    }
 
    return 0;
index 460126e86b1879eb983c2458bcc4613d9215743e..c7d5021923ac8644ef1d821f6c3d8b382e4e4b10 100644 (file)
@@ -1,11 +1,4 @@
-/* Hack alert:
- * The performance hit is disastruous for SPAN functions.
- * Should we use SpanRenderStart / SpanRenderFinish in `swrast.h'
- * for locking / unlocking the LFB?
- * Optimize and check endianess for `read_R8G8B8_pixels'
- */
-
-/* $Id: fxddspan.c,v 1.25 2003/10/02 17:36:44 brianp Exp $ */
+/* $Id: fxddspan.c,v 1.26 2003/10/09 15:12:21 dborca Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #include "fxglidew.h"
 #include "swrast/swrast.h"
 
-#ifdef _MSC_VER
-#ifdef _WIN32
-#pragma warning( disable : 4090 4022 )
-/* 4101 : "different 'const' qualifier"
- * 4022 : "pointer mistmatch for actual parameter 'n'
- */
-#endif
-#endif
-
-
 
 #define writeRegionClipped(fxm,dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data)             \
   FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data)
 /************************************************************************/
 /*****                    Span functions                            *****/
 /************************************************************************/
+#define TDFXPACKCOLOR1555( r, g, b, a )                                           \
+   ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) |     \
+    ((a) ? 0x8000 : 0))
+#define TDFXPACKCOLOR565( r, g, b )                                       \
+   ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
+#define TDFXPACKCOLOR8888( r, g, b, a )                                           \
+   (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
+/************************************************************************/
 
 
-static void
-fxDDWriteRGBASpan(const GLcontext * ctx,
-                 GLuint n, GLint x, GLint y,
-                 const GLubyte rgba[][4], const GLubyte mask[])
-{
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-   GLuint i;
-   GLint bottom = fxMesa->height - 1;
+#define DBG 0
+
+
+#define LOCAL_VARS                                                     \
+    GLuint pitch = info.strideInBytes;                                 \
+    GLuint height = fxMesa->height;                                    \
+    char *buf = (char *)((char *)info.lfbPtr + 0 /* x, y offset */);   \
+    GLuint p;                                                          \
+    (void) buf; (void) p;
+
+#define CLIPPIXEL( _x, _y )    ( _x >= minx && _x < maxx &&            \
+                                 _y >= miny && _y < maxy )
 
-   if (TDFX_DEBUG & VERBOSE_DRIVER) {
-      fprintf(stderr, "%s(...)\n", __FUNCTION__);
-   }
+#define CLIPSPAN( _x, _y, _n, _x1, _n1, _i )                           \
+    if ( _y < miny || _y >= maxy ) {                                   \
+       _n1 = 0, _x1 = x;                                               \
+    } else {                                                           \
+       _n1 = _n;                                                       \
+       _x1 = _x;                                                       \
+       if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx;\
+       if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx);               \
+    }
 
-   if (mask) {
-      int span = 0;
+#define Y_FLIP(_y)             (height - _y - 1)
 
-      for (i = 0; i < n; i++) {
-        if (mask[i]) {
-           ++span;
-        }
-        else {
-           if (span > 0) {
-              LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x + i - span,
-                                  bottom - y,
-                                  /* GR_LFB_SRC_FMT_8888, */ span, /*1, */ 0,
-                                  (void *) rgba[i - span]);
-              span = 0;
-           }
-        }
-      }
+#define HW_WRITE_LOCK()                                                        \
+    fxMesaContext fxMesa = FX_CONTEXT(ctx);                            \
+    GrLfbInfo_t info;                                                  \
+    info.size = sizeof(GrLfbInfo_t);                                   \
+    if ( grLfbLock( GR_LFB_WRITE_ONLY,                                 \
+                   fxMesa->currentFB, LFB_MODE,                                \
+                  GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) {
+
+#define HW_WRITE_UNLOCK()                                              \
+       grLfbUnlock( GR_LFB_WRITE_ONLY, fxMesa->currentFB );            \
+    }
 
-      if (span > 0)
-        LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x + n - span, bottom - y,
-                            /* GR_LFB_SRC_FMT_8888, */ span, /*1, */ 0,
-                            (void *) rgba[n - span]);
-   }
-   else
-      LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x, bottom - y,    /* GR_LFB_SRC_FMT_8888, */
-                         n, /* 1, */ 0, (void *) rgba);
-}
+#define HW_READ_LOCK()                                                 \
+    fxMesaContext fxMesa = FX_CONTEXT(ctx);                            \
+    GrLfbInfo_t info;                                                  \
+    info.size = sizeof(GrLfbInfo_t);                                   \
+    if ( grLfbLock( GR_LFB_READ_ONLY, fxMesa->currentFB,               \
+                    LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) {
 
+#define HW_READ_UNLOCK()                                               \
+       grLfbUnlock( GR_LFB_READ_ONLY, fxMesa->currentFB );             \
+    }
 
-static void
-fxDDWriteRGBSpan(const GLcontext * ctx,
-                GLuint n, GLint x, GLint y,
-                const GLubyte rgb[][3], const GLubyte mask[])
-{
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-   GLuint i;
-   GLint bottom = fxMesa->height - 1;
-   GLubyte rgba[MAX_WIDTH][4];
+#define HW_WRITE_CLIPLOOP()                                            \
+    do {                                                               \
+       int _nc = 1; /* numcliprects */                                 \
+       while (_nc--) {                                                 \
+           const int minx = fxMesa->clipMinX;                          \
+           const int miny = fxMesa->clipMinY;                          \
+           const int maxx = fxMesa->clipMaxX;                          \
+           const int maxy = fxMesa->clipMaxY;
 
-   if (TDFX_DEBUG & VERBOSE_DRIVER) {
-      fprintf(stderr, "%s(...)\n", __FUNCTION__);
-   }
+#define HW_READ_CLIPLOOP()                                             \
+    do {                                                               \
+       int _nc = 1; /* numcliprects */                                 \
+       while (_nc--) {                                                 \
+           const int minx = fxMesa->clipMinX;                          \
+           const int miny = fxMesa->clipMinY;                          \
+           const int maxx = fxMesa->clipMaxX;                          \
+           const int maxy = fxMesa->clipMaxY;
 
-   if (mask) {
-      int span = 0;
+#define HW_ENDCLIPLOOP()                                               \
+       }                                                               \
+    } while (0)
 
-      for (i = 0; i < n; i++) {
-        if (mask[i]) {
-           rgba[span][RCOMP] = rgb[i][0];
-           rgba[span][GCOMP] = rgb[i][1];
-           rgba[span][BCOMP] = rgb[i][2];
-           rgba[span][ACOMP] = 255;
-           ++span;
-        }
-        else {
-           if (span > 0) {
-              LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x + i - span,
-                                  bottom - y,
-                                  /*GR_LFB_SRC_FMT_8888, */ span, /* 1, */ 0,
-                                  (void *) rgba);
-              span = 0;
-           }
-        }
-      }
 
-      if (span > 0)
-        LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x + n - span, bottom - y,
-                            /*GR_LFB_SRC_FMT_8888, */ span, /* 1, */ 0,
-                            (void *) rgba);
-   }
-   else {
-      for (i = 0; i < n; i++) {
-        rgba[i][RCOMP] = rgb[i][0];
-        rgba[i][GCOMP] = rgb[i][1];
-        rgba[i][BCOMP] = rgb[i][2];
-        rgba[i][ACOMP] = 255;
-      }
+/* 16 bit, ARGB1555 color spanline and pixel functions */
 
-      LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x, bottom - y,    /* GR_LFB_SRC_FMT_8888, */
-                         n, /* 1, */ 0, (void *) rgba);
-   }
-}
+#undef LFB_MODE
+#define LFB_MODE       GR_LFBWRITEMODE_1555
 
+#undef BYTESPERPIXEL
+#define BYTESPERPIXEL 2
 
-static void
-fxDDWriteMonoRGBASpan(const GLcontext * ctx,
-                     GLuint n, GLint x, GLint y,
-                     const GLchan color[4], const GLubyte mask[])
-{
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-   GLuint i;
-   GLint bottom = fxMesa->height - 1;
-   GLuint data[MAX_WIDTH];
-   GrColor_t gColor = FXCOLOR4(color);
+#undef INIT_MONO_PIXEL
+#define INIT_MONO_PIXEL(p, color) \
+    p = TDFXPACKCOLOR1555( color[RCOMP], color[GCOMP], color[BCOMP], color[ACOMP] )
 
-   if (TDFX_DEBUG & VERBOSE_DRIVER) {
-      fprintf(stderr, "%s(...)\n", __FUNCTION__);
-   }
+#define WRITE_RGBA( _x, _y, r, g, b, a )                               \
+    *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) =                 \
+                                       TDFXPACKCOLOR1555( r, g, b, a )
 
-   if (mask) {
-      int span = 0;
+#define WRITE_PIXEL( _x, _y, p )                                       \
+    *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) = p
 
-      for (i = 0; i < n; i++) {
-        if (mask[i]) {
-           data[span] = (GLuint) gColor;
-           ++span;
-        }
-        else {
-           if (span > 0) {
-              writeRegionClipped(fxMesa, fxMesa->currentFB, x + i - span,
-                                 bottom - y, GR_LFB_SRC_FMT_8888, span, 1, 0,
-                                 (void *) data);
-              span = 0;
-           }
-        }
-      }
+#define READ_RGBA( rgba, _x, _y )                                      \
+    do {                                                               \
+       GLushort p = *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch);  \
+       rgba[0] = FX_rgb_scale_5[(p >> 10) & 0x1F];                     \
+       rgba[1] = FX_rgb_scale_5[(p >> 5)  & 0x1F];                     \
+       rgba[2] = FX_rgb_scale_5[ p        & 0x1F];                     \
+       rgba[3] = (p & 0x8000) ? 255 : 0;                               \
+    } while (0)
 
-      if (span > 0)
-        writeRegionClipped(fxMesa, fxMesa->currentFB, x + n - span,
-                           bottom - y, GR_LFB_SRC_FMT_8888, span, 1, 0,
-                           (void *) data);
-   }
-   else {
-      for (i = 0; i < n; i++) {
-        data[i] = (GLuint) gColor;
-      }
+#define TAG(x) tdfx##x##_ARGB1555
+#include "../dri/common/spantmp.h"
 
-      writeRegionClipped(fxMesa, fxMesa->currentFB, x, bottom - y,
-                        GR_LFB_SRC_FMT_8888, n, 1, 0, (void *) data);
-   }
-}
 
+/* 16 bit, RGB565 color spanline and pixel functions */
+
+#undef LFB_MODE
+#define LFB_MODE       GR_LFBWRITEMODE_565
+
+#undef BYTESPERPIXEL
+#define BYTESPERPIXEL 2
+
+#undef INIT_MONO_PIXEL
+#define INIT_MONO_PIXEL(p, color) \
+    p = TDFXPACKCOLOR565( color[RCOMP], color[GCOMP], color[BCOMP] )
+
+#define WRITE_RGBA( _x, _y, r, g, b, a )                               \
+    *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) =                 \
+                                       TDFXPACKCOLOR565( r, g, b )
+
+#define WRITE_PIXEL( _x, _y, p )                                       \
+    *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) = p
 
-#if 0
-static void
-fxDDReadRGBASpan(const GLcontext * ctx,
-                GLuint n, GLint x, GLint y, GLubyte rgba[][4])
-{
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-   GLushort data[MAX_WIDTH];
-   GLuint i;
-   GLint bottom = fxMesa->height - 1;
+#define READ_RGBA( rgba, _x, _y )                                      \
+    do {                                                               \
+       GLushort p = *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch);  \
+       rgba[0] = FX_rgb_scale_5[(p >> 11) & 0x1F];                     \
+       rgba[1] = FX_rgb_scale_6[(p >> 5)  & 0x3F];                     \
+       rgba[2] = FX_rgb_scale_5[ p        & 0x1F];                     \
+       rgba[3] = 0xff;                                                 \
+    } while (0)
 
-   if (TDFX_DEBUG & VERBOSE_DRIVER) {
-      fprintf(stderr, "%s(...)\n", __FUNCTION__);
-   }
+#define TAG(x) tdfx##x##_RGB565
+#include "../dri/common/spantmp.h"
 
-   assert(n < MAX_WIDTH);
 
-   FX_grLfbReadRegion(fxMesa->currentFB, x, bottom - y, n, 1, 0, data);
+/* 32 bit, ARGB8888 color spanline and pixel functions */
 
-   for (i = 0; i < n; i++) {
-      GLushort pixel = data[i];
-      rgba[i][RCOMP] = FX_PixelToR[pixel];
-      rgba[i][GCOMP] = FX_PixelToG[pixel];
-      rgba[i][BCOMP] = FX_PixelToB[pixel];
-      rgba[i][ACOMP] = 255;
-   }
-}
-#endif
+#undef LFB_MODE
+#define LFB_MODE       GR_LFBWRITEMODE_8888
 
+#undef BYTESPERPIXEL
+#define BYTESPERPIXEL 4
+
+#undef INIT_MONO_PIXEL
+#define INIT_MONO_PIXEL(p, color) \
+    p = TDFXPACKCOLOR8888( color[RCOMP], color[GCOMP], color[BCOMP], color[ACOMP] )
+
+#define WRITE_RGBA( _x, _y, r, g, b, a )                               \
+    *(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch) =                   \
+                                       TDFXPACKCOLOR8888( r, g, b, a )
+
+#define WRITE_PIXEL( _x, _y, p )                                       \
+    *(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch) = p
+
+#define READ_RGBA( rgba, _x, _y )                                      \
+    do {                                                               \
+       GLuint p = *(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch);      \
+        rgba[0] = (p >> 16) & 0xff;                                    \
+        rgba[1] = (p >>  8) & 0xff;                                    \
+        rgba[2] = (p >>  0) & 0xff;                                    \
+        rgba[3] = (p >> 24) & 0xff;                                    \
+    } while (0)
+
+#define TAG(x) tdfx##x##_ARGB8888
+#include "../dri/common/spantmp.h"
+
+
+/************************************************************************/
+/*****                    Span functions (optimized)                *****/
+/************************************************************************/
 
 /*
- * Read a span of 16-bit RGB pixels.  Note, we don't worry about cliprects
+ * Read a span of 15-bit RGB pixels.  Note, we don't worry about cliprects
  * since OpenGL says obscured pixels have undefined values.
  */
-static void
-read_R5G6B5_span(const GLcontext * ctx,
-                GLuint n, GLint x, GLint y, GLubyte rgba[][4])
+static void fxReadRGBASpan_ARGB1555 (const GLcontext * ctx,
+                                     GLuint n,
+                                     GLint x, GLint y,
+                                     GLubyte rgba[][4])
 {
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-   GrLfbInfo_t info;
-   BEGIN_BOARD_LOCK();
-   if (grLfbLock(GR_LFB_READ_ONLY,
-                fxMesa->currentFB,
-                GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
-      const GLint winX = 0;
-      const GLint winY = fxMesa->height - 1;
-      const GLint srcStride = info.strideInBytes / 2;  /* stride in GLushorts */
-      const GLushort *data16 = (const GLushort *) info.lfbPtr
-        + (winY - y) * srcStride + (winX + x);
-      const GLuint *data32 = (const GLuint *) data16;
-      GLuint i, j;
-      GLuint extraPixel = (n & 1);
-      n -= extraPixel;
-      for (i = j = 0; i < n; i += 2, j++) {
-        GLuint pixel = data32[j];
-        GLuint pixel0 = pixel & 0xffff;
-        GLuint pixel1 = pixel >> 16;
-        rgba[i][RCOMP] = FX_PixelToR[pixel0];
-        rgba[i][GCOMP] = FX_PixelToG[pixel0];
-        rgba[i][BCOMP] = FX_PixelToB[pixel0];
-        rgba[i][ACOMP] = 255;
-        rgba[i + 1][RCOMP] = FX_PixelToR[pixel1];
-        rgba[i + 1][GCOMP] = FX_PixelToG[pixel1];
-        rgba[i + 1][BCOMP] = FX_PixelToB[pixel1];
-        rgba[i + 1][ACOMP] = 255;
-      }
-      if (extraPixel) {
-        GLushort pixel = data16[n];
-        rgba[n][RCOMP] = FX_PixelToR[pixel];
-        rgba[n][GCOMP] = FX_PixelToG[pixel];
-        rgba[n][BCOMP] = FX_PixelToB[pixel];
-        rgba[n][ACOMP] = 255;
-      }
-
-      grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
-   }
-   END_BOARD_LOCK();
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GrLfbInfo_t info;
+ info.size = sizeof(GrLfbInfo_t);
+ if (grLfbLock(GR_LFB_READ_ONLY, fxMesa->currentFB,
+               GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
+    const GLint winX = 0;
+    const GLint winY = fxMesa->height - 1;
+    const GLushort *data16 = (const GLushort *)((const GLubyte *)info.lfbPtr +
+                                               (winY - y) * info.strideInBytes +
+                                                (winX + x) * 2);
+    const GLuint *data32 = (const GLuint *) data16;
+    GLuint i, j;
+    GLuint extraPixel = (n & 1);
+    n -= extraPixel;
+
+    for (i = j = 0; i < n; i += 2, j++) {
+       GLuint pixel = data32[j];
+       rgba[i][0] = FX_rgb_scale_5[(pixel >> 10) & 0x1F];
+       rgba[i][1] = FX_rgb_scale_5[(pixel >> 5)  & 0x1F];
+       rgba[i][2] = FX_rgb_scale_5[ pixel        & 0x1F];
+       rgba[i][3] = (pixel & 0x8000) ? 255 : 0;
+       rgba[i+1][0] = FX_rgb_scale_5[(pixel >> 26) & 0x1F];
+       rgba[i+1][1] = FX_rgb_scale_5[(pixel >> 21) & 0x1F];
+       rgba[i+1][2] = FX_rgb_scale_5[(pixel >> 16) & 0x1F];
+       rgba[i+1][3] = (pixel & 0x80000000) ? 255 : 0;
+    }
+    if (extraPixel) {
+       GLushort pixel = data16[n];
+       rgba[n][0] = FX_rgb_scale_5[(pixel >> 10) & 0x1F];
+       rgba[n][1] = FX_rgb_scale_5[(pixel >> 5)  & 0x1F];
+       rgba[n][2] = FX_rgb_scale_5[ pixel        & 0x1F];
+       rgba[n][3] = (pixel & 0x8000) ? 255 : 0;
+    }
+
+    grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
+ }
 }
 
 /*
- * Read a span of 15-bit RGB pixels.  Note, we don't worry about cliprects
+ * Read a span of 16-bit RGB pixels.  Note, we don't worry about cliprects
  * since OpenGL says obscured pixels have undefined values.
  */
-static void read_R5G5B5_span (const GLcontext * ctx,
-                              GLuint n,
-                              GLint x, GLint y,
-                              GLubyte rgba[][4])
+static void fxReadRGBASpan_RGB565 (const GLcontext * ctx,
+                                   GLuint n,
+                                   GLint x, GLint y,
+                                   GLubyte rgba[][4])
 {
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-   GrLfbInfo_t info;
-   BEGIN_BOARD_LOCK();
-   if (grLfbLock(GR_LFB_READ_ONLY,
-                fxMesa->currentFB,
-                GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
-      const GLint winX = 0;
-      const GLint winY = fxMesa->height - 1;
-      const GLint srcStride = info.strideInBytes / 2;  /* stride in GLushorts */
-      const GLushort *data16 = (const GLushort *) info.lfbPtr
-        + (winY - y) * srcStride + (winX + x);
-      const GLuint *data32 = (const GLuint *) data16;
-      GLuint i, j;
-      GLuint extraPixel = (n & 1);
-      n -= extraPixel;
-      for (i = j = 0; i < n; i += 2, j++) {
-        GLuint pixel = data32[j];
-        rgba[i][RCOMP] = FX_rgb_scale_5[ pixel        & 0x1f];
-        rgba[i][GCOMP] = FX_rgb_scale_5[(pixel >> 5)  & 0x1f];
-        rgba[i][BCOMP] = FX_rgb_scale_5[(pixel >> 10) & 0x1f];
-        rgba[i][ACOMP] = (pixel & 0x8000) ? 255 : 0;
-        rgba[i + 1][RCOMP] = FX_rgb_scale_5[(pixel >> 16) & 0x1f];
-        rgba[i + 1][GCOMP] = FX_rgb_scale_5[(pixel >> 21) & 0x1f];
-        rgba[i + 1][BCOMP] = FX_rgb_scale_5[(pixel >> 26) & 0x1f];
-        rgba[i + 1][ACOMP] = (pixel & 0x80000000) ? 255 : 0;
-      }
-      if (extraPixel) {
-        GLushort pixel = data16[n];
-        rgba[n][RCOMP] = FX_rgb_scale_5[ pixel        & 0x1f];
-        rgba[n][GCOMP] = FX_rgb_scale_5[(pixel >> 5)  & 0x1f];
-        rgba[n][BCOMP] = FX_rgb_scale_5[(pixel >> 10) & 0x1f];
-        rgba[n][ACOMP] = (pixel & 0x8000) ? 255 : 0;
-      }
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GrLfbInfo_t info;
+ info.size = sizeof(GrLfbInfo_t);
+ if (grLfbLock(GR_LFB_READ_ONLY, fxMesa->currentFB,
+               GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
+    const GLint winX = 0;
+    const GLint winY = fxMesa->height - 1;
+    const GLushort *data16 = (const GLushort *)((const GLubyte *)info.lfbPtr +
+                                               (winY - y) * info.strideInBytes +
+                                                (winX + x) * 2);
+    const GLuint *data32 = (const GLuint *) data16;
+    GLuint i, j;
+    GLuint extraPixel = (n & 1);
+    n -= extraPixel;
+
+    for (i = j = 0; i < n; i += 2, j++) {
+        GLuint pixel = data32[j];
+#if 0
+        GLuint pixel0 = pixel & 0xffff;
+        GLuint pixel1 = pixel >> 16;
+        rgba[i][RCOMP] = FX_PixelToR[pixel0];
+        rgba[i][GCOMP] = FX_PixelToG[pixel0];
+        rgba[i][BCOMP] = FX_PixelToB[pixel0];
+        rgba[i][ACOMP] = 255;
+        rgba[i + 1][RCOMP] = FX_PixelToR[pixel1];
+        rgba[i + 1][GCOMP] = FX_PixelToG[pixel1];
+        rgba[i + 1][BCOMP] = FX_PixelToB[pixel1];
+        rgba[i + 1][ACOMP] = 255;
+#else
+       rgba[i][0] = FX_rgb_scale_5[(pixel >> 11) & 0x1F];
+       rgba[i][1] = FX_rgb_scale_6[(pixel >> 5)  & 0x3F];
+       rgba[i][2] = FX_rgb_scale_5[ pixel        & 0x1F];
+       rgba[i][3] = 255;
+       rgba[i+1][0] = FX_rgb_scale_5[(pixel >> 27) & 0x1F];
+       rgba[i+1][1] = FX_rgb_scale_6[(pixel >> 21) & 0x3F];
+       rgba[i+1][2] = FX_rgb_scale_5[(pixel >> 16) & 0x1F];
+       rgba[i+1][3] = 255;
+#endif
+    }
+    if (extraPixel) {
+       GLushort pixel = data16[n];
+#if 0
+       rgba[n][RCOMP] = FX_PixelToR[pixel];
+       rgba[n][GCOMP] = FX_PixelToG[pixel];
+       rgba[n][BCOMP] = FX_PixelToB[pixel];
+       rgba[n][ACOMP] = 255;
+#else
+       rgba[n][0] = FX_rgb_scale_5[(pixel >> 11) & 0x1F];
+       rgba[n][1] = FX_rgb_scale_6[(pixel >> 5)  & 0x3F];
+       rgba[n][2] = FX_rgb_scale_5[ pixel        & 0x1F];
+       rgba[n][3] = 255;
+#endif
+    }
 
-      grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
-   }
-   END_BOARD_LOCK();
+    grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
+ }
 }
 
 /*
  * Read a span of 32-bit RGB pixels.  Note, we don't worry about cliprects
  * since OpenGL says obscured pixels have undefined values.
  */
-static void read_R8G8B8_span (const GLcontext * ctx,
-                              GLuint n,
-                              GLint x, GLint y,
-                              GLubyte rgba[][4])
-{
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-   BEGIN_BOARD_LOCK();
-   grLfbReadRegion(fxMesa->currentFB, x, fxMesa->height - 1 - y, n, 1, n * 4, rgba);
-   END_BOARD_LOCK();
-}
-
-
-/************************************************************************/
-/*****                    Pixel functions                           *****/
-/************************************************************************/
-
-static void
-fxDDWriteRGBAPixels(const GLcontext * ctx,
-                   GLuint n, const GLint x[], const GLint y[],
-                   CONST GLubyte rgba[][4], const GLubyte mask[])
-{
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-   GLuint i;
-   GLint bottom = fxMesa->height - 1;
-
-   if (TDFX_DEBUG & VERBOSE_DRIVER) {
-      fprintf(stderr, "%s(...)\n", __FUNCTION__);
-   }
-
-   for (i = 0; i < n; i++)
-      if (mask[i])
-        LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x[i], bottom - y[i],
-                            1, 1, (void *) rgba[i]);
-}
-
-static void
-fxDDWriteMonoRGBAPixels(const GLcontext * ctx,
-                       GLuint n, const GLint x[], const GLint y[],
-                       const GLchan color[4], const GLubyte mask[])
-{
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-   GLuint i;
-   GLint bottom = fxMesa->height - 1;
-   GrColor_t gColor = FXCOLOR4(color);
-
-   if (TDFX_DEBUG & VERBOSE_DRIVER) {
-      fprintf(stderr, "%s(...)\n", __FUNCTION__);
-   }
-
-   for (i = 0; i < n; i++)
-      if (mask[i])
-        writeRegionClipped(fxMesa, fxMesa->currentFB, x[i], bottom - y[i],
-                           GR_LFB_SRC_FMT_8888, 1, 1, 0, (void *) &gColor);
-}
-
-
-static void
-read_R5G6B5_pixels(const GLcontext * ctx,
-                  GLuint n, const GLint x[], const GLint y[],
-                  GLubyte rgba[][4], const GLubyte mask[])
-{
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-   GrLfbInfo_t info;
-   BEGIN_BOARD_LOCK();
-   if (grLfbLock(GR_LFB_READ_ONLY,
-                fxMesa->currentFB,
-                GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
-      const GLint srcStride = info.strideInBytes / 2;  /* stride in GLushorts */
-      const GLint winX = 0;
-      const GLint winY = fxMesa->height - 1;
-      GLuint i;
-      for (i = 0; i < n; i++) {
-        if (mask[i]) {
-           const GLushort *data16 = (const GLushort *) info.lfbPtr
-              + (winY - y[i]) * srcStride + (winX + x[i]);
-           const GLushort pixel = *data16;
-           rgba[i][RCOMP] = FX_PixelToR[pixel];
-           rgba[i][GCOMP] = FX_PixelToG[pixel];
-           rgba[i][BCOMP] = FX_PixelToB[pixel];
-           rgba[i][ACOMP] = 255;
-        }
-      }
-      grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
-   }
-   END_BOARD_LOCK();
-}
-
-
-static void read_R5G5B5_pixels (const GLcontext * ctx,
-                                GLuint n,
-                                const GLint x[], const GLint y[],
-                                GLubyte rgba[][4],
-                                const GLubyte mask[])
-{
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-   GrLfbInfo_t info;
-   BEGIN_BOARD_LOCK();
-   if (grLfbLock(GR_LFB_READ_ONLY,
-                fxMesa->currentFB,
-                GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
-      const GLint srcStride = info.strideInBytes / 2;  /* stride in GLushorts */
-      const GLint winX = 0;
-      const GLint winY = fxMesa->height - 1;
-      GLuint i;
-      for (i = 0; i < n; i++) {
-        if (mask[i]) {
-           const GLushort *data16 = (const GLushort *) info.lfbPtr
-              + (winY - y[i]) * srcStride + (winX + x[i]);
-           const GLushort pixel = *data16;
-           rgba[i][RCOMP] = FX_rgb_scale_5[ pixel        & 0x1f];
-           rgba[i][GCOMP] = FX_rgb_scale_5[(pixel >> 5)  & 0x1f];
-           rgba[i][BCOMP] = FX_rgb_scale_5[(pixel >> 10) & 0x1f];
-           rgba[i][ACOMP] = (pixel & 0x8000) ? 255 : 0;
-        }
-      }
-      grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
-   }
-   END_BOARD_LOCK();
-}
-
-
-static void
-read_R8G8B8_pixels(const GLcontext * ctx,
-                  GLuint n, const GLint x[], const GLint y[],
-                  GLubyte rgba[][4], const GLubyte mask[])
+static void fxReadRGBASpan_ARGB8888 (const GLcontext * ctx,
+                                     GLuint n,
+                                     GLint x, GLint y,
+                                     GLubyte rgba[][4])
 {
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-   GrLfbInfo_t info;
-   BEGIN_BOARD_LOCK();
-   if (grLfbLock(GR_LFB_READ_ONLY,
-                fxMesa->currentFB,
-                GR_LFBWRITEMODE_ANY, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
-      const GLint srcStride = info.strideInBytes / 4;  /* stride in GLuints */
-      const GLint winX = 0;
-      const GLint winY = fxMesa->height - 1;
-      GLuint i;
-      for (i = 0; i < n; i++) {
-        if (mask[i]) {
-           const GLuint *data32 = (const GLuint *) info.lfbPtr
-              + (winY - y[i]) * srcStride + (winX + x[i]);
-           const GLuint pixel = *data32;
-           *(GLuint *)&rgba[i][0] = pixel;
-        }
-      }
-      grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
-   }
-   END_BOARD_LOCK();
+ /* Hack alert: WRONG! */
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ grLfbReadRegion(fxMesa->currentFB, x, fxMesa->height - 1 - y, n, 1, n * 4, rgba);
 }
 
 
-
 /************************************************************************/
 /*****                    Depth functions                           *****/
 /************************************************************************/
@@ -753,45 +617,79 @@ void
 fxSetupDDSpanPointers(GLcontext * ctx)
 {
    struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
+   fxMesaContext fxMesa = FX_CONTEXT(ctx);
 
    swdd->SetBuffer = fxDDSetBuffer;
 
-   swdd->WriteRGBASpan = fxDDWriteRGBASpan;
-   swdd->WriteRGBSpan = fxDDWriteRGBSpan;
-   swdd->WriteMonoRGBASpan = fxDDWriteMonoRGBASpan;
-   swdd->WriteRGBAPixels = fxDDWriteRGBAPixels;
-   swdd->WriteMonoRGBAPixels = fxDDWriteMonoRGBAPixels;
-
-   /*  swdd->ReadRGBASpan        =fxDDReadRGBASpan; */
-  {
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
    switch (fxMesa->colDepth) {
           case 15:
-               swdd->ReadRGBASpan = read_R5G5B5_span;
-               swdd->ReadRGBAPixels = read_R5G5B5_pixels;
+               swdd->WriteRGBASpan = tdfxWriteRGBASpan_ARGB1555;
+               swdd->WriteRGBSpan = tdfxWriteRGBSpan_ARGB1555;
+               swdd->WriteRGBAPixels = tdfxWriteRGBAPixels_ARGB1555;
+               swdd->WriteMonoRGBASpan = tdfxWriteMonoRGBASpan_ARGB1555;
+               swdd->WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_ARGB1555;
+               swdd->ReadRGBASpan = /*td*/fxReadRGBASpan_ARGB1555;
+               swdd->ReadRGBAPixels = tdfxReadRGBAPixels_ARGB1555;
+
                swdd->WriteDepthSpan = fxDDWriteDepthSpan;
                swdd->WriteDepthPixels = fxDDWriteDepthPixels;
                swdd->ReadDepthSpan = fxDDReadDepthSpan;
                swdd->ReadDepthPixels = fxDDReadDepthPixels;
                break;
           case 16:
-               swdd->ReadRGBASpan = read_R5G6B5_span;
-               swdd->ReadRGBAPixels = read_R5G6B5_pixels;
+               swdd->WriteRGBASpan = tdfxWriteRGBASpan_RGB565;
+               swdd->WriteRGBSpan = tdfxWriteRGBSpan_RGB565;
+               swdd->WriteRGBAPixels = tdfxWriteRGBAPixels_RGB565;
+               swdd->WriteMonoRGBASpan = tdfxWriteMonoRGBASpan_RGB565;
+               swdd->WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_RGB565;
+               swdd->ReadRGBASpan = /*td*/fxReadRGBASpan_RGB565;
+               swdd->ReadRGBAPixels = tdfxReadRGBAPixels_RGB565;
+               
                swdd->WriteDepthSpan = fxDDWriteDepthSpan;
                swdd->WriteDepthPixels = fxDDWriteDepthPixels;
                swdd->ReadDepthSpan = fxDDReadDepthSpan;
                swdd->ReadDepthPixels = fxDDReadDepthPixels;
                break;
           case 32:
-               swdd->ReadRGBASpan = read_R8G8B8_span;
-               swdd->ReadRGBAPixels = read_R8G8B8_pixels;
+               swdd->WriteRGBASpan = tdfxWriteRGBASpan_ARGB8888;
+               swdd->WriteRGBSpan = tdfxWriteRGBSpan_ARGB8888;
+               swdd->WriteRGBAPixels = tdfxWriteRGBAPixels_ARGB8888;
+               swdd->WriteMonoRGBASpan = tdfxWriteMonoRGBASpan_ARGB8888;
+               swdd->WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_ARGB8888;
+               swdd->ReadRGBASpan = tdfxReadRGBASpan_ARGB8888;
+               swdd->ReadRGBAPixels = tdfxReadRGBAPixels_ARGB8888;
+
                swdd->WriteDepthSpan = fxDDWriteDepth32Span;
                swdd->WriteDepthPixels = fxDDWriteDepth32Pixels;
                swdd->ReadDepthSpan = fxDDReadDepth32Span;
                swdd->ReadDepthPixels = fxDDReadDepth32Pixels;
                break;
    }
-  }
+
+#if 0
+   if ( fxMesa->haveHwStencil ) {
+      swdd->WriteStencilSpan   = write_stencil_span;
+      swdd->ReadStencilSpan    = read_stencil_span;
+      swdd->WriteStencilPixels = write_stencil_pixels;
+      swdd->ReadStencilPixels  = read_stencil_pixels;
+   }
+
+   swdd->WriteDepthSpan                = tdfxDDWriteDepthSpan;
+   swdd->WriteDepthPixels      = tdfxDDWriteDepthPixels;
+   swdd->ReadDepthSpan         = tdfxDDReadDepthSpan;
+   swdd->ReadDepthPixels       = tdfxDDReadDepthPixels;
+
+   swdd->WriteCI8Span          = NULL;
+   swdd->WriteCI32Span         = NULL;
+   swdd->WriteMonoCISpan       = NULL;
+   swdd->WriteCI32Pixels       = NULL;
+   swdd->WriteMonoCIPixels     = NULL;
+   swdd->ReadCI32Span          = NULL;
+   swdd->ReadCI32Pixels                = NULL;
+
+   swdd->SpanRenderStart          = tdfxSpanRenderStart; /* BEGIN_BOARD_LOCK */
+   swdd->SpanRenderFinish         = tdfxSpanRenderFinish; /* END_BOARD_LOCK */
+#endif
 }
 
 
index 38a268922ae2826bbd56a68b700e81470e6cddd7..3ae22b6070b0818f443373ec2a5dec987de3e460 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fxddtex.c,v 1.48 2003/10/02 17:36:44 brianp Exp $ */
+/* $Id: fxddtex.c,v 1.49 2003/10/09 15:12:21 dborca Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -41,6 +41,7 @@
 #if defined(FX)
 
 #include "fxdrv.h"
+#include "enums.h"
 #include "image.h"
 #include "teximage.h"
 #include "texformat.h"
@@ -192,8 +193,10 @@ fxDDTexParam(GLcontext * ctx, GLenum target, struct gl_texture_object *tObj,
    tfxTexInfo *ti;
 
    if (TDFX_DEBUG & VERBOSE_DRIVER) {
-      fprintf(stderr, "%s(%d, %x, %x, %x)\n", __FUNCTION__,
-                      tObj->Name, (GLuint) tObj->DriverData, pname, param);
+      fprintf(stderr, "fxDDTexParam(%d, %x, %s, %s)\n",
+                      tObj->Name, (GLuint) tObj->DriverData,
+                      _mesa_lookup_enum_by_nr(pname),
+                      _mesa_lookup_enum_by_nr(param));
    }
 
    if (target != GL_TEXTURE_2D)
@@ -279,6 +282,7 @@ fxDDTexParam(GLcontext * ctx, GLenum target, struct gl_texture_object *tObj,
       case GL_MIRRORED_REPEAT:
          ti->sClamp = GR_TEXTURECLAMP_MIRROR_EXT;
          break;
+      case GL_CLAMP_TO_EDGE: /* CLAMP discarding border */
       case GL_CLAMP:
         ti->sClamp = GR_TEXTURECLAMP_CLAMP;
         break;
@@ -296,6 +300,7 @@ fxDDTexParam(GLcontext * ctx, GLenum target, struct gl_texture_object *tObj,
       case GL_MIRRORED_REPEAT:
          ti->tClamp = GR_TEXTURECLAMP_MIRROR_EXT;
          break;
+      case GL_CLAMP_TO_EDGE: /* CLAMP discarding border */
       case GL_CLAMP:
         ti->tClamp = GR_TEXTURECLAMP_CLAMP;
         break;
@@ -625,125 +630,6 @@ fxTexGetInfo(int w, int h, GrLOD_t * lodlevel, GrAspectRatio_t * ar,
    return 1;
 }
 
-/*
- * Given an OpenGL internal texture format, return the corresponding
- * Glide internal texture format and base texture format.
- */
-void
-fxTexGetFormat(GLcontext *ctx, GLenum glformat, GrTextureFormat_t * tfmt, GLint * ifmt) /* [koolsmoky] */
-{
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-   GLboolean allow32bpt = fxMesa->HaveTexFmt;
-
-   switch (glformat) {
-   case 1:
-   case GL_LUMINANCE:
-   case GL_LUMINANCE4:
-   case GL_LUMINANCE8:
-   case GL_LUMINANCE12:
-   case GL_LUMINANCE16:
-      if (tfmt)
-        (*tfmt) = GR_TEXFMT_INTENSITY_8;
-      if (ifmt)
-        (*ifmt) = GL_LUMINANCE;
-      break;
-   case 2:
-   case GL_LUMINANCE_ALPHA:
-   case GL_LUMINANCE4_ALPHA4:
-   case GL_LUMINANCE6_ALPHA2:
-   case GL_LUMINANCE8_ALPHA8:
-   case GL_LUMINANCE12_ALPHA4:
-   case GL_LUMINANCE12_ALPHA12:
-   case GL_LUMINANCE16_ALPHA16:
-      if (tfmt)
-        (*tfmt) = GR_TEXFMT_ALPHA_INTENSITY_88;
-      if (ifmt)
-        (*ifmt) = GL_LUMINANCE_ALPHA;
-      break;
-   case GL_INTENSITY:
-   case GL_INTENSITY4:
-   case GL_INTENSITY8:
-   case GL_INTENSITY12:
-   case GL_INTENSITY16:
-      if (tfmt)
-        (*tfmt) = GR_TEXFMT_ALPHA_8;
-      if (ifmt)
-        (*ifmt) = GL_INTENSITY;
-      break;
-   case GL_ALPHA:
-   case GL_ALPHA4:
-   case GL_ALPHA8:
-   case GL_ALPHA12:
-   case GL_ALPHA16:
-      if (tfmt)
-        (*tfmt) = GR_TEXFMT_ALPHA_8;
-      if (ifmt)
-        (*ifmt) = GL_ALPHA;
-      break;
-   case GL_R3_G3_B2:
-   case GL_RGB4:
-   case GL_RGB5:
-      if (tfmt)
-        (*tfmt) = GR_TEXFMT_RGB_565;
-      if (ifmt)
-        (*ifmt) = GL_RGB;
-      break;
-   case 3:
-   case GL_RGB:
-   case GL_RGB8:
-   case GL_RGB10:
-   case GL_RGB12:
-   case GL_RGB16:
-      if (tfmt)
-        (*tfmt) = allow32bpt ? GR_TEXFMT_ARGB_8888 : GR_TEXFMT_RGB_565;
-      if (ifmt)
-        (*ifmt) = GL_RGB;
-      break;
-   case GL_RGBA2:
-   case GL_RGBA4:
-      if (tfmt)
-        (*tfmt) = GR_TEXFMT_ARGB_4444;
-      if (ifmt)
-        (*ifmt) = GL_RGBA;
-      break;
-   case 4:
-   case GL_RGBA:
-   case GL_RGBA8:
-   case GL_RGB10_A2:
-   case GL_RGBA12:
-   case GL_RGBA16:
-      if (tfmt)
-        (*tfmt) = allow32bpt ? GR_TEXFMT_ARGB_8888 : GR_TEXFMT_ARGB_4444;
-      if (ifmt)
-        (*ifmt) = GL_RGBA;
-      break;
-   case GL_RGB5_A1:
-      if (tfmt)
-        (*tfmt) = GR_TEXFMT_ARGB_1555;
-      if (ifmt)
-        (*ifmt) = GL_RGBA;
-      break;
-   case GL_COLOR_INDEX:
-   case GL_COLOR_INDEX1_EXT:
-   case GL_COLOR_INDEX2_EXT:
-   case GL_COLOR_INDEX4_EXT:
-   case GL_COLOR_INDEX8_EXT:
-   case GL_COLOR_INDEX12_EXT:
-   case GL_COLOR_INDEX16_EXT:
-      if (tfmt)
-        (*tfmt) = GR_TEXFMT_P_8;
-      if (ifmt)
-        (*ifmt) = GL_RGBA;     /* XXX why is this RGBA? */
-      break;
-   default:
-      fprintf(stderr, "%s: ERROR: unsupported internalFormat (0x%x)\n",
-                     __FUNCTION__, glformat);
-      fxCloseHardware();
-      exit(-1);
-      break;
-   }
-}
-
 static GLboolean
 fxIsTexSupported(GLenum target, GLint internalFormat,
                 const struct gl_texture_image *image)
index b404d52fa6274e99360946f95fab7d10c22e01a7..65c1e58ff25e17f857090f67c0f4d591833d82b1 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fxdrv.h,v 1.59 2003/10/02 17:36:44 brianp Exp $ */
+/* $Id: fxdrv.h,v 1.60 2003/10/09 15:12:21 dborca Exp $ */
 
 /*
  * Mesa 3-D graphics library
 #define FX_UM_ALPHA_CONSTANT        0x08000000
 
 
+/* for Voodoo3/Banshee's grColorCombine() and grAlphaCombine() */
+struct tdfx_combine {
+   GrCombineFunction_t Function;       /* Combine function */
+   GrCombineFactor_t Factor;           /* Combine scale factor */
+   GrCombineLocal_t Local;             /* Local combine source */
+   GrCombineOther_t Other;             /* Other combine source */
+   FxBool Invert;                      /* Combine result inversion flag */
+};
+
+/* for Voodoo3's grTexCombine() */
+struct tdfx_texcombine {
+   GrCombineFunction_t FunctionRGB;
+   GrCombineFactor_t FactorRGB;
+   GrCombineFunction_t FunctionAlpha;
+   GrCombineFactor_t FactorAlpha;
+   FxBool InvertRGB;
+   FxBool InvertAlpha;
+};
+
+
+/* for Voodoo5's grColorCombineExt() */
+struct tdfx_combine_color_ext {
+   GrCCUColor_t SourceA;
+   GrCombineMode_t ModeA;
+   GrCCUColor_t SourceB;
+   GrCombineMode_t ModeB;
+   GrCCUColor_t SourceC;
+   FxBool InvertC;
+   GrCCUColor_t SourceD;
+   FxBool InvertD;
+   FxU32 Shift;
+   FxBool Invert;
+};
+
+/* for Voodoo5's grAlphaCombineExt() */
+struct tdfx_combine_alpha_ext {
+   GrACUColor_t SourceA;
+   GrCombineMode_t ModeA;
+   GrACUColor_t SourceB;
+   GrCombineMode_t ModeB;
+   GrACUColor_t SourceC;
+   FxBool InvertC;
+   GrACUColor_t SourceD;
+   FxBool InvertD;
+   FxU32 Shift;
+   FxBool Invert;
+};
+
+/* for Voodoo5's grTexColorCombineExt() */
+struct tdfx_color_texenv {
+   GrTCCUColor_t SourceA;
+   GrCombineMode_t ModeA;
+   GrTCCUColor_t SourceB;
+   GrCombineMode_t ModeB;
+   GrTCCUColor_t SourceC;
+   FxBool InvertC;
+   GrTCCUColor_t SourceD;
+   FxBool InvertD;
+   FxU32 Shift;
+   FxBool Invert;
+};
+
+/* for Voodoo5's grTexAlphaCombineExt() */
+struct tdfx_alpha_texenv {
+   GrTACUColor_t SourceA;
+   GrCombineMode_t ModeA;
+   GrTACUColor_t SourceB;
+   GrCombineMode_t ModeB;
+   GrTACUColor_t SourceC;
+   FxBool InvertC;
+   GrTCCUColor_t SourceD;
+   FxBool InvertD;
+   FxU32 Shift;
+   FxBool Invert;
+};
+
+/* Voodoo5's texture combine environment */
+struct tdfx_texcombine_ext {
+   struct tdfx_alpha_texenv Alpha;
+   struct tdfx_color_texenv Color;
+   GrColor_t EnvColor;
+};
+
+
 /*
   Memory range from startAddr to endAddr-1
 */
@@ -570,9 +654,6 @@ extern int fxDDInitFxMesaContext(fxMesaContext fxMesa);
 extern void fxDDDestroyFxMesaContext(fxMesaContext fxMesa);
 
 
-void fxColorMask (fxMesaContext fxMesa, GLboolean enable);
-
-
 extern void fxSetScissorValues(GLcontext * ctx);
 extern void fxTMMoveInTM_NoLock(fxMesaContext fxMesa,
                                struct gl_texture_object *tObj, GLint where);
@@ -580,6 +661,12 @@ extern void fxInitPixelTables(fxMesaContext fxMesa, GLboolean bgrOrder);
 
 extern void fxCheckIsInHardware(GLcontext *ctx);
 
+/* fxsetup:
+ * semi-private functions
+ */
+void fxSetupScissor (GLcontext * ctx);
+void fxSetupColorMask (GLcontext * ctx);
+
 /* Flags for software fallback cases */
 #define FX_FALLBACK_TEXTURE_1D_3D      0x0001
 #define FX_FALLBACK_DRAW_BUFFER                0x0002
@@ -595,4 +682,11 @@ extern void fxCheckIsInHardware(GLcontext *ctx);
 
 extern GLuint fx_check_IsInHardware(GLcontext *ctx);
 
+/* run-time debugging */
+#if FX_DEBUG
+extern int TDFX_DEBUG;
+#else
+#define TDFX_DEBUG             0
+#endif
+
 #endif
index f6177e4ff58354a59e7c01ab423f7dfb76b524e6..324b5d99f0f8cc05ea1de542a48ffd6fee249f9e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fxglidew.h,v 1.16 2003/10/02 17:36:44 brianp Exp $ */
+/* $Id: fxglidew.h,v 1.17 2003/10/09 15:12:21 dborca Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -216,12 +216,4 @@ extern FxBool FX_grSstControl(FxU32 code);
 
 
 
-#if FX_DEBUG
-extern int TDFX_DEBUG;
-#else
-#define TDFX_DEBUG             0
-#endif
-
-
-
 #endif /* __FX_GLIDE_WARPER__ */
index 9ebc603ae7ae17b45a87467d97d873494b1cbbcf..2959fede15a77dae9efcdd525bf7eac3a791a846 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fxsetup.c,v 1.40 2003/10/02 17:36:44 brianp Exp $ */
+/* $Id: fxsetup.c,v 1.41 2003/10/09 15:12:21 dborca Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -79,19 +79,13 @@ fxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj)
    else
       FX_smallLodLog2(ti->info) = FX_largeLodLog2(ti->info);
 
-/*jejeje*/
-ti->baseLevelInternalFormat = tObj->Image[minl]->Format;
-#if 0
-   fxTexGetFormat(ctx, tObj->Image[minl]->TexFormat->BaseFormat, &(ti->info.format),
-                 &(ti->baseLevelInternalFormat)); /* [koolsmoky] */
-#endif
+   ti->baseLevelInternalFormat = tObj->Image[minl]->Format;
 
    switch (tObj->WrapS) {
    case GL_MIRRORED_REPEAT:
       ti->sClamp = GR_TEXTURECLAMP_MIRROR_EXT;
       break;
-   case GL_CLAMP_TO_EDGE:
-      /* What's this really mean compared to GL_CLAMP? */
+   case GL_CLAMP_TO_EDGE: /* CLAMP discarding border */
    case GL_CLAMP:
       ti->sClamp = GR_TEXTURECLAMP_CLAMP;
       break;
@@ -105,8 +99,7 @@ ti->baseLevelInternalFormat = tObj->Image[minl]->Format;
    case GL_MIRRORED_REPEAT:
       ti->tClamp = GR_TEXTURECLAMP_MIRROR_EXT;
       break;
-   case GL_CLAMP_TO_EDGE:
-      /* What's this really mean compared to GL_CLAMP? */
+   case GL_CLAMP_TO_EDGE: /* CLAMP discarding border */
    case GL_CLAMP:
       ti->tClamp = GR_TEXTURECLAMP_CLAMP;
       break;
@@ -301,6 +294,10 @@ fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj)
       fprintf(stderr, "%s(%p (%d))\n", __FUNCTION__, (void *)tObj, tObj->Name);
    }
 
+#if 1 /* [dBorca] Good... bad... I'm the guy with the gun! */
+   ti->lastTimeUsed = fxMesa->texBindNumber;
+#endif
+
    /* Make sure we're not loaded incorrectly */
    if (ti->isInTM) {
       if (ti->LODblend) {
@@ -390,66 +387,84 @@ fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj)
 static void
 fxSelectSingleTMUSrc_NoLock(fxMesaContext fxMesa, GLint tmu, FxBool LODblend)
 {
+   struct tdfx_texcombine tex0, tex1;
+
    if (TDFX_DEBUG & VERBOSE_DRIVER) {
       fprintf(stderr, "%s(%d, %d)\n", __FUNCTION__, tmu, LODblend);
    }
 
+   tex0.InvertRGB     = FXFALSE;
+   tex0.InvertAlpha   = FXFALSE;
+   tex1.InvertRGB     = FXFALSE;
+   tex1.InvertAlpha   = FXFALSE;
+
    if (LODblend) {
-      grTexCombine(GR_TMU0,
-                            GR_COMBINE_FUNCTION_BLEND,
-                            GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION,
-                            GR_COMBINE_FUNCTION_BLEND,
-                            GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION,
-                            FXFALSE, FXFALSE);
-
-      if (fxMesa->haveTwoTMUs)
-        grTexCombine(GR_TMU1,
-                               GR_COMBINE_FUNCTION_LOCAL,
-                               GR_COMBINE_FACTOR_NONE,
-                               GR_COMBINE_FUNCTION_LOCAL,
-                               GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
+      tex0.FunctionRGB   = GR_COMBINE_FUNCTION_BLEND;
+      tex0.FactorRGB     = GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION;
+      tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND;
+      tex0.FactorAlpha   = GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION;
+
+      tex1.FunctionRGB   = GR_COMBINE_FUNCTION_LOCAL;
+      tex1.FactorRGB     = GR_COMBINE_FACTOR_NONE;
+      tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
+      tex1.FactorAlpha   = GR_COMBINE_FACTOR_NONE;
+
       fxMesa->tmuSrc = FX_TMU_SPLIT;
    }
    else {
       if (tmu != FX_TMU1) {
-        grTexCombine(GR_TMU0,
-                               GR_COMBINE_FUNCTION_LOCAL,
-                               GR_COMBINE_FACTOR_NONE,
-                               GR_COMBINE_FUNCTION_LOCAL,
-                               GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
-        if (fxMesa->haveTwoTMUs) {
-           grTexCombine(GR_TMU1,
-                                  GR_COMBINE_FUNCTION_ZERO,
-                                  GR_COMBINE_FACTOR_NONE,
-                                  GR_COMBINE_FUNCTION_ZERO,
-                                  GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
-        }
+         tex0.FunctionRGB   = GR_COMBINE_FUNCTION_LOCAL;
+         tex0.FactorRGB     = GR_COMBINE_FACTOR_NONE;
+         tex0.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
+         tex0.FactorAlpha   = GR_COMBINE_FACTOR_NONE;
+
+         tex1.FunctionRGB   = GR_COMBINE_FUNCTION_ZERO;
+         tex1.FactorRGB     = GR_COMBINE_FACTOR_NONE;
+         tex1.FunctionAlpha = GR_COMBINE_FUNCTION_ZERO;
+         tex1.FactorAlpha   = GR_COMBINE_FACTOR_NONE;
+
         fxMesa->tmuSrc = FX_TMU0;
       }
       else {
-        grTexCombine(GR_TMU1,
-                               GR_COMBINE_FUNCTION_LOCAL,
-                               GR_COMBINE_FACTOR_NONE,
-                               GR_COMBINE_FUNCTION_LOCAL,
-                               GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
+         tex1.FunctionRGB   = GR_COMBINE_FUNCTION_LOCAL;
+         tex1.FactorRGB     = GR_COMBINE_FACTOR_NONE;
+         tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
+         tex1.FactorAlpha   = GR_COMBINE_FACTOR_NONE;
 
         /* GR_COMBINE_FUNCTION_SCALE_OTHER doesn't work ?!? */
 
-        grTexCombine(GR_TMU0,
-                               GR_COMBINE_FUNCTION_BLEND,
-                               GR_COMBINE_FACTOR_ONE,
-                               GR_COMBINE_FUNCTION_BLEND,
-                               GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE);
+         tex0.FunctionRGB   = GR_COMBINE_FUNCTION_BLEND;
+         tex0.FactorRGB     = GR_COMBINE_FACTOR_ONE;
+         tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND;
+         tex0.FactorAlpha   = GR_COMBINE_FACTOR_ONE;
 
         fxMesa->tmuSrc = FX_TMU1;
       }
    }
+
+   grTexCombine(GR_TMU0,
+                tex0.FunctionRGB,
+                tex0.FactorRGB,
+                tex0.FunctionAlpha,
+                tex0.FactorAlpha,
+                tex0.InvertRGB,
+                tex0.InvertAlpha);
+   if (fxMesa->haveTwoTMUs) {
+      grTexCombine(GR_TMU1,
+                   tex1.FunctionRGB,
+                   tex1.FactorRGB,
+                   tex1.FunctionAlpha,
+                   tex1.FactorAlpha,
+                   tex1.InvertRGB,
+                   tex1.InvertAlpha);
+   }
 }
 
 static void
 fxSetupTextureSingleTMU_NoLock(GLcontext * ctx, GLuint textureset)
 {
    fxMesaContext fxMesa = FX_CONTEXT(ctx);
+   struct tdfx_combine alphaComb, colorComb;
    GrCombineLocal_t localc, locala;
    GLuint unitsmode;
    GLint ifmt;
@@ -503,59 +518,115 @@ fxSetupTextureSingleTMU_NoLock(GLcontext * ctx, GLuint textureset)
       fprintf(stderr, "%s: envmode is %s\n", __FUNCTION__,
              _mesa_lookup_enum_by_nr(ctx->Texture.Unit[textureset].EnvMode));
 
+   alphaComb.Local    = locala;
+   alphaComb.Invert   = FXFALSE;
+   colorComb.Local    = localc;
+   colorComb.Invert   = FXFALSE;
+
    switch (ctx->Texture.Unit[textureset].EnvMode) {
    case GL_DECAL:
-      grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL,
-                              GR_COMBINE_FACTOR_NONE,
-                              locala, GR_COMBINE_OTHER_NONE, FXFALSE);
+      alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
+      alphaComb.Factor   = GR_COMBINE_FACTOR_NONE;
+      alphaComb.Other    = GR_COMBINE_OTHER_NONE;
 
-      grColorCombine(GR_COMBINE_FUNCTION_BLEND,
-                              GR_COMBINE_FACTOR_TEXTURE_ALPHA,
-                              localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
+      colorComb.Function = GR_COMBINE_FUNCTION_BLEND;
+      colorComb.Factor   = GR_COMBINE_FACTOR_TEXTURE_ALPHA;
+      colorComb.Other    = GR_COMBINE_OTHER_TEXTURE;
       break;
    case GL_MODULATE:
-      grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
-                              GR_COMBINE_FACTOR_LOCAL,
-                              locala, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
-
-      if (ifmt == GL_ALPHA)
-        grColorCombine(GR_COMBINE_FUNCTION_LOCAL,
-                                 GR_COMBINE_FACTOR_NONE,
-                                 localc, GR_COMBINE_OTHER_NONE, FXFALSE);
-      else
-        grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
-                                 GR_COMBINE_FACTOR_LOCAL,
-                                 localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
+      alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+      alphaComb.Factor   = GR_COMBINE_FACTOR_LOCAL;
+      alphaComb.Other    = GR_COMBINE_OTHER_TEXTURE;
+
+      if (ifmt == GL_ALPHA) {
+         colorComb.Function = GR_COMBINE_FUNCTION_LOCAL;
+         colorComb.Factor   = GR_COMBINE_FACTOR_NONE;
+         colorComb.Other    = GR_COMBINE_OTHER_NONE;
+      } else {
+         colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+         colorComb.Factor   = GR_COMBINE_FACTOR_LOCAL;
+         colorComb.Other    = GR_COMBINE_OTHER_TEXTURE;
+      }
       break;
    case GL_BLEND:
-      if (TDFX_DEBUG & VERBOSE_DRIVER)
-        fprintf(stderr, "%s: GL_BLEND not yet supported\n", __FUNCTION__);
+      /*
+       * XXX we can't do real GL_BLEND mode.  These settings assume that
+       * the TexEnv color is black and incoming fragment color is white.
+       */
+      if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) {
+         /* Av = Af */
+         alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
+         alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
+         alphaComb.Other = GR_COMBINE_OTHER_NONE;
+      }
+      else if (ifmt == GL_INTENSITY) {
+         /* Av = Af * (1 - It) + Ac * It */
+         /* XXX this is wrong */
+         alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
+         alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
+         alphaComb.Other = GR_COMBINE_OTHER_NONE;
+      }
+      else {
+         /* Av = Af * At */
+         alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+         alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL;
+         alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
+      }
+      if (ifmt == GL_ALPHA) {
+         colorComb.Function = GR_COMBINE_FUNCTION_LOCAL;
+         colorComb.Factor = GR_COMBINE_FACTOR_NONE;
+         colorComb.Other = GR_COMBINE_OTHER_NONE;
+      }
+      else {
+         colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+         colorComb.Factor = GR_COMBINE_FACTOR_ONE;
+         colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
+         colorComb.Invert = FXTRUE;
+      }
+      /* XXX return GL_FALSE for modes we don't support */
+      if (TDFX_DEBUG & VERBOSE_DRIVER) {
+        fprintf(stderr, "%s: GL_BLEND not quite supported\n", __FUNCTION__);
+      }
       break;
    case GL_REPLACE:
-      if ((ifmt == GL_RGB) || (ifmt == GL_LUMINANCE))
-        grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL,
-                                 GR_COMBINE_FACTOR_NONE,
-                                 locala, GR_COMBINE_OTHER_NONE, FXFALSE);
-      else
-        grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
-                                 GR_COMBINE_FACTOR_ONE,
-                                 locala, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
-
-      if (ifmt == GL_ALPHA)
-        grColorCombine(GR_COMBINE_FUNCTION_LOCAL,
-                                 GR_COMBINE_FACTOR_NONE,
-                                 localc, GR_COMBINE_OTHER_NONE, FXFALSE);
-      else
-        grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
-                                 GR_COMBINE_FACTOR_ONE,
-                                 localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
+      if ((ifmt == GL_RGB) || (ifmt == GL_LUMINANCE)) {
+         alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
+         alphaComb.Factor   = GR_COMBINE_FACTOR_NONE;
+         alphaComb.Other    = GR_COMBINE_OTHER_NONE;
+      } else {
+         alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+         alphaComb.Factor   = GR_COMBINE_FACTOR_ONE;
+         alphaComb.Other    = GR_COMBINE_OTHER_TEXTURE;
+      }
+
+      if (ifmt == GL_ALPHA) {
+         colorComb.Function = GR_COMBINE_FUNCTION_LOCAL;
+         colorComb.Factor   = GR_COMBINE_FACTOR_NONE;
+         colorComb.Other    = GR_COMBINE_OTHER_NONE;
+      } else {
+         colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+         colorComb.Factor   = GR_COMBINE_FACTOR_ONE;
+         colorComb.Other    = GR_COMBINE_OTHER_TEXTURE;
+      }
       break;
    default:
-      if (TDFX_DEBUG & VERBOSE_DRIVER)
+      if (TDFX_DEBUG & VERBOSE_DRIVER) {
         fprintf(stderr, "%s: %x Texture.EnvMode not yet supported\n", __FUNCTION__,
                 ctx->Texture.Unit[textureset].EnvMode);
-      break;
+      }
+      return;
    }
+
+   grAlphaCombine(alphaComb.Function,
+                  alphaComb.Factor,
+                  alphaComb.Local,
+                  alphaComb.Other,
+                  alphaComb.Invert);
+   grColorCombine(colorComb.Function,
+                  colorComb.Factor,
+                  colorComb.Local,
+                  colorComb.Other,
+                  colorComb.Invert);
 }
 
 #if 00
@@ -715,6 +786,8 @@ static void
 fxSetupTextureDoubleTMU_NoLock(GLcontext * ctx)
 {
    fxMesaContext fxMesa = FX_CONTEXT(ctx);
+   struct tdfx_combine alphaComb, colorComb;
+   struct tdfx_texcombine tex0, tex1;
    GrCombineLocal_t localc, locala;
    tfxTexInfo *ti0, *ti1;
    struct gl_texture_object *tObj0 = ctx->Texture.Unit[0].Current2D;
@@ -769,6 +842,16 @@ fxSetupTextureDoubleTMU_NoLock(GLcontext * ctx)
       tmu1 = 0;
    }
    fxMesa->tmuSrc = FX_TMU_BOTH;
+
+   tex0.InvertRGB     = FXFALSE;
+   tex0.InvertAlpha   = FXFALSE;
+   tex1.InvertRGB     = FXFALSE;
+   tex1.InvertAlpha   = FXFALSE;
+   alphaComb.Local    = locala;
+   alphaComb.Invert   = FXFALSE;
+   colorComb.Local    = localc;
+   colorComb.Invert   = FXFALSE;
+
    switch (envmode) {
    case (FX_UM_E0_MODULATE | FX_UM_E1_MODULATE):
       {
@@ -777,120 +860,111 @@ fxSetupTextureDoubleTMU_NoLock(GLcontext * ctx)
         isalpha[tmu0] = (ti0->baseLevelInternalFormat == GL_ALPHA);
         isalpha[tmu1] = (ti1->baseLevelInternalFormat == GL_ALPHA);
 
-        if (isalpha[FX_TMU1])
-           grTexCombine(GR_TMU1,
-                                  GR_COMBINE_FUNCTION_ZERO,
-                                  GR_COMBINE_FACTOR_NONE,
-                                  GR_COMBINE_FUNCTION_LOCAL,
-                                  GR_COMBINE_FACTOR_NONE, FXTRUE, FXFALSE);
-        else
-           grTexCombine(GR_TMU1,
-                                  GR_COMBINE_FUNCTION_LOCAL,
-                                  GR_COMBINE_FACTOR_NONE,
-                                  GR_COMBINE_FUNCTION_LOCAL,
-                                  GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
-
-        if (isalpha[FX_TMU0])
-           grTexCombine(GR_TMU0,
-                                  GR_COMBINE_FUNCTION_BLEND_OTHER,
-                                  GR_COMBINE_FACTOR_ONE,
-                                  GR_COMBINE_FUNCTION_BLEND_OTHER,
-                                  GR_COMBINE_FACTOR_LOCAL, FXFALSE, FXFALSE);
-        else
-           grTexCombine(GR_TMU0,
-                                  GR_COMBINE_FUNCTION_BLEND_OTHER,
-                                  GR_COMBINE_FACTOR_LOCAL,
-                                  GR_COMBINE_FUNCTION_BLEND_OTHER,
-                                  GR_COMBINE_FACTOR_LOCAL, FXFALSE, FXFALSE);
-
-        grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
-                                 GR_COMBINE_FACTOR_LOCAL,
-                                 localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
-
-        grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
-                                 GR_COMBINE_FACTOR_LOCAL,
-                                 locala, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
+        if (isalpha[FX_TMU1]) {
+            tex1.FunctionRGB   = GR_COMBINE_FUNCTION_ZERO;
+            tex1.FactorRGB     = GR_COMBINE_FACTOR_NONE;
+            tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
+            tex1.FactorAlpha   = GR_COMBINE_FACTOR_NONE;
+            tex1.InvertRGB     = FXTRUE;
+        } else {
+            tex1.FunctionRGB   = GR_COMBINE_FUNCTION_LOCAL;
+            tex1.FactorRGB     = GR_COMBINE_FACTOR_NONE;
+            tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
+            tex1.FactorAlpha   = GR_COMBINE_FACTOR_NONE;
+         }
+
+        if (isalpha[FX_TMU0]) {
+            tex0.FunctionRGB   = GR_COMBINE_FUNCTION_BLEND_OTHER;
+            tex0.FactorRGB     = GR_COMBINE_FACTOR_ONE;
+            tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER;
+            tex0.FactorAlpha   = GR_COMBINE_FACTOR_LOCAL;
+        } else {
+            tex0.FunctionRGB   = GR_COMBINE_FUNCTION_BLEND_OTHER;
+            tex0.FactorRGB     = GR_COMBINE_FACTOR_LOCAL;
+            tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER;
+            tex0.FactorAlpha   = GR_COMBINE_FACTOR_LOCAL;
+         }
+
+         colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+         colorComb.Factor   = GR_COMBINE_FACTOR_LOCAL;
+         colorComb.Other    = GR_COMBINE_OTHER_TEXTURE;
+
+         alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+         alphaComb.Factor   = GR_COMBINE_FACTOR_LOCAL;
+         alphaComb.Other    = GR_COMBINE_OTHER_TEXTURE;
         break;
       }
    case (FX_UM_E0_REPLACE | FX_UM_E1_BLEND):   /* Only for GLQuake */
       if (tmu1 == FX_TMU1) {
-        grTexCombine(GR_TMU1,
-                               GR_COMBINE_FUNCTION_LOCAL,
-                               GR_COMBINE_FACTOR_NONE,
-                               GR_COMBINE_FUNCTION_LOCAL,
-                               GR_COMBINE_FACTOR_NONE, FXTRUE, FXFALSE);
-
-        grTexCombine(GR_TMU0,
-                               GR_COMBINE_FUNCTION_BLEND_OTHER,
-                               GR_COMBINE_FACTOR_LOCAL,
-                               GR_COMBINE_FUNCTION_BLEND_OTHER,
-                               GR_COMBINE_FACTOR_LOCAL, FXFALSE, FXFALSE);
+         tex1.FunctionRGB   = GR_COMBINE_FUNCTION_LOCAL;
+         tex1.FactorRGB     = GR_COMBINE_FACTOR_NONE;
+         tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
+         tex1.FactorAlpha   = GR_COMBINE_FACTOR_NONE;
+         tex1.InvertRGB     = FXTRUE;
+
+         tex0.FunctionRGB   = GR_COMBINE_FUNCTION_BLEND_OTHER;
+         tex0.FactorRGB     = GR_COMBINE_FACTOR_LOCAL;
+         tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER;
+         tex0.FactorAlpha   = GR_COMBINE_FACTOR_LOCAL;
       }
       else {
-        grTexCombine(GR_TMU1,
-                               GR_COMBINE_FUNCTION_LOCAL,
-                               GR_COMBINE_FACTOR_NONE,
-                               GR_COMBINE_FUNCTION_LOCAL,
-                               GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
-
-        grTexCombine(GR_TMU0,
-                               GR_COMBINE_FUNCTION_BLEND_OTHER,
-                               GR_COMBINE_FACTOR_ONE_MINUS_LOCAL,
-                               GR_COMBINE_FUNCTION_BLEND_OTHER,
-                               GR_COMBINE_FACTOR_ONE_MINUS_LOCAL,
-                               FXFALSE, FXFALSE);
+         tex1.FunctionRGB   = GR_COMBINE_FUNCTION_LOCAL;
+         tex1.FactorRGB     = GR_COMBINE_FACTOR_NONE;
+         tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
+         tex1.FactorAlpha   = GR_COMBINE_FACTOR_NONE;
+
+         tex0.FunctionRGB   = GR_COMBINE_FUNCTION_BLEND_OTHER;
+         tex0.FactorRGB     = GR_COMBINE_FACTOR_ONE_MINUS_LOCAL;
+         tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER;
+         tex0.FactorAlpha   = GR_COMBINE_FACTOR_ONE_MINUS_LOCAL;
       }
 
-      grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL,
-                              GR_COMBINE_FACTOR_NONE,
-                              locala, GR_COMBINE_OTHER_NONE, FXFALSE);
+      alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
+      alphaComb.Factor   = GR_COMBINE_FACTOR_NONE;
+      alphaComb.Other    = GR_COMBINE_OTHER_NONE;
 
-      grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
-                              GR_COMBINE_FACTOR_ONE,
-                              localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
+      colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+      colorComb.Factor   = GR_COMBINE_FACTOR_ONE;
+      colorComb.Other    = GR_COMBINE_OTHER_TEXTURE;
       break;
    case (FX_UM_E0_REPLACE | FX_UM_E1_MODULATE):        /* Quake 2 and 3 */
       if (tmu1 == FX_TMU1) {
-        grTexCombine(GR_TMU1,
-                               GR_COMBINE_FUNCTION_LOCAL,
-                               GR_COMBINE_FACTOR_NONE,
-                               GR_COMBINE_FUNCTION_ZERO,
-                               GR_COMBINE_FACTOR_NONE, FXFALSE, FXTRUE);
-
-        grTexCombine(GR_TMU0,
-                               GR_COMBINE_FUNCTION_BLEND_OTHER,
-                               GR_COMBINE_FACTOR_LOCAL,
-                               GR_COMBINE_FUNCTION_BLEND_OTHER,
-                               GR_COMBINE_FACTOR_LOCAL, FXFALSE, FXFALSE);
-
+         tex1.FunctionRGB   = GR_COMBINE_FUNCTION_LOCAL;
+         tex1.FactorRGB     = GR_COMBINE_FACTOR_NONE;
+         tex1.FunctionAlpha = GR_COMBINE_FUNCTION_ZERO;
+         tex1.FactorAlpha   = GR_COMBINE_FACTOR_NONE;
+         tex1.InvertAlpha   = FXTRUE;
+
+         tex0.FunctionRGB   = GR_COMBINE_FUNCTION_BLEND_OTHER;
+         tex0.FactorRGB     = GR_COMBINE_FACTOR_LOCAL;
+         tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER;
+         tex0.FactorAlpha   = GR_COMBINE_FACTOR_LOCAL;
       }
       else {
-        grTexCombine(GR_TMU1,
-                               GR_COMBINE_FUNCTION_LOCAL,
-                               GR_COMBINE_FACTOR_NONE,
-                               GR_COMBINE_FUNCTION_LOCAL,
-                               GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
-
-        grTexCombine(GR_TMU0,
-                               GR_COMBINE_FUNCTION_BLEND_OTHER,
-                               GR_COMBINE_FACTOR_LOCAL,
-                               GR_COMBINE_FUNCTION_BLEND_OTHER,
-                               GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE);
+         tex1.FunctionRGB   = GR_COMBINE_FUNCTION_LOCAL;
+         tex1.FactorRGB     = GR_COMBINE_FACTOR_NONE;
+         tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
+         tex1.FactorAlpha   = GR_COMBINE_FACTOR_NONE;
+
+         tex0.FunctionRGB   = GR_COMBINE_FUNCTION_BLEND_OTHER;
+         tex0.FactorRGB     = GR_COMBINE_FACTOR_LOCAL;
+         tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND_OTHER;
+         tex0.FactorAlpha   = GR_COMBINE_FACTOR_ONE;
       }
 
-      if (ti0->baseLevelInternalFormat == GL_RGB)
-        grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL,
-                                 GR_COMBINE_FACTOR_NONE,
-                                 locala, GR_COMBINE_OTHER_NONE, FXFALSE);
-      else
-        grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
-                                 GR_COMBINE_FACTOR_ONE,
-                                 locala, GR_COMBINE_OTHER_NONE, FXFALSE);
-
+      if (ti0->baseLevelInternalFormat == GL_RGB) {
+         alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
+         alphaComb.Factor   = GR_COMBINE_FACTOR_NONE;
+         alphaComb.Other    = GR_COMBINE_OTHER_NONE;
+      } else {
+         alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+         alphaComb.Factor   = GR_COMBINE_FACTOR_ONE;
+         alphaComb.Other    = GR_COMBINE_OTHER_NONE;
+      }
 
-      grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
-                              GR_COMBINE_FACTOR_ONE,
-                              localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
+      colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+      colorComb.Factor   = GR_COMBINE_FACTOR_ONE;
+      colorComb.Other    = GR_COMBINE_OTHER_TEXTURE;
       break;
 
 
@@ -901,45 +975,69 @@ fxSetupTextureDoubleTMU_NoLock(GLcontext * ctx)
         isalpha[tmu0] = (ti0->baseLevelInternalFormat == GL_ALPHA);
         isalpha[tmu1] = (ti1->baseLevelInternalFormat == GL_ALPHA);
 
-        if (isalpha[FX_TMU1])
-           grTexCombine(GR_TMU1,
-                                  GR_COMBINE_FUNCTION_ZERO,
-                                  GR_COMBINE_FACTOR_NONE,
-                                  GR_COMBINE_FUNCTION_LOCAL,
-                                  GR_COMBINE_FACTOR_NONE, FXTRUE, FXFALSE);
-        else
-           grTexCombine(GR_TMU1,
-                                  GR_COMBINE_FUNCTION_LOCAL,
-                                  GR_COMBINE_FACTOR_NONE,
-                                  GR_COMBINE_FUNCTION_LOCAL,
-                                  GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
-
-        if (isalpha[FX_TMU0])
-           grTexCombine(GR_TMU0,
-                                  GR_COMBINE_FUNCTION_SCALE_OTHER,
-                                  GR_COMBINE_FACTOR_ONE,
-                                  GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
-                                  GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE);
-        else
-           grTexCombine(GR_TMU0,
-                                  GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
-                                  GR_COMBINE_FACTOR_ONE,
-                                  GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
-                                  GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE);
-
-        grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
-                                 GR_COMBINE_FACTOR_LOCAL,
-                                 localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
-
-        grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
-                                 GR_COMBINE_FACTOR_LOCAL,
-                                 locala, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
+        if (isalpha[FX_TMU1]) {
+            tex1.FunctionRGB   = GR_COMBINE_FUNCTION_ZERO;
+            tex1.FactorRGB     = GR_COMBINE_FACTOR_NONE;
+            tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
+            tex1.FactorAlpha   = GR_COMBINE_FACTOR_NONE;
+            tex1.InvertRGB     = FXTRUE;
+        } else {
+            tex1.FunctionRGB   = GR_COMBINE_FUNCTION_LOCAL;
+            tex1.FactorRGB     = GR_COMBINE_FACTOR_NONE;
+            tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
+            tex1.FactorAlpha   = GR_COMBINE_FACTOR_NONE;
+         }
+
+        if (isalpha[FX_TMU0]) {
+            tex0.FunctionRGB   = GR_COMBINE_FUNCTION_SCALE_OTHER;
+            tex0.FactorRGB     = GR_COMBINE_FACTOR_ONE;
+            tex0.FunctionAlpha = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
+            tex0.FactorAlpha   = GR_COMBINE_FACTOR_ONE;
+        } else {
+            tex0.FunctionRGB   = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
+            tex0.FactorRGB     = GR_COMBINE_FACTOR_ONE;
+            tex0.FunctionAlpha = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
+            tex0.FactorAlpha   = GR_COMBINE_FACTOR_ONE;
+         }
+
+         colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+         colorComb.Factor   = GR_COMBINE_FACTOR_LOCAL;
+         colorComb.Other    = GR_COMBINE_OTHER_TEXTURE;
+
+         alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+         alphaComb.Factor   = GR_COMBINE_FACTOR_LOCAL;
+         alphaComb.Other    = GR_COMBINE_OTHER_TEXTURE;
         break;
       }
    default:
       fprintf(stderr, "%s: Unexpected dual texture mode encountered\n", __FUNCTION__);
-      break;
+      return;
    }
+
+   grAlphaCombine(alphaComb.Function,
+                  alphaComb.Factor,
+                  alphaComb.Local,
+                  alphaComb.Other,
+                  alphaComb.Invert);
+   grColorCombine(colorComb.Function,
+                  colorComb.Factor,
+                  colorComb.Local,
+                  colorComb.Other,
+                  colorComb.Invert);
+   grTexCombine(GR_TMU0,
+                tex0.FunctionRGB,
+                tex0.FactorRGB,
+                tex0.FunctionAlpha,
+                tex0.FactorAlpha,
+                tex0.InvertRGB,
+                tex0.InvertAlpha);
+   grTexCombine(GR_TMU1,
+                tex1.FunctionRGB,
+                tex1.FactorRGB,
+                tex1.FunctionAlpha,
+                tex1.FactorAlpha,
+                tex1.InvertRGB,
+                tex1.InvertAlpha);
 }
 
 /************************* No Texture ***************************/
@@ -967,12 +1065,16 @@ fxSetupTextureNone_NoLock(GLcontext * ctx)
       localc = GR_COMBINE_LOCAL_CONSTANT;
 
    grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL,
-                           GR_COMBINE_FACTOR_NONE,
-                           locala, GR_COMBINE_OTHER_NONE, FXFALSE);
+                  GR_COMBINE_FACTOR_NONE,
+                  locala,
+                  GR_COMBINE_OTHER_NONE,
+                  FXFALSE);
 
    grColorCombine(GR_COMBINE_FUNCTION_LOCAL,
-                           GR_COMBINE_FACTOR_NONE,
-                           localc, GR_COMBINE_OTHER_NONE, FXFALSE);
+                  GR_COMBINE_FACTOR_NONE,
+                  localc,
+                  GR_COMBINE_OTHER_NONE,
+                  FXFALSE);
 
    fxMesa->lastUnitsMode = FX_UM_NONE;
 }
@@ -1336,25 +1438,6 @@ fxSetupStencil (GLcontext * ctx)
 /**************************** Color Mask SetUp **************************/
 /************************************************************************/
 
-void fxColorMask (fxMesaContext fxMesa, GLboolean enable)
-{
-/* These are used in calls to FX_grColorMask() */
-static const FxBool false4[4] = { FXFALSE, FXFALSE, FXFALSE, FXFALSE };
-static const FxBool true4[4] = { FXTRUE, FXTRUE, FXTRUE, FXTRUE };
-
-   const FxBool *rgba = enable ? true4 : false4;
-
-   if (fxMesa->colDepth != 16) {
-      /* 32bpp mode or 15bpp mode */
-      fxMesa->Glide.grColorMaskExt(rgba[RCOMP], rgba[GCOMP],
-                                   rgba[BCOMP], rgba[ACOMP] && fxMesa->haveHwAlpha);
-   }
-   else {
-      /* 16 bpp mode */
-      grColorMask(rgba[RCOMP] || rgba[GCOMP] || rgba[BCOMP], rgba[ACOMP] && fxMesa->haveHwAlpha);
-   }
-}
-
 void
 fxDDColorMask(GLcontext * ctx,
              GLboolean r, GLboolean g, GLboolean b, GLboolean a)
@@ -1367,16 +1450,24 @@ fxDDColorMask(GLcontext * ctx,
    (void) a;
 }
 
-static void
+void
 fxSetupColorMask(GLcontext * ctx)
 {
    fxMesaContext fxMesa = FX_CONTEXT(ctx);
 
-   if (ctx->Color.DrawBuffer == GL_NONE) {
-      fxColorMask(fxMesa, GL_FALSE);
+   if (fxMesa->colDepth != 16) {
+      /* 32bpp mode or 15bpp mode */
+      fxMesa->Glide.grColorMaskExt(ctx->Color.ColorMask[RCOMP],
+                                   ctx->Color.ColorMask[GCOMP],
+                                   ctx->Color.ColorMask[BCOMP],
+                                   ctx->Color.ColorMask[ACOMP] && fxMesa->haveHwAlpha);
    }
    else {
-      fxColorMask(fxMesa, GL_TRUE);
+      /* 16 bpp mode */
+      grColorMask(ctx->Color.ColorMask[RCOMP] ||
+                  ctx->Color.ColorMask[GCOMP] ||
+                  ctx->Color.ColorMask[BCOMP],
+                  ctx->Color.ColorMask[ACOMP] && fxMesa->haveHwAlpha);
    }
 }
 
@@ -1453,30 +1544,34 @@ fxSetScissorValues(GLcontext * ctx)
 {
    fxMesaContext fxMesa = FX_CONTEXT(ctx);
    int xmin, xmax;
-   int ymin, ymax, check;
+   int ymin, ymax;
 
    if (ctx->Scissor.Enabled) {
       xmin = ctx->Scissor.X;
       xmax = ctx->Scissor.X + ctx->Scissor.Width;
       ymin = ctx->Scissor.Y;
       ymax = ctx->Scissor.Y + ctx->Scissor.Height;
-      check = 1;
+
+      if (xmin < 0)
+         xmin = 0;
+      if (xmax > fxMesa->width)
+         xmax = fxMesa->width;
+      if (ymin < fxMesa->screen_height - fxMesa->height)
+         ymin = fxMesa->screen_height - fxMesa->height;
+      if (ymax > fxMesa->screen_height - 0)
+         ymax = fxMesa->screen_height - 0;
    }
    else {
       xmin = 0;
       ymin = 0;
       xmax = fxMesa->width;
       ymax = fxMesa->height;
-      check = 0;
    }
-   if (xmin < fxMesa->clipMinX)
-      xmin = fxMesa->clipMinX;
-   if (xmax > fxMesa->clipMaxX)
-      xmax = fxMesa->clipMaxX;
-   if (ymin < fxMesa->screen_height - fxMesa->clipMaxY)
-      ymin = fxMesa->screen_height - fxMesa->clipMaxY;
-   if (ymax > fxMesa->screen_height - fxMesa->clipMinY)
-      ymax = fxMesa->screen_height - fxMesa->clipMinY;
+
+   fxMesa->clipMinX = xmin;
+   fxMesa->clipMinY = ymin;
+   fxMesa->clipMaxX = xmax;
+   fxMesa->clipMaxY = ymax;
    grClipWindow(xmin, ymin, xmax, ymax);
 }
 
index 648649c0328206865f18841a5aeafe8cfa9084f0..35b42051068118367612786a2c2ea16b05e1bb40 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fxtexman.c,v 1.17 2003/10/02 17:36:44 brianp Exp $ */
+/* $Id: fxtexman.c,v 1.18 2003/10/09 15:12:21 dborca Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -45,6 +45,7 @@
 #include "fxdrv.h"
 
 int texSwaps = 0;
+static FxU32 texBoundMask;
 
 #define FX_2MB_SPLIT 0x200000
 
@@ -120,30 +121,37 @@ fxTMNewRangeNode(fxMesaContext fxMesa, FxU32 start, FxU32 end)
         fxCloseHardware();
         exit(-1);
       }
-      result->next = NULL;
    }
    result->startAddr = start;
    result->endAddr = end;
    return result;
 }
 
+#if 1
+#define fxTMDeleteRangeNode(fxMesa, range) \
+   do {                                    \
+       range->next = fxMesa->tmPool;       \
+       fxMesa->tmPool = range;             \
+   } while (0);
+#else
 static void
 fxTMDeleteRangeNode(fxMesaContext fxMesa, MemRange * range)
 {
    range->next = fxMesa->tmPool;
    fxMesa->tmPool = range;
 }
+#endif
 
 static void
 fxTMUInit(fxMesaContext fxMesa, int tmu)
 {
    MemRange *tmn, *last;
-   FxU32 start, end, blockstart, blockend, boundary;
+   FxU32 start, end, blockstart, blockend, chunk;
 
    start = grTexMinAddress(tmu);
    end = grTexMaxAddress(tmu);
 
-   boundary = (fxMesa->type >= GR_SSTTYPE_Banshee) ? (end - start) : FX_2MB_SPLIT;
+   chunk = (fxMesa->type >= GR_SSTTYPE_Banshee) ? (end - start) : FX_2MB_SPLIT;
        
    if (fxMesa->verbose) {
       fprintf(stderr, "Voodoo %s configuration:\n",
@@ -152,7 +160,7 @@ fxTMUInit(fxMesaContext fxMesa, int tmu)
              (unsigned int) start);
       fprintf(stderr, "Voodoo  Higher texture memory address (%u)\n",
              (unsigned int) end);
-      fprintf(stderr, "Voodoo  Splitting Texture memory in %luMB blocks:\n", boundary >> 20);
+      fprintf(stderr, "Voodoo  Splitting Texture memory in %luMB blocks:\n", chunk >> 20);
    }
 
    fxMesa->freeTexMem[tmu] = end - start;
@@ -161,16 +169,18 @@ fxTMUInit(fxMesaContext fxMesa, int tmu)
    last = 0;
    blockstart = start;
    while (blockstart < end) {
-      if (blockstart + boundary > end)
+      if (blockstart + chunk > end)
         blockend = end;
       else
-        blockend = blockstart + boundary;
+        blockend = blockstart + chunk;
 
       if (fxMesa->verbose)
         fprintf(stderr, "Voodoo    %07u-%07u\n",
                 (unsigned int) blockstart, (unsigned int) blockend);
 
       tmn = fxTMNewRangeNode(fxMesa, blockstart, blockend);
+      tmn->next = NULL;
+
 
       if (last)
         last->next = tmn;
@@ -178,7 +188,7 @@ fxTMUInit(fxMesaContext fxMesa, int tmu)
         fxMesa->tmFree[tmu] = tmn;
       last = tmn;
 
-      blockstart += boundary;
+      blockstart += chunk;
    }
 }
 
@@ -229,7 +239,6 @@ static void
 fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange * range)
 {
    MemRange *tmp, *prev;
-   FxU32 boundary = (fxMesa->type >= GR_SSTTYPE_Banshee) ? -1 : (FX_2MB_SPLIT - 1);
 
    if (range->startAddr == range->endAddr) {
       fxTMDeleteRangeNode(fxMesa, range);
@@ -252,7 +261,7 @@ fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange * range)
    range->next = tmp;
    if (tmp) {
       if (range->endAddr == tmp->startAddr
-         && tmp->startAddr & boundary) {
+         && tmp->startAddr & texBoundMask) {
         /* Combine */
         tmp->startAddr = range->startAddr;
         fxTMDeleteRangeNode(fxMesa, range);
@@ -261,7 +270,7 @@ fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange * range)
    }
    if (prev) {
       if (prev->endAddr == range->startAddr
-         && range->startAddr & boundary) {
+         && range->startAddr & texBoundMask) {
         /* Combine */
         prev->endAddr = range->endAddr;
         prev->next = range->next;
@@ -312,7 +321,7 @@ fxTMFindOldestObject(fxMesaContext fxMesa, int tmu)
         }
 
          /* examine priority */
-         if (obj->Priority < lowestPriority) {
+         if (tmp->Priority < lowestPriority) {
             lowestPriority = tmp->Priority;
             lowestPriorityObj = tmp;
          }
@@ -320,8 +329,7 @@ fxTMFindOldestObject(fxMesaContext fxMesa, int tmu)
       tmp = tmp->Next;
    }
 
-   if (lowestPriority < 1.0) {
-       ASSERT(lowestPriorityObj);
+   if (lowestPriorityObj != NULL) {
        if (TDFX_DEBUG & VERBOSE_TEXTURE) {
           fprintf(stderr, "fxTMFindOldestObject: %d pri=%f\n", lowestPriorityObj->Name, lowestPriority);
        }
@@ -753,6 +761,8 @@ fxTMInit(fxMesaContext fxMesa)
 
    if (fxMesa->haveTwoTMUs)
       fxTMUInit(fxMesa, FX_TMU1);
+
+   texBoundMask = (fxMesa->type >= GR_SSTTYPE_Banshee) ? -1 : (FX_2MB_SPLIT - 1);
 }
 
 void
index 3c6f51a32640a40989f863332aaec5508e4fb423..4eb536a813c6b2bc828c650f8224a5d778b4ad2e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fxtris.c,v 1.24 2003/10/02 17:36:44 brianp Exp $ */
+/* $Id: fxtris.c,v 1.25 2003/10/09 15:12:21 dborca Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -1097,8 +1097,6 @@ static GLenum reduced_prim[GL_POLYGON+1] = {
  */
 static void fxRasterPrimitive( GLcontext *ctx, GLenum prim )
 {
- extern void fxSetupCull (GLcontext *ctx);
-
    fxMesaContext fxMesa = FX_CONTEXT( ctx );
 
    fxMesa->raster_primitive = prim;
@@ -1176,7 +1174,7 @@ void fxCheckIsInHardware( GLcontext *ctx )
    if (newfallback) {
       if (oldfallback == 0) {
          if (fxMesa->verbose) {
-            fprintf(stderr, "Voodoo ! begin SW 0x08%x %s\n", newfallback, getFallbackString(newfallback));
+            fprintf(stderr, "Voodoo ! begin SW 0x%08x %s\n", newfallback, getFallbackString(newfallback));
          }
         _swsetup_Wakeup( ctx );
       }
@@ -1197,7 +1195,7 @@ void fxCheckIsInHardware( GLcontext *ctx )
         fxChooseVertexState(ctx);
         fxDDChooseRenderState(ctx);
          if (fxMesa->verbose) {
-            fprintf(stderr, "Voodoo ! end SW 0x08%x %s\n", oldfallback, getFallbackString(oldfallback));
+            fprintf(stderr, "Voodoo ! end SW 0x%08x %s\n", oldfallback, getFallbackString(oldfallback));
          }
       }
    }
index da9108b7ba091fbcb7e2257e24dbeb320e2a11c7..857093b5c960323e4a95c5a393994acf2d993c85 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fxvb.c,v 1.19 2003/10/02 17:36:45 brianp Exp $ */
+/* $Id: fxvb.c,v 1.20 2003/10/09 15:12:21 dborca Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -118,7 +118,7 @@ static void interp_extras( GLcontext *ctx,
                 GET_COLOR(VB->ColorPtr[1], dst),
                 GET_COLOR(VB->ColorPtr[1], out),
                 GET_COLOR(VB->ColorPtr[1], in) );
-#if 0 /* [dBorca] leaving disabled for now */
+#if 1 /* [dBorca] GL_EXT_separate_specular_color */
       if (VB->SecondaryColorPtr[1]) {
         INTERP_3CHAN( t,
                    GET_COLOR(VB->SecondaryColorPtr[1], dst),
@@ -143,7 +143,7 @@ static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src )
    if (VB->ColorPtr[1]) {
         COPY_CHAN4( GET_COLOR(VB->ColorPtr[1], dst),
                   GET_COLOR(VB->ColorPtr[1], src) );
-#if 0 /* [dBorca] leaving disabled for now */
+#if 1 /* [dBorca] GL_EXT_separate_specular_color */
         if (VB->SecondaryColorPtr[1]) {
            COPY_CHAN4( GET_COLOR(VB->SecondaryColorPtr[1], dst),
                      GET_COLOR(VB->SecondaryColorPtr[1], src) );
index d1a022ff5e40b471eb3454483fb8d6f899c76e73..306a47c9b30ab59a57d20f47f4c0182c6cf34516 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fxvbtmp.h,v 1.13 2003/10/02 17:36:45 brianp Exp $ */
+/* $Id: fxvbtmp.h,v 1.14 2003/10/09 15:12:21 dborca Exp $ */
 
 /*
  * Mesa 3-D graphics library
  */
 
 
+#define VIEWPORT_X(dst,x) dst = s[0]  * x + s[12]
+#define VIEWPORT_Y(dst,y) dst = s[5]  * y + s[13]
+#define VIEWPORT_Z(dst,z) dst = s[10] * z + s[14]
+
 static void TAG(emit)( GLcontext *ctx,
                       GLuint start, GLuint end,
                       void *dest )
@@ -89,9 +93,9 @@ static void TAG(emit)( GLcontext *ctx,
       if (IND & SETUP_XYZW) {
          if (mask[i] == 0) {
            /* unclipped */
-           v->x   = s[0]  * proj[0][0] + s[12];
-           v->y   = s[5]  * proj[0][1] + s[13];
-           v->ooz = s[10] * proj[0][2] + s[14];
+           VIEWPORT_X(v->x,   proj[0][0]);
+           VIEWPORT_Y(v->y,   proj[0][1]);
+           VIEWPORT_Z(v->ooz, proj[0][2]);
            v->oow = proj[0][3];
          } else {
             /* clipped */
@@ -122,32 +126,24 @@ static void TAG(emit)( GLcontext *ctx,
       }
       if (IND & SETUP_TMU0) {
         GLfloat w = v->oow;
+         v->tmuvtx[0].sow = tc0[0][0] * u0scale * w;
+         v->tmuvtx[0].tow = tc0[0][1] * v0scale * w;
         if (IND & SETUP_PTEX) {
-           v->tmuvtx[0].sow = tc0[0][0] * u0scale * w;
-           v->tmuvtx[0].tow = tc0[0][1] * v0scale * w;
            v->tmuvtx[0].oow = w;
            if (tc0_size == 4) 
-              v->tmuvtx[0].oow = tc0[0][3] * w;
-        } 
-        else {
-           v->tmuvtx[0].sow = tc0[0][0] * u0scale * w;
-           v->tmuvtx[0].tow = tc0[0][1] * v0scale * w;
+              v->tmuvtx[0].oow *= tc0[0][3];
         } 
         tc0 =  (GLfloat (*)[4])((GLubyte *)tc0 +  tc0_stride);
       }
       if (IND & SETUP_TMU1) {
         GLfloat w = v->oow;
+         v->tmuvtx[1].sow = tc1[0][0] * u1scale * w;
+         v->tmuvtx[1].tow = tc1[0][1] * v1scale * w;
         if (IND & SETUP_PTEX) {
-           v->tmuvtx[1].sow = tc1[0][0] * u1scale * w;
-           v->tmuvtx[1].tow = tc1[0][1] * v1scale * w;
            v->tmuvtx[1].oow = w;
            if (tc1_size == 4) 
-              v->tmuvtx[1].oow = tc1[0][3] * w;
+              v->tmuvtx[1].oow *= tc1[0][3];
         } 
-        else {
-           v->tmuvtx[1].sow = tc1[0][0] * u1scale * w;
-           v->tmuvtx[1].tow = tc1[0][1] * v1scale * w;
-        }
         tc1 =  (GLfloat (*)[4])((GLubyte *)tc1 +  tc1_stride);
       } 
    }
@@ -197,9 +193,9 @@ static void TAG(interp)( GLcontext *ctx,
    const GLfloat wout = 1.0F / out->oow;
    const GLfloat win = 1.0F / in->oow;
 
-   dst->x   = s[0]  * dstclip[0] * oow + s[12];        
-   dst->y   = s[5]  * dstclip[1] * oow + s[13];        
-   dst->ooz = s[10] * dstclip[2] * oow + s[14];        
+   VIEWPORT_X(dst->x,   dstclip[0] * oow);
+   VIEWPORT_Y(dst->y,   dstclip[1] * oow);
+   VIEWPORT_Z(dst->ooz, dstclip[2] * oow);
    dst->oow = oow;     
    
    if (IND & SETUP_SNAP) {