mesa/main: use call_once instead of open-coding
[mesa.git] / src / mesa / swrast / s_tritemp.h
index fe19a3363f967b55f2b3ed3c760a1d618dfde733..4dc42a80a729a16594a89c1fb810870a731f6f51 100644 (file)
@@ -1,8 +1,7 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.1
  *
- * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /*
  * This file is #include'd to generate custom triangle rasterizers.
  *
  * The following macros may be defined to indicate what auxillary information
- * must be interplated across the triangle:
- *    INTERP_Z        - if defined, interpolate vertex Z values
- *    INTERP_W        - if defined, interpolate vertex W values
- *    INTERP_FOG      - if defined, interpolate fog values
- *    INTERP_RGB      - if defined, interpolate RGB values
- *    INTERP_ALPHA    - if defined, interpolate Alpha values (req's INTERP_RGB)
- *    INTERP_SPEC     - if defined, interpolate specular RGB values
- *    INTERP_INDEX    - if defined, interpolate color index values
+ * must be interpolated across the triangle:
+ *    INTERP_Z        - if defined, interpolate integer Z values
+ *    INTERP_RGB      - if defined, interpolate integer RGB values
+ *    INTERP_ALPHA    - if defined, interpolate integer Alpha values
  *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
- *                         (fast, simple 2-D texture mapping)
- *    INTERP_TEX      - if defined, interpolate set 0 float STRQ texcoords
- *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
- *    INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
+ *                         (fast, simple 2-D texture mapping, without
+ *                         perspective correction)
+ *    INTERP_ATTRIBS  - if defined, interpolate arbitrary attribs (texcoords,
+ *                         varying vars, etc)  This also causes W to be
+ *                         computed for perspective correction).
  *
  * When one can directly address pixels in the color buffer the following
  * macros can be defined and used to compute pixel addresses during
  *                          Y==0 at bottom of screen and increases upward.
  *
  * Similarly, for direct depth buffer access, this type is used for depth
- * buffer addressing:
+ * buffer addressing (see zRow):
  *    DEPTH_TYPE          - either GLushort or GLuint
  *
  * Optionally, one may provide one-time setup code per triangle:
  *    SETUP_CODE    - code which is to be executed once per triangle
- *    CLEANUP_CODE    - code to execute at end of triangle
  *
  * The following macro MUST be defined:
  *    RENDER_SPAN(span) - code to write a span of pixels.
  * SUB_PIXEL_BITS.
  */
 
-/*
- * ColorTemp is used for intermediate color values.
- */
-#if CHAN_TYPE == GL_FLOAT
-#define ColorTemp GLfloat
-#else
-#define ColorTemp GLint  /* same as GLfixed */
-#endif
+#include "util/u_math.h"
 
-
-/*
- * Walk triangle edges with GLfixed or GLdouble
- */
-#if TRIANGLE_WALK_DOUBLE
-#define GLinterp        GLdouble
-#define InterpToInt(X)  ((GLint) (X))
-#define INTERP_ONE      1.0
-#else
-#define GLinterp        GLfixed
-#define InterpToInt(X)  FixedToInt(X)
-#define INTERP_ONE      FIXED_ONE
+#ifndef MAX_GLUINT
+#define MAX_GLUINT     0xffffffffu
 #endif
 
 
 /*
- * Either loop over all texture units, or just use unit zero.
+ * Some code we unfortunately need to prevent negative interpolated colors.
  */
-#ifdef INTERP_MULTITEX
-#define TEX_UNIT_LOOP(CODE)                                    \
-   {                                                           \
-      GLuint u;                                                        \
-      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {       \
-         if (ctx->Texture._EnabledCoordUnits & (1 << u)) {     \
-            CODE                                               \
-         }                                                     \
-      }                                                                \
-   }
-#define INTERP_TEX
-#elif defined(INTERP_TEX)
-#define TEX_UNIT_LOOP(CODE)                                    \
-   {                                                           \
-      const GLuint u = 0;                                      \
-      CODE                                                     \
-   }
+#ifndef CLAMP_INTERPOLANT
+#define CLAMP_INTERPOLANT(CHANNEL, CHANNELSTEP, LEN)           \
+do {                                                           \
+   GLfixed endVal = span.CHANNEL + (LEN) * span.CHANNELSTEP;   \
+   if (endVal < 0) {                                           \
+      span.CHANNEL -= endVal;                                  \
+   }                                                           \
+   if (span.CHANNEL < 0) {                                     \
+      span.CHANNEL = 0;                                                \
+   }                                                           \
+} while (0)
 #endif
 
 
-static void NAME(GLcontext *ctx, const SWvertex *v0,
+static void NAME(struct gl_context *ctx, const SWvertex *v0,
                                  const SWvertex *v1,
                                  const SWvertex *v2 )
 {
    typedef struct {
       const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
-#if TRIANGLE_WALK_DOUBLE
-      GLdouble dx;     /* X(v1) - X(v0) */
-      GLdouble dy;     /* Y(v1) - Y(v0) */
-      GLdouble dxdy;   /* dx/dy */
-      GLdouble adjy;   /* adjust from v[0]->fy to fsy, scaled */
-      GLdouble fsx;    /* first sample point x coord */
-      GLdouble fsy;
-      GLdouble fx0;    /*X of lower endpoint */
-#else
       GLfloat dx;      /* X(v1) - X(v0) */
       GLfloat dy;      /* Y(v1) - Y(v0) */
       GLfloat dxdy;    /* dx/dy */
@@ -164,10 +128,10 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
       GLfixed fsx;     /* first sample point x coord */
       GLfixed fsy;
       GLfixed fx0;     /* fixed pt X of lower endpoint */
-#endif
       GLint lines;     /* number of lines to be sampled on this edge */
    } EdgeT;
 
+   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
 #ifdef INTERP_Z
    const GLint depthBits = ctx->DrawBuffer->Visual.depthBits;
    const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0;
@@ -178,43 +142,43 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
    GLfloat oneOverArea;
    const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
    GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign;
-#if !TRIANGLE_WALK_DOUBLE
    const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */
-#endif
-   GLinterp vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
+   GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
+
+   SWspan span;
 
-   struct sw_span span;
+   (void) swrast;
 
-   INIT_SPAN(span, GL_POLYGON, 0, 0, 0);
+   INIT_SPAN(span, GL_POLYGON);
+   span.y = 0; /* silence warnings */
 
 #ifdef INTERP_Z
    (void) fixedToDepthShift;
 #endif
 
    /*
-   printf("%s()\n", __FUNCTION__);
-   printf("  %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
-   printf("  %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
-   printf("  %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
-   */
-   /*
-   ASSERT(v0->win[2] >= 0.0);
-   ASSERT(v1->win[2] >= 0.0);
-   ASSERT(v2->win[2] >= 0.0);
+   printf("%s()\n", __func__);
+   printf("  %g, %g, %g\n",
+          v0->attrib[VARYING_SLOT_POS][0],
+          v0->attrib[VARYING_SLOT_POS][1],
+          v0->attrib[VARYING_SLOT_POS][2]);
+   printf("  %g, %g, %g\n",
+          v1->attrib[VARYING_SLOT_POS][0],
+          v1->attrib[VARYING_SLOT_POS][1],
+          v1->attrib[VARYING_SLOT_POS][2]);
+   printf("  %g, %g, %g\n",
+          v2->attrib[VARYING_SLOT_POS][0],
+          v2->attrib[VARYING_SLOT_POS][1],
+          v2->attrib[VARYING_SLOT_POS][2]);
    */
+
    /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
     * And find the order of the 3 vertices along the Y axis.
     */
    {
-#if TRIANGLE_WALK_DOUBLE
-      const GLdouble fy0 = v0->win[1] - 0.5;
-      const GLdouble fy1 = v1->win[1] - 0.5;
-      const GLdouble fy2 = v2->win[1] - 0.5;
-#else
-      const GLfixed fy0 = FloatToFixed(v0->win[1] - 0.5F) & snapMask;
-      const GLfixed fy1 = FloatToFixed(v1->win[1] - 0.5F) & snapMask;
-      const GLfixed fy2 = FloatToFixed(v2->win[1] - 0.5F) & snapMask;
-#endif
+      const GLfixed fy0 = FloatToFixed(v0->attrib[VARYING_SLOT_POS][1] - 0.5F) & snapMask;
+      const GLfixed fy1 = FloatToFixed(v1->attrib[VARYING_SLOT_POS][1] - 0.5F) & snapMask;
+      const GLfixed fy2 = FloatToFixed(v2->attrib[VARYING_SLOT_POS][1] - 0.5F) & snapMask;
       if (fy0 <= fy1) {
          if (fy1 <= fy2) {
             /* y0 <= y1 <= y2 */
@@ -254,15 +218,9 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
       }
 
       /* fixed point X coords */
-#if TRIANGLE_WALK_DOUBLE
-      vMin_fx = vMin->win[0] + 0.5;
-      vMid_fx = vMid->win[0] + 0.5;
-      vMax_fx = vMax->win[0] + 0.5;
-#else
-      vMin_fx = FloatToFixed(vMin->win[0] + 0.5F) & snapMask;
-      vMid_fx = FloatToFixed(vMid->win[0] + 0.5F) & snapMask;
-      vMax_fx = FloatToFixed(vMax->win[0] + 0.5F) & snapMask;
-#endif
+      vMin_fx = FloatToFixed(vMin->attrib[VARYING_SLOT_POS][0] + 0.5F) & snapMask;
+      vMid_fx = FloatToFixed(vMid->attrib[VARYING_SLOT_POS][0] + 0.5F) & snapMask;
+      vMax_fx = FloatToFixed(vMax->attrib[VARYING_SLOT_POS][0] + 0.5F) & snapMask;
    }
 
    /* vertex/edge relationship */
@@ -271,107 +229,62 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
    eBot.v0 = vMin;   eBot.v1 = vMid;
 
    /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
-#if TRIANGLE_WALK_DOUBLE
-   eMaj.dx = vMax_fx - vMin_fx;
-   eMaj.dy = vMax_fy - vMin_fy;
-   eTop.dx = vMax_fx - vMid_fx;
-   eTop.dy = vMax_fy - vMid_fy;
-   eBot.dx = vMid_fx - vMin_fx;
-   eBot.dy = vMid_fy - vMin_fy;
-#else
    eMaj.dx = FixedToFloat(vMax_fx - vMin_fx);
    eMaj.dy = FixedToFloat(vMax_fy - vMin_fy);
    eTop.dx = FixedToFloat(vMax_fx - vMid_fx);
    eTop.dy = FixedToFloat(vMax_fy - vMid_fy);
    eBot.dx = FixedToFloat(vMid_fx - vMin_fx);
    eBot.dy = FixedToFloat(vMid_fy - vMin_fy);
-#endif
 
    /* compute area, oneOverArea and perform backface culling */
    {
-#if TRIANGLE_WALK_DOUBLE
-      const GLdouble area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
-#else
       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
-#endif
-      /* Do backface culling */
-      if (area * bf < 0.0)
+
+      if (util_is_inf_or_nan(area) || area == 0.0F)
          return;
 
-      if (IS_INF_OR_NAN(area) || area == 0.0F)
+      if (area * bf * swrast->_BackfaceCullSign < 0.0F)
          return;
 
       oneOverArea = 1.0F / area;
-   }
 
-   span.facing = ctx->_Facing; /* for 2-sided stencil test */
+      /* 0 = front, 1 = back */
+      span.facing = oneOverArea * bf > 0.0F;
+   }
 
    /* Edge setup.  For a triangle strip these could be reused... */
    {
-#if TRIANGLE_WALK_DOUBLE
-      eMaj.fsy = CEILF(vMin_fy);
-      eMaj.lines = (GLint) CEILF(vMax_fy - eMaj.fsy);
-#else
       eMaj.fsy = FixedCeil(vMin_fy);
       eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy));
-#endif
       if (eMaj.lines > 0) {
          eMaj.dxdy = eMaj.dx / eMaj.dy;
-#if TRIANGLE_WALK_DOUBLE
-         eMaj.adjy = (eMaj.fsy - vMin_fy) * FIXED_SCALE;  /* SCALED! */
-         eMaj.fx0 = vMin_fx;
-         eMaj.fsx = eMaj.fx0 + (eMaj.adjy * eMaj.dxdy) / (GLdouble) FIXED_SCALE;
-#else
          eMaj.fdxdy = SignedFloatToFixed(eMaj.dxdy);
          eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
          eMaj.fx0 = vMin_fx;
          eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * eMaj.dxdy);
-#endif
       }
       else {
          return;  /*CULLED*/
       }
 
-#if TRIANGLE_WALK_DOUBLE
-      eTop.fsy = CEILF(vMid_fy);
-      eTop.lines = (GLint) CEILF(vMax_fy - eTop.fsy);
-#else
       eTop.fsy = FixedCeil(vMid_fy);
       eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy));
-#endif
       if (eTop.lines > 0) {
          eTop.dxdy = eTop.dx / eTop.dy;
-#if TRIANGLE_WALK_DOUBLE
-         eTop.adjy = (eTop.fsy - vMid_fy) * FIXED_SCALE; /* SCALED! */
-         eTop.fx0 = vMid_fx;
-         eTop.fsx = eTop.fx0 + (eTop.adjy * eTop.dxdy) / (GLdouble) FIXED_SCALE;
-#else
          eTop.fdxdy = SignedFloatToFixed(eTop.dxdy);
          eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
          eTop.fx0 = vMid_fx;
          eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * eTop.dxdy);
-#endif
       }
 
-#if TRIANGLE_WALK_DOUBLE
-      eBot.fsy = CEILF(vMin_fy);
-      eBot.lines = (GLint) CEILF(vMid_fy - eBot.fsy);
-#else
       eBot.fsy = FixedCeil(vMin_fy);
       eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy));
-#endif
       if (eBot.lines > 0) {
          eBot.dxdy = eBot.dx / eBot.dy;
-#if TRIANGLE_WALK_DOUBLE
-         eBot.adjy = (eBot.fsy - vMin_fy) * FIXED_SCALE;  /* SCALED! */
-         eBot.fx0 = vMin_fx;
-         eBot.fsx = eBot.fx0 + (eBot.adjy * eBot.dxdy) / (GLdouble) FIXED_SCALE;
-#else
          eBot.fdxdy = SignedFloatToFixed(eBot.dxdy);
          eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
          eBot.fx0 = vMin_fx;
          eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * eBot.dxdy);
-#endif
       }
    }
 
@@ -411,9 +324,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
    {
       GLint scan_from_left_to_right;  /* true if scanning left-to-right */
-#ifdef INTERP_INDEX
-      GLfloat didx, didy;
-#endif
 
       /*
        * Execute user-supplied setup code
@@ -429,204 +339,108 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_Z
       span.interpMask |= SPAN_Z;
       {
-         GLfloat eMaj_dz = vMax->win[2] - vMin->win[2];
-         GLfloat eBot_dz = vMid->win[2] - vMin->win[2];
-         span.dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
-         if (span.dzdx > maxDepth || span.dzdx < -maxDepth) {
+         GLfloat eMaj_dz = vMax->attrib[VARYING_SLOT_POS][2] - vMin->attrib[VARYING_SLOT_POS][2];
+         GLfloat eBot_dz = vMid->attrib[VARYING_SLOT_POS][2] - vMin->attrib[VARYING_SLOT_POS][2];
+         span.attrStepX[VARYING_SLOT_POS][2] = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
+         if (span.attrStepX[VARYING_SLOT_POS][2] > maxDepth ||
+             span.attrStepX[VARYING_SLOT_POS][2] < -maxDepth) {
             /* probably a sliver triangle */
-            span.dzdx = 0.0;
-            span.dzdy = 0.0;
+            span.attrStepX[VARYING_SLOT_POS][2] = 0.0;
+            span.attrStepY[VARYING_SLOT_POS][2] = 0.0;
          }
          else {
-            span.dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
+            span.attrStepY[VARYING_SLOT_POS][2] = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
          }
          if (depthBits <= 16)
-            span.zStep = SignedFloatToFixed(span.dzdx);
+            span.zStep = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_POS][2]);
          else
-            span.zStep = (GLint) span.dzdx;
-      }
-#endif
-#ifdef INTERP_W
-      span.interpMask |= SPAN_W;
-      {
-         const GLfloat eMaj_dw = vMax->win[3] - vMin->win[3];
-         const GLfloat eBot_dw = vMid->win[3] - vMin->win[3];
-         span.dwdx = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw);
-         span.dwdy = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx);
-      }
-#endif
-#ifdef INTERP_FOG
-      span.interpMask |= SPAN_FOG;
-      {
-#  ifdef INTERP_W
-         const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3];
-         const GLfloat eMaj_dfog = vMax->fog * wMax - vMin->fog * wMin;
-         const GLfloat eBot_dfog = vMid->fog * wMid - vMin->fog * wMin;
-#  else
-         const GLfloat eMaj_dfog = vMax->fog - vMin->fog;
-         const GLfloat eBot_dfog = vMid->fog - vMin->fog;
-#  endif
-         span.dfogdx = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
-         span.dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
-         span.fogStep = span.dfogdx;
+            span.zStep = (GLint) span.attrStepX[VARYING_SLOT_POS][2];
       }
 #endif
 #ifdef INTERP_RGB
       span.interpMask |= SPAN_RGBA;
       if (ctx->Light.ShadeModel == GL_SMOOTH) {
-         GLfloat eMaj_dr = (GLfloat) ((ColorTemp) vMax->color[RCOMP] - (ColorTemp) vMin->color[RCOMP]);
-         GLfloat eBot_dr = (GLfloat) ((ColorTemp) vMid->color[RCOMP] - (ColorTemp) vMin->color[RCOMP]);
-         GLfloat eMaj_dg = (GLfloat) ((ColorTemp) vMax->color[GCOMP] - (ColorTemp) vMin->color[GCOMP]);
-         GLfloat eBot_dg = (GLfloat) ((ColorTemp) vMid->color[GCOMP] - (ColorTemp) vMin->color[GCOMP]);
-         GLfloat eMaj_db = (GLfloat) ((ColorTemp) vMax->color[BCOMP] - (ColorTemp) vMin->color[BCOMP]);
-         GLfloat eBot_db = (GLfloat) ((ColorTemp) vMid->color[BCOMP] - (ColorTemp) vMin->color[BCOMP]);
+         GLfloat eMaj_dr = (GLfloat) (vMax->color[RCOMP] - vMin->color[RCOMP]);
+         GLfloat eBot_dr = (GLfloat) (vMid->color[RCOMP] - vMin->color[RCOMP]);
+         GLfloat eMaj_dg = (GLfloat) (vMax->color[GCOMP] - vMin->color[GCOMP]);
+         GLfloat eBot_dg = (GLfloat) (vMid->color[GCOMP] - vMin->color[GCOMP]);
+         GLfloat eMaj_db = (GLfloat) (vMax->color[BCOMP] - vMin->color[BCOMP]);
+         GLfloat eBot_db = (GLfloat) (vMid->color[BCOMP] - vMin->color[BCOMP]);
 #  ifdef INTERP_ALPHA
-         GLfloat eMaj_da = (GLfloat) ((ColorTemp) vMax->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]);
-         GLfloat eBot_da = (GLfloat) ((ColorTemp) vMid->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]);
+         GLfloat eMaj_da = (GLfloat) (vMax->color[ACOMP] - vMin->color[ACOMP]);
+         GLfloat eBot_da = (GLfloat) (vMid->color[ACOMP] - vMin->color[ACOMP]);
 #  endif
-         span.drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
-         span.drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
-         span.dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
-         span.dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
-         span.dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
-         span.dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
-#  if CHAN_TYPE == GL_FLOAT
-         span.redStep   = span.drdx;
-         span.greenStep = span.dgdx;
-         span.blueStep  = span.dbdx;
-#  else
-         span.redStep   = SignedFloatToFixed(span.drdx);
-         span.greenStep = SignedFloatToFixed(span.dgdx);
-         span.blueStep  = SignedFloatToFixed(span.dbdx);
-#  endif /* GL_FLOAT */
+         span.attrStepX[VARYING_SLOT_COL0][0] = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
+         span.attrStepY[VARYING_SLOT_COL0][0] = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
+         span.attrStepX[VARYING_SLOT_COL0][1] = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
+         span.attrStepY[VARYING_SLOT_COL0][1] = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
+         span.attrStepX[VARYING_SLOT_COL0][2] = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
+         span.attrStepY[VARYING_SLOT_COL0][2] = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
+         span.redStep   = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_COL0][0]);
+         span.greenStep = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_COL0][1]);
+         span.blueStep  = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_COL0][2]);
 #  ifdef INTERP_ALPHA
-         span.dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
-         span.dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
-#    if CHAN_TYPE == GL_FLOAT
-         span.alphaStep = span.dadx;
-#    else
-         span.alphaStep = SignedFloatToFixed(span.dadx);
-#    endif /* GL_FLOAT */
+         span.attrStepX[VARYING_SLOT_COL0][3] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
+         span.attrStepY[VARYING_SLOT_COL0][3] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
+         span.alphaStep = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_COL0][3]);
 #  endif /* INTERP_ALPHA */
       }
       else {
-         ASSERT (ctx->Light.ShadeModel == GL_FLAT);
+         assert(ctx->Light.ShadeModel == GL_FLAT);
          span.interpMask |= SPAN_FLAT;
-         span.drdx = span.drdy = 0.0F;
-         span.dgdx = span.dgdy = 0.0F;
-         span.dbdx = span.dbdy = 0.0F;
-#    if CHAN_TYPE == GL_FLOAT
-        span.redStep   = 0.0F;
-        span.greenStep = 0.0F;
-        span.blueStep  = 0.0F;
-#    else
+         span.attrStepX[VARYING_SLOT_COL0][0] = span.attrStepY[VARYING_SLOT_COL0][0] = 0.0F;
+         span.attrStepX[VARYING_SLOT_COL0][1] = span.attrStepY[VARYING_SLOT_COL0][1] = 0.0F;
+         span.attrStepX[VARYING_SLOT_COL0][2] = span.attrStepY[VARYING_SLOT_COL0][2] = 0.0F;
         span.redStep   = 0;
         span.greenStep = 0;
         span.blueStep  = 0;
-#    endif /* GL_FLOAT */
 #  ifdef INTERP_ALPHA
-         span.dadx = span.dady = 0.0F;
-#    if CHAN_TYPE == GL_FLOAT
-        span.alphaStep = 0.0F;
-#    else
+         span.attrStepX[VARYING_SLOT_COL0][3] = span.attrStepY[VARYING_SLOT_COL0][3] = 0.0F;
         span.alphaStep = 0;
-#    endif /* GL_FLOAT */
 #  endif
       }
 #endif /* INTERP_RGB */
-#ifdef INTERP_SPEC
-      span.interpMask |= SPAN_SPEC;
-      if (ctx->Light.ShadeModel == GL_SMOOTH) {
-         GLfloat eMaj_dsr = (GLfloat) ((ColorTemp) vMax->specular[RCOMP] - (ColorTemp) vMin->specular[RCOMP]);
-         GLfloat eBot_dsr = (GLfloat) ((ColorTemp) vMid->specular[RCOMP] - (ColorTemp) vMin->specular[RCOMP]);
-         GLfloat eMaj_dsg = (GLfloat) ((ColorTemp) vMax->specular[GCOMP] - (ColorTemp) vMin->specular[GCOMP]);
-         GLfloat eBot_dsg = (GLfloat) ((ColorTemp) vMid->specular[GCOMP] - (ColorTemp) vMin->specular[GCOMP]);
-         GLfloat eMaj_dsb = (GLfloat) ((ColorTemp) vMax->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]);
-         GLfloat eBot_dsb = (GLfloat) ((ColorTemp) vMid->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]);
-         span.dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr);
-         span.dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx);
-         span.dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg);
-         span.dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx);
-         span.dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb);
-         span.dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx);
-#  if CHAN_TYPE == GL_FLOAT
-         span.specRedStep   = span.dsrdx;
-         span.specGreenStep = span.dsgdx;
-         span.specBlueStep  = span.dsbdx;
-#  else
-         span.specRedStep   = SignedFloatToFixed(span.dsrdx);
-         span.specGreenStep = SignedFloatToFixed(span.dsgdx);
-         span.specBlueStep  = SignedFloatToFixed(span.dsbdx);
-#  endif
-      }
-      else {
-         span.dsrdx = span.dsrdy = 0.0F;
-         span.dsgdx = span.dsgdy = 0.0F;
-         span.dsbdx = span.dsbdy = 0.0F;
-#  if CHAN_TYPE == GL_FLOAT
-        span.specRedStep   = 0.0F;
-        span.specGreenStep = 0.0F;
-        span.specBlueStep  = 0.0F;
-#  else
-        span.specRedStep   = 0;
-        span.specGreenStep = 0;
-        span.specBlueStep  = 0;
-#  endif
-      }
-#endif /* INTERP_SPEC */
-#ifdef INTERP_INDEX
-      span.interpMask |= SPAN_INDEX;
-      if (ctx->Light.ShadeModel == GL_SMOOTH) {
-         GLfloat eMaj_di = vMax->index - vMin->index;
-         GLfloat eBot_di = vMid->index - vMin->index;
-         didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di);
-         didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx);
-         span.indexStep = SignedFloatToFixed(didx);
-      }
-      else {
-         span.interpMask |= SPAN_FLAT;
-         didx = didy = 0.0F;
-         span.indexStep = 0;
-      }
-#endif
 #ifdef INTERP_INT_TEX
-      span.interpMask |= SPAN_INT_TEXTURE;
       {
-         GLfloat eMaj_ds = (vMax->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE;
-         GLfloat eBot_ds = (vMid->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE;
-         GLfloat eMaj_dt = (vMax->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE;
-         GLfloat eBot_dt = (vMid->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE;
-         span.texStepX[0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
-         span.texStepY[0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
-         span.texStepX[0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
-         span.texStepY[0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
-         span.intTexStep[0] = SignedFloatToFixed(span.texStepX[0][0]);
-         span.intTexStep[1] = SignedFloatToFixed(span.texStepX[0][1]);
+         GLfloat eMaj_ds = (vMax->attrib[VARYING_SLOT_TEX0][0] - vMin->attrib[VARYING_SLOT_TEX0][0]) * S_SCALE;
+         GLfloat eBot_ds = (vMid->attrib[VARYING_SLOT_TEX0][0] - vMin->attrib[VARYING_SLOT_TEX0][0]) * S_SCALE;
+         GLfloat eMaj_dt = (vMax->attrib[VARYING_SLOT_TEX0][1] - vMin->attrib[VARYING_SLOT_TEX0][1]) * T_SCALE;
+         GLfloat eBot_dt = (vMid->attrib[VARYING_SLOT_TEX0][1] - vMin->attrib[VARYING_SLOT_TEX0][1]) * T_SCALE;
+         span.attrStepX[VARYING_SLOT_TEX0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
+         span.attrStepY[VARYING_SLOT_TEX0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
+         span.attrStepX[VARYING_SLOT_TEX0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
+         span.attrStepY[VARYING_SLOT_TEX0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
+         span.intTexStep[0] = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_TEX0][0]);
+         span.intTexStep[1] = SignedFloatToFixed(span.attrStepX[VARYING_SLOT_TEX0][1]);
       }
 #endif
-#ifdef INTERP_TEX
-      span.interpMask |= SPAN_TEXTURE;
+#ifdef INTERP_ATTRIBS
       {
-         /* win[3] is 1/W */
-         const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3];
-         TEX_UNIT_LOOP(
-            GLfloat eMaj_ds = vMax->texcoord[u][0] * wMax - vMin->texcoord[u][0] * wMin;
-            GLfloat eBot_ds = vMid->texcoord[u][0] * wMid - vMin->texcoord[u][0] * wMin;
-            GLfloat eMaj_dt = vMax->texcoord[u][1] * wMax - vMin->texcoord[u][1] * wMin;
-            GLfloat eBot_dt = vMid->texcoord[u][1] * wMid - vMin->texcoord[u][1] * wMin;
-            GLfloat eMaj_du = vMax->texcoord[u][2] * wMax - vMin->texcoord[u][2] * wMin;
-            GLfloat eBot_du = vMid->texcoord[u][2] * wMid - vMin->texcoord[u][2] * wMin;
-            GLfloat eMaj_dv = vMax->texcoord[u][3] * wMax - vMin->texcoord[u][3] * wMin;
-            GLfloat eBot_dv = vMid->texcoord[u][3] * wMid - vMin->texcoord[u][3] * wMin;
-            span.texStepX[u][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
-            span.texStepY[u][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
-            span.texStepX[u][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
-            span.texStepY[u][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
-            span.texStepX[u][2] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
-            span.texStepY[u][2] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
-            span.texStepX[u][3] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
-            span.texStepY[u][3] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
-         )
+         /* attrib[VARYING_SLOT_POS][3] is 1/W */
+         const GLfloat wMax = vMax->attrib[VARYING_SLOT_POS][3];
+         const GLfloat wMin = vMin->attrib[VARYING_SLOT_POS][3];
+         const GLfloat wMid = vMid->attrib[VARYING_SLOT_POS][3];
+         {
+            const GLfloat eMaj_dw = wMax - wMin;
+            const GLfloat eBot_dw = wMid - wMin;
+            span.attrStepX[VARYING_SLOT_POS][3] = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw);
+            span.attrStepY[VARYING_SLOT_POS][3] = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx);
+         }
+         ATTRIB_LOOP_BEGIN
+            if (swrast->_InterpMode[attr] == GL_FLAT) {
+               ASSIGN_4V(span.attrStepX[attr], 0.0, 0.0, 0.0, 0.0);
+               ASSIGN_4V(span.attrStepY[attr], 0.0, 0.0, 0.0, 0.0);
+            }
+            else {
+               GLuint c;
+               for (c = 0; c < 4; c++) {
+                  GLfloat eMaj_da = vMax->attrib[attr][c] * wMax - vMin->attrib[attr][c] * wMin;
+                  GLfloat eBot_da = vMid->attrib[attr][c] * wMid - vMin->attrib[attr][c] * wMin;
+                  span.attrStepX[attr][c] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
+                  span.attrStepY[attr][c] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
+               }
+            }
+         ATTRIB_LOOP_END
       }
 #endif
 
@@ -679,9 +493,9 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
       {
          GLint subTriangle;
-         GLinterp fxLeftEdge = 0, fxRightEdge = 0;
-         GLinterp fdxLeftEdge = 0, fdxRightEdge = 0;
-         GLinterp fError = 0, fdError = 0;
+         GLfixed fxLeftEdge = 0, fxRightEdge = 0;
+         GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
+         GLfixed fError = 0, fdError = 0;
 #ifdef PIXEL_ADDRESS
          PIXEL_TYPE *pRow = NULL;
          GLint dPRowOuter = 0, dPRowInner;  /* offset in bytes */
@@ -693,43 +507,25 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
          DEPTH_TYPE *zRow = NULL;
          GLint dZRowOuter = 0, dZRowInner;  /* offset in bytes */
 #  endif
-         GLfixed zLeft = 0, fdzOuter = 0, fdzInner;
-#endif
-#ifdef INTERP_W
-         GLfloat wLeft = 0, dwOuter = 0, dwInner;
-#endif
-#ifdef INTERP_FOG
-         GLfloat fogLeft = 0, dfogOuter = 0, dfogInner;
+         GLuint zLeft = 0;
+         GLfixed fdzOuter = 0, fdzInner;
 #endif
 #ifdef INTERP_RGB
-         ColorTemp rLeft = 0, fdrOuter = 0, fdrInner;
-         ColorTemp gLeft = 0, fdgOuter = 0, fdgInner;
-         ColorTemp bLeft = 0, fdbOuter = 0, fdbInner;
+         GLint rLeft = 0, fdrOuter = 0, fdrInner;
+         GLint gLeft = 0, fdgOuter = 0, fdgInner;
+         GLint bLeft = 0, fdbOuter = 0, fdbInner;
 #endif
 #ifdef INTERP_ALPHA
-         ColorTemp aLeft = 0, fdaOuter = 0, fdaInner;
-#endif
-#ifdef INTERP_SPEC
-         ColorTemp srLeft=0, dsrOuter=0, dsrInner;
-         ColorTemp sgLeft=0, dsgOuter=0, dsgInner;
-         ColorTemp sbLeft=0, dsbOuter=0, dsbInner;
-#endif
-#ifdef INTERP_INDEX
-         GLfixed iLeft=0, diOuter=0, diInner;
+         GLint aLeft = 0, fdaOuter = 0, fdaInner;
 #endif
 #ifdef INTERP_INT_TEX
          GLfixed sLeft=0, dsOuter=0, dsInner;
          GLfixed tLeft=0, dtOuter=0, dtInner;
 #endif
-#ifdef INTERP_TEX
-         GLfloat sLeft[MAX_TEXTURE_COORD_UNITS];
-         GLfloat tLeft[MAX_TEXTURE_COORD_UNITS];
-         GLfloat uLeft[MAX_TEXTURE_COORD_UNITS];
-         GLfloat vLeft[MAX_TEXTURE_COORD_UNITS];
-         GLfloat dsOuter[MAX_TEXTURE_COORD_UNITS], dsInner[MAX_TEXTURE_COORD_UNITS];
-         GLfloat dtOuter[MAX_TEXTURE_COORD_UNITS], dtInner[MAX_TEXTURE_COORD_UNITS];
-         GLfloat duOuter[MAX_TEXTURE_COORD_UNITS], duInner[MAX_TEXTURE_COORD_UNITS];
-         GLfloat dvOuter[MAX_TEXTURE_COORD_UNITS], dvInner[MAX_TEXTURE_COORD_UNITS];
+#ifdef INTERP_ATTRIBS
+         GLfloat wLeft = 0, dwOuter = 0, dwInner;
+         GLfloat attrLeft[VARYING_SLOT_MAX][4];
+         GLfloat daOuter[VARYING_SLOT_MAX][4], daInner[VARYING_SLOT_MAX][4];
 #endif
 
          for (subTriangle=0; subTriangle<=1; subTriangle++) {
@@ -776,30 +572,12 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
             if (setupLeft && eLeft->lines > 0) {
                const SWvertex *vLower = eLeft->v0;
-#if TRIANGLE_WALK_DOUBLE
-               const GLdouble fsy = eLeft->fsy;
-               const GLdouble fsx = eLeft->fsx;
-               const GLdouble fx = CEILF(fsx);
-               const GLdouble adjx = (fx - eLeft->fx0) * FIXED_SCALE;  /* SCALED! */
-#else
                const GLfixed fsy = eLeft->fsy;
                const GLfixed fsx = eLeft->fsx;  /* no fractional part */
                const GLfixed fx = FixedCeil(fsx);  /* no fractional part */
-               const GLfixed adjx = (GLinterp) (fx - eLeft->fx0); /* SCALED! */
-#endif
-               const GLinterp adjy = (GLinterp) eLeft->adjy;      /* SCALED! */
+               const GLfixed adjx = (GLfixed) (fx - eLeft->fx0); /* SCALED! */
+               const GLfixed adjy = (GLfixed) eLeft->adjy;      /* SCALED! */
                GLint idxOuter;
-#if TRIANGLE_WALK_DOUBLE
-               GLdouble dxOuter;
-
-               fError = fx - fsx - 1.0;
-               fxLeftEdge = fsx;
-               fdxLeftEdge = eLeft->dxdy;
-               dxOuter = FLOORF(fdxLeftEdge);
-               fdError = dxOuter - fdxLeftEdge + 1.0;
-               idxOuter = (GLint) dxOuter;
-               span.y = (GLint) fsy;
-#else
                GLfloat dxOuter;
                GLfixed fdxOuter;
 
@@ -811,7 +589,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
                idxOuter = FixedToInt(fdxOuter);
                dxOuter = (GLfloat) idxOuter;
                span.y = FixedToInt(fsy);
-#endif
 
                /* silence warnings on some compilers */
                (void) dxOuter;
@@ -821,7 +598,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
 #ifdef PIXEL_ADDRESS
                {
-                  pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(InterpToInt(fxLeftEdge), span.y);
+                  pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(FixedToInt(fxLeftEdge), span.y);
                   dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE);
                   /* negative because Y=0 at bottom and increases upward */
                }
@@ -838,178 +615,122 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
 #ifdef INTERP_Z
                {
-                  GLfloat z0 = vLower->win[2];
+                  GLfloat z0 = vLower->attrib[VARYING_SLOT_POS][2];
                   if (depthBits <= 16) {
                      /* interpolate fixed-pt values */
-                     GLfloat tmp = (z0 * FIXED_SCALE + span.dzdx * adjx + span.dzdy * adjy) + FIXED_HALF;
+                     GLfloat tmp = (z0 * FIXED_SCALE
+                                    + span.attrStepX[VARYING_SLOT_POS][2] * adjx
+                                    + span.attrStepY[VARYING_SLOT_POS][2] * adjy) + FIXED_HALF;
                      if (tmp < MAX_GLUINT / 2)
                         zLeft = (GLfixed) tmp;
                      else
                         zLeft = MAX_GLUINT / 2;
-                     fdzOuter = SignedFloatToFixed(span.dzdy + dxOuter * span.dzdx);
+                     fdzOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_POS][2] +
+                                                   dxOuter * span.attrStepX[VARYING_SLOT_POS][2]);
                   }
                   else {
-                     /* interpolate depth values exactly */
-                     zLeft = (GLint) (z0 + span.dzdx * FixedToFloat(adjx) + span.dzdy * FixedToFloat(adjy));
-                     fdzOuter = (GLint) (span.dzdy + dxOuter * span.dzdx);
+                     /* interpolate depth values w/out scaling */
+                     zLeft = (GLuint) (z0 + span.attrStepX[VARYING_SLOT_POS][2] * FixedToFloat(adjx)
+                                          + span.attrStepY[VARYING_SLOT_POS][2] * FixedToFloat(adjy));
+                     fdzOuter = (GLint) (span.attrStepY[VARYING_SLOT_POS][2] +
+                                         dxOuter * span.attrStepX[VARYING_SLOT_POS][2]);
                   }
 #  ifdef DEPTH_TYPE
                   zRow = (DEPTH_TYPE *)
-                    zrb->GetPointer(ctx, zrb, InterpToInt(fxLeftEdge), span.y);
+                    _swrast_pixel_address(zrb, FixedToInt(fxLeftEdge), span.y);
                   dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE);
 #  endif
                }
 #endif
-#ifdef INTERP_W
-               wLeft = vLower->win[3] + (span.dwdx * adjx + span.dwdy * adjy) * (1.0F/FIXED_SCALE);
-               dwOuter = span.dwdy + dxOuter * span.dwdx;
-#endif
-#ifdef INTERP_FOG
-#  ifdef INTERP_W
-               fogLeft = vLower->fog * vLower->win[3] + (span.dfogdx * adjx + span.dfogdy * adjy) * (1.0F/FIXED_SCALE);
-#  else
-               fogLeft = vLower->fog + (span.dfogdx * adjx + span.dfogdy * adjy) * (1.0F/FIXED_SCALE);
-#  endif
-               dfogOuter = span.dfogdy + dxOuter * span.dfogdx;
-#endif
 #ifdef INTERP_RGB
                if (ctx->Light.ShadeModel == GL_SMOOTH) {
-#  if CHAN_TYPE == GL_FLOAT
-                  rLeft = vLower->color[RCOMP] + (span.drdx * adjx + span.drdy * adjy) * (1.0F / FIXED_SCALE);
-                  gLeft = vLower->color[GCOMP] + (span.dgdx * adjx + span.dgdy * adjy) * (1.0F / FIXED_SCALE);
-                  bLeft = vLower->color[BCOMP] + (span.dbdx * adjx + span.dbdy * adjy) * (1.0F / FIXED_SCALE);
-                  fdrOuter = span.drdy + dxOuter * span.drdx;
-                  fdgOuter = span.dgdy + dxOuter * span.dgdx;
-                  fdbOuter = span.dbdy + dxOuter * span.dbdx;
-#  else
-                  rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP]) + span.drdx * adjx + span.drdy * adjy) + FIXED_HALF;
-                  gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP]) + span.dgdx * adjx + span.dgdy * adjy) + FIXED_HALF;
-                  bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP]) + span.dbdx * adjx + span.dbdy * adjy) + FIXED_HALF;
-                  fdrOuter = SignedFloatToFixed(span.drdy + dxOuter * span.drdx);
-                  fdgOuter = SignedFloatToFixed(span.dgdy + dxOuter * span.dgdx);
-                  fdbOuter = SignedFloatToFixed(span.dbdy + dxOuter * span.dbdx);
-#  endif
+                  rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP])
+                                  + span.attrStepX[VARYING_SLOT_COL0][0] * adjx
+                                  + span.attrStepY[VARYING_SLOT_COL0][0] * adjy) + FIXED_HALF;
+                  gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP])
+                                  + span.attrStepX[VARYING_SLOT_COL0][1] * adjx
+                                  + span.attrStepY[VARYING_SLOT_COL0][1] * adjy) + FIXED_HALF;
+                  bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP])
+                                  + span.attrStepX[VARYING_SLOT_COL0][2] * adjx
+                                  + span.attrStepY[VARYING_SLOT_COL0][2] * adjy) + FIXED_HALF;
+                  fdrOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_COL0][0]
+                                                + dxOuter * span.attrStepX[VARYING_SLOT_COL0][0]);
+                  fdgOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_COL0][1]
+                                                + dxOuter * span.attrStepX[VARYING_SLOT_COL0][1]);
+                  fdbOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_COL0][2]
+                                                + dxOuter * span.attrStepX[VARYING_SLOT_COL0][2]);
 #  ifdef INTERP_ALPHA
-#    if CHAN_TYPE == GL_FLOAT
-                  aLeft = vLower->color[ACOMP] + (span.dadx * adjx + span.dady * adjy) * (1.0F / FIXED_SCALE);
-                  fdaOuter = span.dady + dxOuter * span.dadx;
-#    else
-                  aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP]) + span.dadx * adjx + span.dady * adjy) + FIXED_HALF;
-                  fdaOuter = SignedFloatToFixed(span.dady + dxOuter * span.dadx);
-#    endif
+                  aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP])
+                                  + span.attrStepX[VARYING_SLOT_COL0][3] * adjx
+                                  + span.attrStepY[VARYING_SLOT_COL0][3] * adjy) + FIXED_HALF;
+                  fdaOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_COL0][3]
+                                                + dxOuter * span.attrStepX[VARYING_SLOT_COL0][3]);
 #  endif
                }
                else {
-                  ASSERT (ctx->Light.ShadeModel == GL_FLAT);
-#  if CHAN_TYPE == GL_FLOAT
-                  rLeft = v2->color[RCOMP];
-                  gLeft = v2->color[GCOMP];
-                  bLeft = v2->color[BCOMP];
-                  fdrOuter = fdgOuter = fdbOuter = 0.0F;
-#  else
+                  assert(ctx->Light.ShadeModel == GL_FLAT);
                   rLeft = ChanToFixed(v2->color[RCOMP]);
                   gLeft = ChanToFixed(v2->color[GCOMP]);
                   bLeft = ChanToFixed(v2->color[BCOMP]);
                   fdrOuter = fdgOuter = fdbOuter = 0;
-#  endif
 #  ifdef INTERP_ALPHA
-#    if CHAN_TYPE == GL_FLOAT
-                  aLeft = v2->color[ACOMP];
-                  fdaOuter = 0.0F;
-#    else
                   aLeft = ChanToFixed(v2->color[ACOMP]);
                   fdaOuter = 0;
-#    endif
 #  endif
                }
-#endif
+#endif /* INTERP_RGB */
 
-#ifdef INTERP_SPEC
-               if (ctx->Light.ShadeModel == GL_SMOOTH) {
-#  if CHAN_TYPE == GL_FLOAT
-                  srLeft = vLower->specular[RCOMP] + (span.dsrdx * adjx + span.dsrdy * adjy) * (1.0F / FIXED_SCALE);
-                  sgLeft = vLower->specular[GCOMP] + (span.dsgdx * adjx + span.dsgdy * adjy) * (1.0F / FIXED_SCALE);
-                  sbLeft = vLower->specular[BCOMP] + (span.dsbdx * adjx + span.dsbdy * adjy) * (1.0F / FIXED_SCALE);
-                  dsrOuter = span.dsrdy + dxOuter * span.dsrdx;
-                  dsgOuter = span.dsgdy + dxOuter * span.dsgdx;
-                  dsbOuter = span.dsbdy + dxOuter * span.dsbdx;
-#  else
-                  srLeft = (GLfixed) (ChanToFixed(vLower->specular[RCOMP]) + span.dsrdx * adjx + span.dsrdy * adjy) + FIXED_HALF;
-                  sgLeft = (GLfixed) (ChanToFixed(vLower->specular[GCOMP]) + span.dsgdx * adjx + span.dsgdy * adjy) + FIXED_HALF;
-                  sbLeft = (GLfixed) (ChanToFixed(vLower->specular[BCOMP]) + span.dsbdx * adjx + span.dsbdy * adjy) + FIXED_HALF;
-                  dsrOuter = SignedFloatToFixed(span.dsrdy + dxOuter * span.dsrdx);
-                  dsgOuter = SignedFloatToFixed(span.dsgdy + dxOuter * span.dsgdx);
-                  dsbOuter = SignedFloatToFixed(span.dsbdy + dxOuter * span.dsbdx);
-#  endif
-               }
-               else {
-#if  CHAN_TYPE == GL_FLOAT
-                  srLeft = v2->specular[RCOMP];
-                  sgLeft = v2->specular[GCOMP];
-                  sbLeft = v2->specular[BCOMP];
-                  dsrOuter = dsgOuter = dsbOuter = 0.0F;
-#  else
-                  srLeft = ChanToFixed(v2->specular[RCOMP]);
-                  sgLeft = ChanToFixed(v2->specular[GCOMP]);
-                  sbLeft = ChanToFixed(v2->specular[BCOMP]);
-                  dsrOuter = dsgOuter = dsbOuter = 0;
-#  endif
-               }
-#endif
 
-#ifdef INTERP_INDEX
-               if (ctx->Light.ShadeModel == GL_SMOOTH) {
-                  iLeft = (GLfixed)(vLower->index * FIXED_SCALE
-                                 + didx * adjx + didy * adjy) + FIXED_HALF;
-                  diOuter = SignedFloatToFixed(didy + dxOuter * didx);
-               }
-               else {
-                  iLeft = FloatToFixed(v2->index);
-                  diOuter = 0;
-               }
-#endif
 #ifdef INTERP_INT_TEX
                {
                   GLfloat s0, t0;
-                  s0 = vLower->texcoord[0][0] * S_SCALE;
-                  sLeft = (GLfixed)(s0 * FIXED_SCALE + span.texStepX[0][0] * adjx
-                                 + span.texStepY[0][0] * adjy) + FIXED_HALF;
-                  dsOuter = SignedFloatToFixed(span.texStepY[0][0] + dxOuter * span.texStepX[0][0]);
-
-                  t0 = vLower->texcoord[0][1] * T_SCALE;
-                  tLeft = (GLfixed)(t0 * FIXED_SCALE + span.texStepX[0][1] * adjx
-                                 + span.texStepY[0][1] * adjy) + FIXED_HALF;
-                  dtOuter = SignedFloatToFixed(span.texStepY[0][1] + dxOuter * span.texStepX[0][1]);
+                  s0 = vLower->attrib[VARYING_SLOT_TEX0][0] * S_SCALE;
+                  sLeft = (GLfixed)(s0 * FIXED_SCALE + span.attrStepX[VARYING_SLOT_TEX0][0] * adjx
+                                 + span.attrStepY[VARYING_SLOT_TEX0][0] * adjy) + FIXED_HALF;
+                  dsOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_TEX0][0]
+                                               + dxOuter * span.attrStepX[VARYING_SLOT_TEX0][0]);
+
+                  t0 = vLower->attrib[VARYING_SLOT_TEX0][1] * T_SCALE;
+                  tLeft = (GLfixed)(t0 * FIXED_SCALE + span.attrStepX[VARYING_SLOT_TEX0][1] * adjx
+                                 + span.attrStepY[VARYING_SLOT_TEX0][1] * adjy) + FIXED_HALF;
+                  dtOuter = SignedFloatToFixed(span.attrStepY[VARYING_SLOT_TEX0][1]
+                                               + dxOuter * span.attrStepX[VARYING_SLOT_TEX0][1]);
                }
 #endif
-#ifdef INTERP_TEX
-               TEX_UNIT_LOOP(
-                  const GLfloat invW = vLower->win[3];
-                  const GLfloat s0 = vLower->texcoord[u][0] * invW;
-                  const GLfloat t0 = vLower->texcoord[u][1] * invW;
-                  const GLfloat u0 = vLower->texcoord[u][2] * invW;
-                  const GLfloat v0 = vLower->texcoord[u][3] * invW;
-                  sLeft[u] = s0 + (span.texStepX[u][0] * adjx + span.texStepY[u][0] * adjy) * (1.0F/FIXED_SCALE);
-                  tLeft[u] = t0 + (span.texStepX[u][1] * adjx + span.texStepY[u][1] * adjy) * (1.0F/FIXED_SCALE);
-                  uLeft[u] = u0 + (span.texStepX[u][2] * adjx + span.texStepY[u][2] * adjy) * (1.0F/FIXED_SCALE);
-                  vLeft[u] = v0 + (span.texStepX[u][3] * adjx + span.texStepY[u][3] * adjy) * (1.0F/FIXED_SCALE);
-                  dsOuter[u] = span.texStepY[u][0] + dxOuter * span.texStepX[u][0];
-                  dtOuter[u] = span.texStepY[u][1] + dxOuter * span.texStepX[u][1];
-                  duOuter[u] = span.texStepY[u][2] + dxOuter * span.texStepX[u][2];
-                  dvOuter[u] = span.texStepY[u][3] + dxOuter * span.texStepX[u][3];
-               )
+#ifdef INTERP_ATTRIBS
+               {
+                  const GLuint attr = VARYING_SLOT_POS;
+                  wLeft = vLower->attrib[VARYING_SLOT_POS][3]
+                        + (span.attrStepX[attr][3] * adjx
+                           + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE);
+                  dwOuter = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3];
+               }
+               ATTRIB_LOOP_BEGIN
+                  const GLfloat invW = vLower->attrib[VARYING_SLOT_POS][3];
+                  if (swrast->_InterpMode[attr] == GL_FLAT) {
+                     GLuint c;
+                     for (c = 0; c < 4; c++) {
+                        attrLeft[attr][c] = v2->attrib[attr][c] * invW;
+                        daOuter[attr][c] = 0.0;
+                     }
+                  }
+                  else {
+                     GLuint c;
+                     for (c = 0; c < 4; c++) {
+                        const GLfloat a = vLower->attrib[attr][c] * invW;
+                        attrLeft[attr][c] = a + (  span.attrStepX[attr][c] * adjx
+                                                 + span.attrStepY[attr][c] * adjy) * (1.0F/FIXED_SCALE);
+                        daOuter[attr][c] = span.attrStepY[attr][c] + dxOuter * span.attrStepX[attr][c];
+                     }
+                  }
+               ATTRIB_LOOP_END
 #endif
             } /*if setupLeft*/
 
 
             if (setupRight && eRight->lines>0) {
-#if TRIANGLE_WALK_DOUBLE
-               fxRightEdge = eRight->fsx;
-               fdxRightEdge = eRight->dxdy;
-#else
                fxRightEdge = eRight->fsx - FIXED_EPSILON;
                fdxRightEdge = eRight->fdxdy;
-#endif
             }
 
             if (lines==0) {
@@ -1027,12 +748,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #  endif
             fdzInner = fdzOuter + span.zStep;
 #endif
-#ifdef INTERP_W
-            dwInner = dwOuter + span.dwdx;
-#endif
-#ifdef INTERP_FOG
-            dfogInner = dfogOuter + span.dfogdx;
-#endif
 #ifdef INTERP_RGB
             fdrInner = fdrOuter + span.redStep;
             fdgInner = fdgOuter + span.greenStep;
@@ -1041,32 +756,25 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_ALPHA
             fdaInner = fdaOuter + span.alphaStep;
 #endif
-#ifdef INTERP_SPEC
-            dsrInner = dsrOuter + span.specRedStep;
-            dsgInner = dsgOuter + span.specGreenStep;
-            dsbInner = dsbOuter + span.specBlueStep;
-#endif
-#ifdef INTERP_INDEX
-            diInner = diOuter + span.indexStep;
-#endif
 #ifdef INTERP_INT_TEX
             dsInner = dsOuter + span.intTexStep[0];
             dtInner = dtOuter + span.intTexStep[1];
 #endif
-#ifdef INTERP_TEX
-            TEX_UNIT_LOOP(
-               dsInner[u] = dsOuter[u] + span.texStepX[u][0];
-               dtInner[u] = dtOuter[u] + span.texStepX[u][1];
-               duInner[u] = duOuter[u] + span.texStepX[u][2];
-               dvInner[u] = dvOuter[u] + span.texStepX[u][3];
-            )
+#ifdef INTERP_ATTRIBS
+            dwInner = dwOuter + span.attrStepX[VARYING_SLOT_POS][3];
+            ATTRIB_LOOP_BEGIN
+               GLuint c;
+               for (c = 0; c < 4; c++) {
+                  daInner[attr][c] = daOuter[attr][c] + span.attrStepX[attr][c];
+               }
+            ATTRIB_LOOP_END
 #endif
 
             while (lines > 0) {
                /* initialize the span interpolants to the leftmost value */
                /* ff = fixed-pt fragment */
-               const GLint right = InterpToInt(fxRightEdge);
-               span.x = InterpToInt(fxLeftEdge);
+               const GLint right = FixedToInt(fxRightEdge);
+               span.x = FixedToInt(fxLeftEdge);
                if (right <= span.x)
                   span.end = 0;
                else
@@ -1075,12 +783,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_Z
                span.z = zLeft;
 #endif
-#ifdef INTERP_W
-               span.w = wLeft;
-#endif
-#ifdef INTERP_FOG
-               span.fog = fogLeft;
-#endif
 #ifdef INTERP_RGB
                span.red = rLeft;
                span.green = gLeft;
@@ -1089,97 +791,39 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_ALPHA
                span.alpha = aLeft;
 #endif
-#ifdef INTERP_SPEC
-               span.specRed = srLeft;
-               span.specGreen = sgLeft;
-               span.specBlue = sbLeft;
-#endif
-#ifdef INTERP_INDEX
-               span.index = iLeft;
-#endif
 #ifdef INTERP_INT_TEX
                span.intTex[0] = sLeft;
                span.intTex[1] = tLeft;
 #endif
 
-#ifdef INTERP_TEX
-               TEX_UNIT_LOOP(
-                  span.tex[u][0] = sLeft[u];
-                  span.tex[u][1] = tLeft[u];
-                  span.tex[u][2] = uLeft[u];
-                  span.tex[u][3] = vLeft[u];
-               )
+#ifdef INTERP_ATTRIBS
+               span.attrStart[VARYING_SLOT_POS][3] = wLeft;
+               ATTRIB_LOOP_BEGIN
+                  GLuint c;
+                  for (c = 0; c < 4; c++) {
+                     span.attrStart[attr][c] = attrLeft[attr][c];
+                  }
+               ATTRIB_LOOP_END
 #endif
 
-               if (span.end > 1) {
-                  /* Under rare circumstances, we might have to fudge the
-                   * colors. XXX does this really happen anymore???
-                   */
+               /* This is where we actually generate fragments */
+               /* XXX the test for span.y > 0 _shouldn't_ be needed but
+                * it fixes a problem on 64-bit Opterons (bug 4842).
+                */
+               if (span.end > 0 && span.y >= 0) {
                   const GLint len = span.end - 1;
                   (void) len;
 #ifdef INTERP_RGB
-                  {
-                     GLfixed ffrend = span.red + len * span.redStep;
-                     GLfixed ffgend = span.green + len * span.greenStep;
-                     GLfixed ffbend = span.blue + len * span.blueStep;
-                     if (ffrend < 0) {
-                        span.red -= ffrend;
-                        if (span.red < 0)
-                           span.red = 0;
-                     }
-                     if (ffgend < 0) {
-                        span.green -= ffgend;
-                        if (span.green < 0)
-                           span.green = 0;
-                     }
-                     if (ffbend < 0) {
-                        span.blue -= ffbend;
-                        if (span.blue < 0)
-                           span.blue = 0;
-                     }
-                  }
+                  CLAMP_INTERPOLANT(red, redStep, len);
+                  CLAMP_INTERPOLANT(green, greenStep, len);
+                  CLAMP_INTERPOLANT(blue, blueStep, len);
 #endif
 #ifdef INTERP_ALPHA
-                  {
-                     GLfixed ffaend = span.alpha + len * span.alphaStep;
-                     if (ffaend < 0) {
-                        span.alpha -= ffaend;
-                        if (span.alpha < 0)
-                           span.alpha = 0;
-                     }
-                  }
+                  CLAMP_INTERPOLANT(alpha, alphaStep, len);
 #endif
-#ifdef INTERP_SPEC
                   {
-                     GLfixed ffsrend = span.specRed + len * span.specRedStep;
-                     GLfixed ffsgend = span.specGreen + len * span.specGreenStep;
-                     GLfixed ffsbend = span.specBlue + len * span.specBlueStep;
-                     if (ffsrend < 0) {
-                        span.specRed -= ffsrend;
-                        if (span.specRed < 0)
-                           span.specRed = 0;
-                     }
-                     if (ffsgend < 0) {
-                        span.specGreen -= ffsgend;
-                        if (span.specGreen < 0)
-                           span.specGreen = 0;
-                     }
-                     if (ffsbend < 0) {
-                        span.specBlue -= ffsbend;
-                        if (span.specBlue < 0)
-                           span.specBlue = 0;
-                     }
+                     RENDER_SPAN( span );
                   }
-#endif
-#ifdef INTERP_INDEX
-                  if (span.index < 0)
-                     span.index = 0;
-#endif
-               } /* span.end > 1 */
-
-               /* This is where we actually generate fragments */
-               if (span.end > 0) {
-                  RENDER_SPAN( span );
                }
 
                /*
@@ -1196,7 +840,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
                fError += fdError;
                if (fError >= 0) {
-                  fError -= INTERP_ONE;
+                  fError -= FIXED_ONE;
 
 #ifdef PIXEL_ADDRESS
                   pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter);
@@ -1207,12 +851,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #  endif
                   zLeft += fdzOuter;
 #endif
-#ifdef INTERP_W
-                  wLeft += dwOuter;
-#endif
-#ifdef INTERP_FOG
-                  fogLeft += dfogOuter;
-#endif
 #ifdef INTERP_RGB
                   rLeft += fdrOuter;
                   gLeft += fdgOuter;
@@ -1221,25 +859,18 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_ALPHA
                   aLeft += fdaOuter;
 #endif
-#ifdef INTERP_SPEC
-                  srLeft += dsrOuter;
-                  sgLeft += dsgOuter;
-                  sbLeft += dsbOuter;
-#endif
-#ifdef INTERP_INDEX
-                  iLeft += diOuter;
-#endif
 #ifdef INTERP_INT_TEX
                   sLeft += dsOuter;
                   tLeft += dtOuter;
 #endif
-#ifdef INTERP_TEX
-                  TEX_UNIT_LOOP(
-                     sLeft[u] += dsOuter[u];
-                     tLeft[u] += dtOuter[u];
-                     uLeft[u] += duOuter[u];
-                     vLeft[u] += dvOuter[u];
-                  )
+#ifdef INTERP_ATTRIBS
+                  wLeft += dwOuter;
+                  ATTRIB_LOOP_BEGIN
+                     GLuint c;
+                     for (c = 0; c < 4; c++) {
+                        attrLeft[attr][c] += daOuter[attr][c];
+                     }
+                  ATTRIB_LOOP_END
 #endif
                }
                else {
@@ -1252,12 +883,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #  endif
                   zLeft += fdzInner;
 #endif
-#ifdef INTERP_W
-                  wLeft += dwInner;
-#endif
-#ifdef INTERP_FOG
-                  fogLeft += dfogInner;
-#endif
 #ifdef INTERP_RGB
                   rLeft += fdrInner;
                   gLeft += fdgInner;
@@ -1266,25 +891,18 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_ALPHA
                   aLeft += fdaInner;
 #endif
-#ifdef INTERP_SPEC
-                  srLeft += dsrInner;
-                  sgLeft += dsgInner;
-                  sbLeft += dsbInner;
-#endif
-#ifdef INTERP_INDEX
-                  iLeft += diInner;
-#endif
 #ifdef INTERP_INT_TEX
                   sLeft += dsInner;
                   tLeft += dtInner;
 #endif
-#ifdef INTERP_TEX
-                  TEX_UNIT_LOOP(
-                     sLeft[u] += dsInner[u];
-                     tLeft[u] += dtInner[u];
-                     uLeft[u] += duInner[u];
-                     vLeft[u] += dvInner[u];
-                  )
+#ifdef INTERP_ATTRIBS
+                  wLeft += dwInner;
+                  ATTRIB_LOOP_BEGIN
+                     GLuint c;
+                     for (c = 0; c < 4; c++) {
+                        attrLeft[attr][c] += daInner[attr][c];
+                     }
+                  ATTRIB_LOOP_END
 #endif
                }
             } /*while lines>0*/
@@ -1292,14 +910,10 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
          } /* for subTriangle */
 
       }
-#ifdef CLEANUP_CODE
-      CLEANUP_CODE
-#endif
    }
 }
 
 #undef SETUP_CODE
-#undef CLEANUP_CODE
 #undef RENDER_SPAN
 
 #undef PIXEL_TYPE
@@ -1308,24 +922,14 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #undef DEPTH_TYPE
 
 #undef INTERP_Z
-#undef INTERP_W
-#undef INTERP_FOG
 #undef INTERP_RGB
 #undef INTERP_ALPHA
-#undef INTERP_SPEC
-#undef INTERP_INDEX
 #undef INTERP_INT_TEX
-#undef INTERP_TEX
-#undef INTERP_MULTITEX
-#undef TEX_UNIT_LOOP
+#undef INTERP_ATTRIBS
 
 #undef S_SCALE
 #undef T_SCALE
 
 #undef FixedToDepth
-#undef ColorTemp
-#undef GLinterp
-#undef InterpToInt
-#undef INTERP_ONE
 
 #undef NAME