Fix typo
[mesa.git] / src / mesa / swrast / s_triangle.c
index 267a0f2c8e50e20901c527898c615dfe7b70a210..2baa2b5d29a337890d659aebc3f4982dec959696 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: s_triangle.c,v 1.2 2000/11/05 18:24:41 keithw Exp $ */
+/* $Id: s_triangle.c,v 1.15 2001/03/03 20:33:30 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
  * Version:  3.5
  * 
- * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2001  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"),
@@ -34,6 +34,7 @@
 
 #include "glheader.h"
 #include "context.h"
+#include "colormac.h"
 #include "macros.h"
 #include "mem.h"
 #include "mmath.h"
 #include "s_span.h"
 #include "s_triangle.h"
  
-GLboolean gl_cull_triangle( GLcontext *ctx,
-                           SWvertex *v0, 
-                           SWvertex *v1, 
-                           SWvertex *v2 )
+GLboolean _mesa_cull_triangle( GLcontext *ctx,
+                           const SWvertex *v0, 
+                           const SWvertex *v1, 
+                           const SWvertex *v2 )
 {
    GLfloat ex = v1->win[0] - v0->win[0];
    GLfloat ey = v1->win[1] - v0->win[1];
@@ -58,7 +59,7 @@ GLboolean gl_cull_triangle( GLcontext *ctx,
    GLfloat fy = v2->win[1] - v0->win[1];
    GLfloat c = ex*fy-ey*fx;
 
-   if (c * ctx->_backface_sign > 0)
+   if (c * SWRAST_CONTEXT(ctx)->_backface_sign > 0)
       return 0;
    
    return 1;
@@ -69,17 +70,11 @@ GLboolean gl_cull_triangle( GLcontext *ctx,
  * Render a flat-shaded color index triangle.
  */
 static void flat_ci_triangle( GLcontext *ctx,
-                             SWvertex *v0, 
-                             SWvertex *v1, 
-                             SWvertex *v2 )
+                             const SWvertex *v0, 
+                             const SWvertex *v1, 
+                             const SWvertex *v2 )
 {
 #define INTERP_Z 1
-#define SETUP_CODE                             \
-   GLuint index = v0->index;   \
-   if (1) {                                    \
-      /* set the color index */                        \
-      (*ctx->Driver.Index)( ctx, index );      \
-   }
 
 #define INNER_LOOP( LEFT, RIGHT, Y )                           \
        {                                                       \
@@ -94,8 +89,8 @@ static void flat_ci_triangle( GLcontext *ctx,
                 fogspan[i] = fffog / 256;                      \
                 fffog += fdfogdx;                              \
              }                                                 \
-             gl_write_monoindex_span( ctx, n, LEFT, Y, zspan,  \
-                                fogspan, index, GL_POLYGON );  \
+             _mesa_write_monoindex_span( ctx, n, LEFT, Y, zspan,       \
+                         fogspan, v0->index, GL_POLYGON );     \
           }                                                    \
        }
 
@@ -108,9 +103,9 @@ static void flat_ci_triangle( GLcontext *ctx,
  * Render a smooth-shaded color index triangle.
  */
 static void smooth_ci_triangle( GLcontext *ctx,
-                               SWvertex *v0, 
-                               SWvertex *v1, 
-                               SWvertex *v2 )
+                               const SWvertex *v0, 
+                               const SWvertex *v1, 
+                               const SWvertex *v2 )
 {
 #define INTERP_Z 1
 #define INTERP_INDEX 1
@@ -131,7 +126,7 @@ static void smooth_ci_triangle( GLcontext *ctx,
                 fogspan[i] = fffog / 256;                      \
                 fffog += fdfogdx;                              \
              }                                                 \
-             gl_write_index_span( ctx, n, LEFT, Y, zspan, fogspan,     \
+             _mesa_write_index_span( ctx, n, LEFT, Y, zspan, fogspan,  \
                                   index, GL_POLYGON );         \
           }                                                    \
        }
@@ -145,23 +140,13 @@ static void smooth_ci_triangle( GLcontext *ctx,
  * Render a flat-shaded RGBA triangle.
  */
 static void flat_rgba_triangle( GLcontext *ctx,
-                               SWvertex *v0,
-                               SWvertex *v1,
-                               SWvertex *v2 )
+                               const SWvertex *v0,
+                               const SWvertex *v1,
+                               const SWvertex *v2 )
 {
 #define INTERP_Z 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
 
-#define SETUP_CODE                             \
-   if (1) {                                    \
-      /* set the color */                      \
-      GLchan r = v0->color[0]; \
-      GLchan g = v0->color[1]; \
-      GLchan b = v0->color[2]; \
-      GLchan a = v0->color[3]; \
-      (*ctx->Driver.Color)( ctx, r, g, b, a ); \
-   }
-
 #define INNER_LOOP( LEFT, RIGHT, Y )                           \
        {                                                       \
           const GLint n = RIGHT-LEFT;                          \
@@ -175,9 +160,8 @@ static void flat_rgba_triangle( GLcontext *ctx,
                 fogspan[i] = fffog / 256;                      \
                 fffog += fdfogdx;                              \
              }                                                 \
-              gl_write_monocolor_span( ctx, n, LEFT, Y, zspan, \
-                                       fogspan, \
-                                       v0->color,      \
+              _mesa_write_monocolor_span( ctx, n, LEFT, Y, zspan,      \
+                                       fogspan, v2->color,     \
                                       GL_POLYGON );            \
           }                                                    \
        }
@@ -194,9 +178,9 @@ static void flat_rgba_triangle( GLcontext *ctx,
  * Render a smooth-shaded RGBA triangle.
  */
 static void smooth_rgba_triangle( GLcontext *ctx,
-                                 SWvertex *v0,
-                                 SWvertex *v1,
-                                 SWvertex *v2 )
+                                 const SWvertex *v0,
+                                 const SWvertex *v1,
+                                 const SWvertex *v2 )
 {
 
 #define INTERP_Z 1
@@ -226,7 +210,7 @@ static void smooth_rgba_triangle( GLcontext *ctx,
                 ffb += fdbdx;                                  \
                 ffa += fdadx;                                  \
              }                                                 \
-             gl_write_rgba_span( ctx, n, LEFT, Y,              \
+             _mesa_write_rgba_span( ctx, n, LEFT, Y,           \
                                   (CONST GLdepth *) zspan,     \
                                   fogspan,                      \
                                  rgba, GL_POLYGON );           \
@@ -247,27 +231,25 @@ static void smooth_rgba_triangle( GLcontext *ctx,
  * No fog.
  */
 static void simple_textured_triangle( GLcontext *ctx,
-                                     SWvertex *v0,
-                                     SWvertex *v1,
-                                     SWvertex *v2 )
+                                     const SWvertex *v0,
+                                     const SWvertex *v1,
+                                     const SWvertex *v2 )
 {
 #define INTERP_INT_TEX 1
 #define S_SCALE twidth
 #define T_SCALE theight
 #define SETUP_CODE                                                     \
-   struct gl_texture_object *obj = ctx->Texture.Unit[0].CurrentD[2];   \
+   struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D;     \
    GLint b = obj->BaseLevel;                                           \
    GLfloat twidth = (GLfloat) obj->Image[b]->Width;                    \
    GLfloat theight = (GLfloat) obj->Image[b]->Height;                  \
    GLint twidth_log2 = obj->Image[b]->WidthLog2;                       \
-   GLchan *texture = obj->Image[b]->Data;                              \
+   const GLchan *texture = (const GLchan *) obj->Image[b]->Data;       \
    GLint smask = obj->Image[b]->Width - 1;                             \
    GLint tmask = obj->Image[b]->Height - 1;                            \
    if (!texture) {                                                     \
-      if (!_mesa_get_teximages_from_driver(ctx, obj))                  \
-         return;                                                       \
-      texture = obj->Image[b]->Data;                                   \
-      ASSERT(texture);                                                 \
+      /* this shouldn't happen */                                      \
+      return;                                                          \
    }
 
 #define INNER_LOOP( LEFT, RIGHT, Y )                           \
@@ -306,9 +288,9 @@ static void simple_textured_triangle( GLcontext *ctx,
  * No fog.
  */
 static void simple_z_textured_triangle( GLcontext *ctx,
-                                       SWvertex *v0,
-                                       SWvertex *v1,
-                                       SWvertex *v2 )
+                                       const SWvertex *v0,
+                                       const SWvertex *v1,
+                                       const SWvertex *v2 )
 {
 #define INTERP_Z 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
@@ -316,19 +298,17 @@ static void simple_z_textured_triangle( GLcontext *ctx,
 #define S_SCALE twidth
 #define T_SCALE theight
 #define SETUP_CODE                                                     \
-   struct gl_texture_object *obj = ctx->Texture.Unit[0].CurrentD[2];   \
+   struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D;     \
    GLint b = obj->BaseLevel;                                           \
    GLfloat twidth = (GLfloat) obj->Image[b]->Width;                    \
    GLfloat theight = (GLfloat) obj->Image[b]->Height;                  \
    GLint twidth_log2 = obj->Image[b]->WidthLog2;                       \
-   GLchan *texture = obj->Image[b]->Data;                              \
+   const GLchan *texture = (const GLchan *) obj->Image[b]->Data;       \
    GLint smask = obj->Image[b]->Width - 1;                             \
    GLint tmask = obj->Image[b]->Height - 1;                            \
    if (!texture) {                                                     \
-      if (!_mesa_get_teximages_from_driver(ctx, obj))                  \
-         return;                                                       \
-      texture = obj->Image[b]->Data;                                   \
-      ASSERT(texture);                                                 \
+      /* this shouldn't happen */                                      \
+      return;                                                          \
    }
 
 #define INNER_LOOP( LEFT, RIGHT, Y )                           \
@@ -375,9 +355,9 @@ static void simple_z_textured_triangle( GLcontext *ctx,
  * Render an RGB/RGBA textured triangle without perspective correction.
  */
 static void affine_textured_triangle( GLcontext *ctx,
-                                     SWvertex *v0,
-                                     SWvertex *v1,
-                                     SWvertex *v2 )
+                                     const SWvertex *v0,
+                                     const SWvertex *v1,
+                                     const SWvertex *v2 )
 {
 #define INTERP_Z 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
@@ -388,12 +368,12 @@ static void affine_textured_triangle( GLcontext *ctx,
 #define T_SCALE theight
 #define SETUP_CODE                                                     \
    struct gl_texture_unit *unit = ctx->Texture.Unit+0;                 \
-   struct gl_texture_object *obj = unit->CurrentD[2];                  \
+   struct gl_texture_object *obj = unit->Current2D;                    \
    GLint b = obj->BaseLevel;                                           \
    GLfloat twidth = (GLfloat) obj->Image[b]->Width;                    \
    GLfloat theight = (GLfloat) obj->Image[b]->Height;                  \
    GLint twidth_log2 = obj->Image[b]->WidthLog2;                       \
-   GLchan *texture = obj->Image[b]->Data;                              \
+   const GLchan *texture = (const GLchan *) obj->Image[b]->Data;       \
    GLint smask = obj->Image[b]->Width - 1;                             \
    GLint tmask = obj->Image[b]->Height - 1;                             \
    GLint format = obj->Image[b]->Format;                                \
@@ -403,17 +383,15 @@ static void affine_textured_triangle( GLcontext *ctx,
    GLfixed er, eg, eb, ea;                                              \
    GLint tr, tg, tb, ta;                                                \
    if (!texture) {                                                     \
-      if (!_mesa_get_teximages_from_driver(ctx, obj))                  \
-         return;                                                       \
-      texture = obj->Image[b]->Data;                                   \
-      ASSERT(texture);                                                 \
+      /* this shouldn't happen */                                      \
+      return;                                                          \
    }                                                                   \
    if (envmode == GL_BLEND || envmode == GL_ADD) {                      \
       /* potential off-by-one error here? (1.0f -> 2048 -> 0) */        \
-      er = FloatToFixed(unit->EnvColor[0]);                             \
-      eg = FloatToFixed(unit->EnvColor[1]);                             \
-      eb = FloatToFixed(unit->EnvColor[2]);                             \
-      ea = FloatToFixed(unit->EnvColor[3]);                             \
+      er = FloatToFixed(unit->EnvColor[RCOMP]);                         \
+      eg = FloatToFixed(unit->EnvColor[GCOMP]);                         \
+      eb = FloatToFixed(unit->EnvColor[BCOMP]);                         \
+      ea = FloatToFixed(unit->EnvColor[ACOMP]);                         \
    }                                                                    \
    switch (format) {                                                    \
    case GL_ALPHA:                                                       \
@@ -431,7 +409,7 @@ static void affine_textured_triangle( GLcontext *ctx,
       comp = 4;                                                         \
       break;                                                            \
    default:                                                             \
-      gl_problem(NULL, "Bad texture format in affine_texture_triangle");\
+      _mesa_problem(NULL, "Bad texture format in affine_texture_triangle");\
       return;                                                           \
    }                                                                    \
    tbytesline = obj->Image[b]->Width * comp;                            \
@@ -445,9 +423,9 @@ static void affine_textured_triangle( GLcontext *ctx,
    */ 
 
 #define NEAREST_RGB    \
-        tr = tex00[0]; \
-        tg = tex00[1]; \
-        tb = tex00[2]; \
+        tr = tex00[RCOMP]; \
+        tg = tex00[GCOMP]; \
+        tb = tex00[BCOMP]; \
         ta = 0xff
 
 #define LINEAR_RGB                                                      \
@@ -460,10 +438,10 @@ static void affine_textured_triangle( GLcontext *ctx,
        ta = 0xff
 
 #define NEAREST_RGBA   \
-        tr = tex00[0]; \
-        tg = tex00[1]; \
-        tb = tex00[2]; \
-        ta = tex00[3]
+        tr = tex00[RCOMP]; \
+        tg = tex00[GCOMP]; \
+        tb = tex00[BCOMP]; \
+        ta = tex00[ACOMP]
 
 #define LINEAR_RGBA                                                     \
        tr = (ti * (si * tex00[0] + sf * tex01[0]) +                    \
@@ -476,34 +454,34 @@ static void affine_textured_triangle( GLcontext *ctx,
               tf * (si * tex10[3] + sf * tex11[3])) >> 2 * FIXED_SHIFT
 
 #define MODULATE                                       \
-        dest[0] = ffr * (tr + 1) >> (FIXED_SHIFT + 8); \
-        dest[1] = ffg * (tg + 1) >> (FIXED_SHIFT + 8); \
-        dest[2] = ffb * (tb + 1) >> (FIXED_SHIFT + 8); \
-        dest[3] = ffa * (ta + 1) >> (FIXED_SHIFT + 8)
+        dest[RCOMP] = ffr * (tr + 1) >> (FIXED_SHIFT + 8); \
+        dest[GCOMP] = ffg * (tg + 1) >> (FIXED_SHIFT + 8); \
+        dest[BCOMP] = ffb * (tb + 1) >> (FIXED_SHIFT + 8); \
+        dest[ACOMP] = ffa * (ta + 1) >> (FIXED_SHIFT + 8)
 
 #define DECAL                                                                \
-       dest[0] = ((0xff - ta) * ffr + ((ta + 1) * tr << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \
-       dest[1] = ((0xff - ta) * ffg + ((ta + 1) * tg << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \
-       dest[2] = ((0xff - ta) * ffb + ((ta + 1) * tb << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \
-       dest[3] = FixedToInt(ffa)
+       dest[RCOMP] = ((0xff - ta) * ffr + ((ta + 1) * tr << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \
+       dest[GCOMP] = ((0xff - ta) * ffg + ((ta + 1) * tg << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \
+       dest[BCOMP] = ((0xff - ta) * ffb + ((ta + 1) * tb << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \
+       dest[ACOMP] = FixedToInt(ffa)
 
 #define BLEND                                                               \
-        dest[0] = ((0xff - tr) * ffr + (tr + 1) * er) >> (FIXED_SHIFT + 8); \
-        dest[1] = ((0xff - tg) * ffg + (tg + 1) * eg) >> (FIXED_SHIFT + 8); \
-        dest[2] = ((0xff - tb) * ffb + (tb + 1) * eb) >> (FIXED_SHIFT + 8); \
-        dest[3] = ffa * (ta + 1) >> (FIXED_SHIFT + 8)
+        dest[RCOMP] = ((0xff - tr) * ffr + (tr + 1) * er) >> (FIXED_SHIFT + 8); \
+        dest[GCOMP] = ((0xff - tg) * ffg + (tg + 1) * eg) >> (FIXED_SHIFT + 8); \
+        dest[BCOMP] = ((0xff - tb) * ffb + (tb + 1) * eb) >> (FIXED_SHIFT + 8); \
+        dest[ACOMP] = ffa * (ta + 1) >> (FIXED_SHIFT + 8)
 
 #define REPLACE       \
-        dest[0] = tr; \
-        dest[1] = tg; \
-        dest[2] = tb; \
-        dest[3] = ta
+        dest[RCOMP] = tr; \
+        dest[GCOMP] = tg; \
+        dest[BCOMP] = tb; \
+        dest[ACOMP] = ta
 
 #define ADD                                                          \
-        dest[0] = ((ffr << 8) + (tr + 1) * er) >> (FIXED_SHIFT + 8); \
-        dest[1] = ((ffg << 8) + (tg + 1) * eg) >> (FIXED_SHIFT + 8); \
-        dest[2] = ((ffb << 8) + (tb + 1) * eb) >> (FIXED_SHIFT + 8); \
-        dest[3] = ffa * (ta + 1) >> (FIXED_SHIFT + 8)
+        dest[RCOMP] = ((ffr << 8) + (tr + 1) * er) >> (FIXED_SHIFT + 8); \
+        dest[GCOMP] = ((ffg << 8) + (tg + 1) * eg) >> (FIXED_SHIFT + 8); \
+        dest[BCOMP] = ((ffb << 8) + (tb + 1) * eb) >> (FIXED_SHIFT + 8); \
+        dest[ACOMP] = ffa * (ta + 1) >> (FIXED_SHIFT + 8)
 
 /* shortcuts */
 
@@ -516,7 +494,7 @@ static void affine_textured_triangle( GLcontext *ctx,
            GLint s = FixedToInt(ffs) & smask;              \
            GLint t = FixedToInt(fft) & tmask;              \
            GLint pos = (t << twidth_log2) + s;             \
-           GLchan *tex00 = texture + COMP * pos;           \
+           const GLchan *tex00 = texture + COMP * pos;     \
           zspan[i] = FixedToDepth(ffz);                   \
           fogspan[i] = fffog / 256;                       \
            DO_TEX;                                         \
@@ -540,10 +518,10 @@ static void affine_textured_triangle( GLcontext *ctx,
            GLint si = FIXED_FRAC_MASK - sf;                \
            GLint ti = FIXED_FRAC_MASK - tf;                \
            GLint pos = (t << twidth_log2) + s;             \
-           GLchan *tex00 = texture + COMP * pos;           \
-           GLchan *tex10 = tex00 + tbytesline;             \
-           GLchan *tex01 = tex00 + COMP;                   \
-           GLchan *tex11 = tex10 + COMP;                   \
+           const GLchan *tex00 = texture + COMP * pos;     \
+           const GLchan *tex10 = tex00 + tbytesline;       \
+           const GLchan *tex01 = tex00 + COMP;             \
+           const GLchan *tex11 = tex10 + COMP;             \
            if (t == tmask) {                               \
               tex10 -= tsize;                              \
               tex11 -= tsize;                              \
@@ -670,7 +648,7 @@ static void affine_textured_triangle( GLcontext *ctx,
                 }                                         \
                  break;                                    \
              }                                            \
-              gl_write_rgba_span(ctx, n, LEFT, Y, zspan,   \
+              _mesa_write_rgba_span(ctx, n, LEFT, Y, zspan,   \
                                  fogspan,                  \
                                  rgba, GL_POLYGON);        \
               /* explicit kill of variables: */            \
@@ -696,10 +674,11 @@ static void affine_textured_triangle( GLcontext *ctx,
  * This function written by Klaus Niederkrueger <klaus@math.leidenuniv.nl>
  * Send all questions and bug reports to him.
  */
+#if 0 /* XXX disabled because of texcoord interpolation errors */
 static void near_persp_textured_triangle(GLcontext *ctx,
-                                        SWvertex *v0,
-                                        SWvertex *v1,
-                                        SWvertex *v2 )
+                                        const SWvertex *v0,
+                                        const SWvertex *v1,
+                                        const SWvertex *v2 )
 {
 /* The BIAS value is used to shift negative values into positive values.
  * Without this, negative texture values don't GL_REPEAT correctly at just
@@ -716,12 +695,12 @@ static void near_persp_textured_triangle(GLcontext *ctx,
 #define INTERP_TEX 1
 #define SETUP_CODE                                                     \
    struct gl_texture_unit *unit = ctx->Texture.Unit+0;                 \
-   struct gl_texture_object *obj = unit->CurrentD[2];                  \
+   struct gl_texture_object *obj = unit->Current2D;                    \
    const GLint b = obj->BaseLevel;                                     \
    const GLfloat twidth = (GLfloat) obj->Image[b]->Width;              \
    const GLfloat theight = (GLfloat) obj->Image[b]->Height;            \
    const GLint twidth_log2 = obj->Image[b]->WidthLog2;                 \
-   GLchan *texture = obj->Image[b]->Data;                              \
+   const GLchan *texture = (const GLchan *) obj->Image[b]->Data;       \
    const GLint smask = (obj->Image[b]->Width - 1);                      \
    const GLint tmask = (obj->Image[b]->Height - 1);                     \
    const GLint format = obj->Image[b]->Format;                          \
@@ -730,16 +709,14 @@ static void near_persp_textured_triangle(GLcontext *ctx,
    GLfixed er, eg, eb, ea;                                              \
    GLint tr, tg, tb, ta;                                                \
    if (!texture) {                                                     \
-      if (!_mesa_get_teximages_from_driver(ctx, obj))                  \
-         return;                                                       \
-      texture = obj->Image[b]->Data;                                   \
-      ASSERT(texture);                                                 \
+      /* this shouldn't happen */                                      \
+      return;                                                          \
    }                                                                   \
    if (envmode == GL_BLEND || envmode == GL_ADD) {                      \
-      er = FloatToFixed(unit->EnvColor[0]);                             \
-      eg = FloatToFixed(unit->EnvColor[1]);                             \
-      eb = FloatToFixed(unit->EnvColor[2]);                             \
-      ea = FloatToFixed(unit->EnvColor[3]);                             \
+      er = FloatToFixed(unit->EnvColor[RCOMP]);                         \
+      eg = FloatToFixed(unit->EnvColor[GCOMP]);                         \
+      eb = FloatToFixed(unit->EnvColor[BCOMP]);                         \
+      ea = FloatToFixed(unit->EnvColor[ACOMP]);                         \
    }                                                                    \
    sscale = twidth;                                                     \
    tscale = theight;                                                    \
@@ -751,7 +728,7 @@ static void near_persp_textured_triangle(GLcontext *ctx,
       GLint s = (int)(SS * invQ + BIAS) & smask;      \
       GLint t = (int)(TT * invQ + BIAS) & tmask;      \
       GLint pos = COMP * ((t << twidth_log2) + s);    \
-      GLchan *tex00 = texture + pos;                  \
+      const GLchan *tex00 = texture + pos;            \
       zspan[i] = FixedToDepth(ffz);                   \
       fogspan[i] = fffog / 256;                       \
       DO_TEX;                                         \
@@ -1408,7 +1385,7 @@ static void near_persp_textured_triangle(GLcontext *ctx,
                break;                                                  \
             }                                                          \
          }                                                             \
-         gl_write_rgba_span( ctx, n, LEFT, Y, zspan,                   \
+         _mesa_write_rgba_span( ctx, n, LEFT, Y, zspan,                        \
                              fogspan, rgba, GL_POLYGON);               \
          ffr = ffg = ffb = ffa = 0;                                    \
       }                                                                        \
@@ -1425,7 +1402,7 @@ static void near_persp_textured_triangle(GLcontext *ctx,
 #undef DRAW_LINE
 #undef BIAS
 }
-
+#endif
 
 
 /*
@@ -1436,10 +1413,11 @@ static void near_persp_textured_triangle(GLcontext *ctx,
  * This function written by Klaus Niederkrueger <klaus@math.leidenuniv.nl>
  * Send all questions and bug reports to him.
  */
+#if 0 /* XXX disabled because of texcoord interpolation errors */
 static void lin_persp_textured_triangle( GLcontext *ctx,
-                                        SWvertex *v0,
-                                        SWvertex *v1,
-                                        SWvertex *v2 )
+                                        const SWvertex *v0,
+                                        const SWvertex *v1,
+                                        const SWvertex *v2 )
 {
 #define INTERP_Z 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
@@ -1448,7 +1426,7 @@ static void lin_persp_textured_triangle( GLcontext *ctx,
 #define INTERP_TEX 1
 #define SETUP_CODE                                                     \
    struct gl_texture_unit *unit = ctx->Texture.Unit+0;                 \
-   struct gl_texture_object *obj = unit->CurrentD[2];                  \
+   struct gl_texture_object *obj = unit->Current2D;                    \
    const GLint b = obj->BaseLevel;                                     \
    const GLfloat twidth = (GLfloat) obj->Image[b]->Width;              \
    const GLfloat theight = (GLfloat) obj->Image[b]->Height;            \
@@ -1463,16 +1441,13 @@ static void lin_persp_textured_triangle( GLcontext *ctx,
    GLfixed er, eg, eb, ea;                                              \
    GLint tr, tg, tb, ta;                                                \
    if (!texture) {                                                     \
-      if (!_mesa_get_teximages_from_driver(ctx, obj))                  \
-         return;                                                       \
-      texture = obj->Image[b]->Data;                                   \
-      ASSERT(texture);                                                 \
+      return;                                                          \
    }                                                                   \
    if (envmode == GL_BLEND || envmode == GL_ADD) {                      \
-      er = FloatToFixed(unit->EnvColor[0]);                             \
-      eg = FloatToFixed(unit->EnvColor[1]);                             \
-      eb = FloatToFixed(unit->EnvColor[2]);                             \
-      ea = FloatToFixed(unit->EnvColor[3]);                             \
+      er = FloatToFixed(unit->EnvColor[RCOMP]);                         \
+      eg = FloatToFixed(unit->EnvColor[GCOMP]);                         \
+      eb = FloatToFixed(unit->EnvColor[BCOMP]);                         \
+      ea = FloatToFixed(unit->EnvColor[ACOMP]);                         \
    }                                                                    \
    switch (format) {                                                    \
    case GL_ALPHA:                                                      \
@@ -1490,7 +1465,7 @@ static void lin_persp_textured_triangle( GLcontext *ctx,
       comp = 4;                                                         \
       break;                                                            \
    default:                                                            \
-      gl_problem(NULL, "Bad texture format in lin_persp_texture_triangle"); \
+      _mesa_problem(NULL, "Bad texture format in lin_persp_texture_triangle"); \
       return;                                                           \
    }                                                                    \
    sscale = FIXED_SCALE * twidth;                                       \
@@ -1595,18 +1570,17 @@ static void lin_persp_textured_triangle( GLcontext *ctx,
                abort();                                        \
             }                                          \
          }                                             \
-         gl_write_rgba_span( ctx, n, LEFT, Y, zspan,   \
+         _mesa_write_rgba_span( ctx, n, LEFT, Y, zspan,        \
                              fogspan,                   \
                              rgba, GL_POLYGON );       \
          ffr = ffg = ffb = ffa = 0;                    \
       }                                                        \
    }
 
-
 #include "s_tritemp.h"
 #undef SPAN
 }
-
+#endif
 
 
 /*
@@ -1616,9 +1590,9 @@ static void lin_persp_textured_triangle( GLcontext *ctx,
  * R is already used for red.
  */
 static void general_textured_triangle( GLcontext *ctx,
-                                      SWvertex *v0,
-                                      SWvertex *v1,
-                                      SWvertex *v2 )
+                                      const SWvertex *v0,
+                                      const SWvertex *v1,
+                                      const SWvertex *v2 )
 {
 #define INTERP_Z 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
@@ -1629,10 +1603,10 @@ static void general_textured_triangle( GLcontext *ctx,
    GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT);    \
    GLint r, g, b, a;                                           \
    if (flat_shade) {                                           \
-      r = v0->color[0];                                \
-      g = v0->color[1];                                \
-      b = v0->color[2];                                \
-      a = v0->color[3];                                \
+      r = v2->color[RCOMP];                                    \
+      g = v2->color[GCOMP];                                    \
+      b = v2->color[BCOMP];                                    \
+      a = v2->color[ACOMP];                                    \
    }
 #define INNER_LOOP( LEFT, RIGHT, Y )                           \
        {                                                       \
@@ -1645,7 +1619,7 @@ static void general_textured_triangle( GLcontext *ctx,
           if (n>0) {                                           \
               if (flat_shade) {                                        \
                  for (i=0;i<n;i++) {                           \
-                   GLdouble invQ = 1.0 / vv;                   \
+                   GLdouble invQ = vv ? (1.0 / vv) : 1.0;      \
                    zspan[i] = FixedToDepth(ffz);               \
                    fogspan[i] = fffog / 256;                   \
                    rgba[i][RCOMP] = r;                         \
@@ -1665,7 +1639,7 @@ static void general_textured_triangle( GLcontext *ctx,
               }                                                        \
               else {                                           \
                  for (i=0;i<n;i++) {                           \
-                   GLdouble invQ = 1.0 / vv;                   \
+                   GLdouble invQ = vv ? (1.0 / vv) : 1.0;      \
                    zspan[i] = FixedToDepth(ffz);               \
                    rgba[i][RCOMP] = FixedToInt(ffr);           \
                    rgba[i][GCOMP] = FixedToInt(ffg);           \
@@ -1687,7 +1661,7 @@ static void general_textured_triangle( GLcontext *ctx,
                    vv += dvdx;                                 \
                 }                                              \
               }                                                        \
-             gl_write_texture_span( ctx, n, LEFT, Y, zspan, fogspan,   \
+             _mesa_write_texture_span( ctx, n, LEFT, Y, zspan, fogspan,        \
                                      s, t, u, NULL,            \
                                     rgba, \
                                      NULL, GL_POLYGON );       \
@@ -1706,9 +1680,9 @@ static void general_textured_triangle( GLcontext *ctx,
  * R is already used for red.
  */
 static void general_textured_spec_triangle1( GLcontext *ctx,
-                                            SWvertex *v0,
-                                            SWvertex *v1,
-                                            SWvertex *v2,
+                                            const SWvertex *v0,
+                                            const SWvertex *v1,
+                                            const SWvertex *v2,
                                              GLdepth zspan[MAX_WIDTH],
                                              GLfixed fogspan[MAX_WIDTH],
                                              GLchan rgba[MAX_WIDTH][4],
@@ -1724,13 +1698,13 @@ static void general_textured_spec_triangle1( GLcontext *ctx,
    GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT);    \
    GLint r, g, b, a, sr, sg, sb;                               \
    if (flat_shade) {                                           \
-      r = v0->color[0];                                \
-      g = v0->color[1];                                \
-      b = v0->color[2];                                \
-      a = v0->color[3];                                \
-      sr = v0->specular[0];                    \
-      sg = v0->specular[1];                    \
-      sb = v0->specular[2];                    \
+      r = v2->color[RCOMP];                                    \
+      g = v2->color[GCOMP];                                    \
+      b = v2->color[BCOMP];                                    \
+      a = v2->color[ACOMP];                                    \
+      sr = v2->specular[RCOMP];                                        \
+      sg = v2->specular[GCOMP];                                        \
+      sb = v2->specular[BCOMP];                                        \
    }
 #define INNER_LOOP( LEFT, RIGHT, Y )                           \
        {                                                       \
@@ -1740,7 +1714,7 @@ static void general_textured_spec_triangle1( GLcontext *ctx,
           if (n>0) {                                           \
               if (flat_shade) {                                        \
                  for (i=0;i<n;i++) {                           \
-                   GLdouble invQ = 1.0 / vv;                   \
+                   GLdouble invQ = vv ? (1.0 / vv) : 1.0;      \
                    zspan[i] = FixedToDepth(ffz);               \
                    fogspan[i] = fffog / 256;                   \
                    rgba[i][RCOMP] = r;                         \
@@ -1763,7 +1737,7 @@ static void general_textured_spec_triangle1( GLcontext *ctx,
               }                                                        \
               else {                                           \
                  for (i=0;i<n;i++) {                           \
-                   GLdouble invQ = 1.0 / vv;                   \
+                   GLdouble invQ = vv ? (1.0 / vv) : 1.0;      \
                    zspan[i] = FixedToDepth(ffz);               \
                    fogspan[i] = fffog / 256;                   \
                    rgba[i][RCOMP] = FixedToInt(ffr);           \
@@ -1791,7 +1765,7 @@ static void general_textured_spec_triangle1( GLcontext *ctx,
                    vv += dvdx;                                 \
                 }                                              \
               }                                                        \
-             gl_write_texture_span( ctx, n, LEFT, Y, zspan,    \
+             _mesa_write_texture_span( ctx, n, LEFT, Y, zspan, \
                                    fogspan,                     \
                                    s, t, u, NULL, rgba,                \
                                    (CONST GLchan (*)[4]) spec, \
@@ -1803,26 +1777,6 @@ static void general_textured_spec_triangle1( GLcontext *ctx,
 }
 
 
-
-/*
- * Compute the lambda value for a fragment. (texture level of detail)
- */
-static INLINE GLfloat
-compute_lambda( GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
-                GLfloat invQ, GLfloat width, GLfloat height ) 
-{
-   GLfloat dudx = dsdx * invQ * width;
-   GLfloat dudy = dsdy * invQ * width;
-   GLfloat dvdx = dtdx * invQ * height;
-   GLfloat dvdy = dtdy * invQ * height;
-   GLfloat r1 = dudx * dudx + dudy * dudy;
-   GLfloat r2 = dvdx * dvdx + dvdy * dvdy;
-   GLfloat rho2 = r1 + r2;     /* used to be:  rho2 = MAX2(r1,r2); */
-   /* return log base 2 of rho */
-   return log(rho2) * 1.442695 * 0.5;       /* 1.442695 = 1/log(2) */
-}
-
-
 /*
  * Render a smooth-shaded, textured, RGBA triangle.
  * Interpolate S,T,U with perspective correction and compute lambda for
@@ -1831,9 +1785,9 @@ compute_lambda( GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
  * mipmaps, lambda is also used to select the texture level of detail.
  */
 static void lambda_textured_triangle1( GLcontext *ctx,
-                                      SWvertex *v0,
-                                      SWvertex *v1,
-                                      SWvertex *v2, 
+                                      const SWvertex *v0,
+                                      const SWvertex *v1,
+                                      const SWvertex *v2, 
                                        GLfloat s[MAX_WIDTH],
                                        GLfloat t[MAX_WIDTH],
                                        GLfloat u[MAX_WIDTH] )
@@ -1842,6 +1796,7 @@ static void lambda_textured_triangle1( GLcontext *ctx,
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
 #define INTERP_RGB 1
 #define INTERP_ALPHA 1
+#define INTERP_LAMBDA 1
 #define INTERP_TEX 1
 
 #define SETUP_CODE                                                     \
@@ -1853,10 +1808,10 @@ static void lambda_textured_triangle1( GLcontext *ctx,
    const GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT);      \
    GLint r, g, b, a;                                                   \
    if (flat_shade) {                                                   \
-      r = v0->color[0];                                        \
-      g = v0->color[1];                                        \
-      b = v0->color[2];                                        \
-      a = v0->color[3];                                        \
+      r = v2->color[RCOMP];                                            \
+      g = v2->color[GCOMP];                                            \
+      b = v2->color[BCOMP];                                            \
+      a = v2->color[ACOMP];                                            \
    }
 
 #define INNER_LOOP( LEFT, RIGHT, Y )                                   \
@@ -1870,7 +1825,7 @@ static void lambda_textured_triangle1( GLcontext *ctx,
           if (n>0) {                                                   \
              if (flat_shade) {                                         \
                 for (i=0;i<n;i++) {                                    \
-                   GLdouble invQ = 1.0 / vv;                           \
+                   GLdouble invQ = vv ? (1.0 / vv) : 1.0;              \
                    zspan[i] = FixedToDepth(ffz);                       \
                    fogspan[i] = fffog / 256;                           \
                    rgba[i][RCOMP] = r;                                 \
@@ -1880,8 +1835,7 @@ static void lambda_textured_triangle1( GLcontext *ctx,
                    s[i] = ss*invQ;                                     \
                    t[i] = tt*invQ;                                     \
                    u[i] = uu*invQ;                                     \
-                   lambda[i] = compute_lambda( dsdx, dsdy, dtdx, dtdy, \
-                                               invQ, twidth, theight );\
+                    COMPUTE_LAMBDA(lambda[i], invQ);                   \
                    ffz += fdzdx;                                       \
                    fffog += fdfogdx;                                   \
                    ss += dsdx;                                         \
@@ -1892,7 +1846,7 @@ static void lambda_textured_triangle1( GLcontext *ctx,
               }                                                                \
               else {                                                   \
                 for (i=0;i<n;i++) {                                    \
-                   GLdouble invQ = 1.0 / vv;                           \
+                   GLdouble invQ = vv ? (1.0 / vv) : 1.0;              \
                    zspan[i] = FixedToDepth(ffz);                       \
                    fogspan[i] = fffog / 256;                           \
                    rgba[i][RCOMP] = FixedToInt(ffr);                   \
@@ -1902,8 +1856,7 @@ static void lambda_textured_triangle1( GLcontext *ctx,
                    s[i] = ss*invQ;                                     \
                    t[i] = tt*invQ;                                     \
                    u[i] = uu*invQ;                                     \
-                   lambda[i] = compute_lambda( dsdx, dsdy, dtdx, dtdy, \
-                                               invQ, twidth, theight );\
+                    COMPUTE_LAMBDA(lambda[i], invQ);                   \
                    ffz += fdzdx;                                       \
                    fffog += fdfogdx;                                   \
                    ffr += fdrdx;                                       \
@@ -1916,7 +1869,7 @@ static void lambda_textured_triangle1( GLcontext *ctx,
                    vv += dvdx;                                         \
                 }                                                      \
               }                                                                \
-             gl_write_texture_span( ctx, n, LEFT, Y, zspan, fogspan,   \
+             _mesa_write_texture_span( ctx, n, LEFT, Y, zspan, fogspan,        \
                                      s, t, u, lambda,                  \
                                     rgba, NULL, GL_POLYGON );          \
           }                                                            \
@@ -1935,9 +1888,9 @@ static void lambda_textured_triangle1( GLcontext *ctx,
  * mipmaps, lambda is also used to select the texture level of detail.
  */
 static void lambda_textured_spec_triangle1( GLcontext *ctx,
-                                           SWvertex *v0,
-                                           SWvertex *v1,
-                                           SWvertex *v2,
+                                           const SWvertex *v0,
+                                           const SWvertex *v1,
+                                           const SWvertex *v2,
                                             GLfloat s[MAX_WIDTH],
                                             GLfloat t[MAX_WIDTH],
                                             GLfloat u[MAX_WIDTH] )
@@ -1948,6 +1901,7 @@ static void lambda_textured_spec_triangle1( GLcontext *ctx,
 #define INTERP_SPEC 1
 #define INTERP_ALPHA 1
 #define INTERP_TEX 1
+#define INTERP_LAMBDA 1
 
 #define SETUP_CODE                                                     \
    const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;        \
@@ -1958,13 +1912,13 @@ static void lambda_textured_spec_triangle1( GLcontext *ctx,
    const GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT);      \
    GLint r, g, b, a, sr, sg, sb;                                       \
    if (flat_shade) {                                                   \
-      r = v0->color[0];                                        \
-      g = v0->color[1];                                        \
-      b = v0->color[2];                                        \
-      a = v0->color[3];                                        \
-      sr = v0->specular[0];                            \
-      sg = v0->specular[1];                            \
-      sb = v0->specular[2];                            \
+      r = v2->color[RCOMP];                                            \
+      g = v2->color[GCOMP];                                            \
+      b = v2->color[BCOMP];                                            \
+      a = v2->color[ACOMP];                                            \
+      sr = v2->specular[RCOMP];                                                \
+      sg = v2->specular[GCOMP];                                                \
+      sb = v2->specular[BCOMP];                                                \
    }
 
 #define INNER_LOOP( LEFT, RIGHT, Y )                                   \
@@ -1979,7 +1933,7 @@ static void lambda_textured_spec_triangle1( GLcontext *ctx,
           if (n>0) {                                                   \
              if (flat_shade) {                                         \
                 for (i=0;i<n;i++) {                                    \
-                   GLdouble invQ = 1.0 / vv;                           \
+                   GLdouble invQ = vv ? (1.0 / vv) : 1.0;              \
                    zspan[i] = FixedToDepth(ffz);                       \
                    fogspan[i] = fffog / 256;                           \
                    rgba[i][RCOMP] = r;                                 \
@@ -1992,8 +1946,7 @@ static void lambda_textured_spec_triangle1( GLcontext *ctx,
                    s[i] = ss*invQ;                                     \
                    t[i] = tt*invQ;                                     \
                    u[i] = uu*invQ;                                     \
-                   lambda[i] = compute_lambda( dsdx, dsdy, dtdx, dtdy, \
-                                               invQ, twidth, theight );\
+                    COMPUTE_LAMBDA(lambda[i], invQ);                   \
                    fffog += fdfogdx;                                   \
                    ffz += fdzdx;                                       \
                    ss += dsdx;                                         \
@@ -2004,7 +1957,7 @@ static void lambda_textured_spec_triangle1( GLcontext *ctx,
               }                                                                \
               else {                                                   \
                 for (i=0;i<n;i++) {                                    \
-                   GLdouble invQ = 1.0 / vv;                           \
+                   GLdouble invQ = vv ? (1.0 / vv) : 1.0;              \
                    zspan[i] = FixedToDepth(ffz);                       \
                    fogspan[i] = fffog / 256;                           \
                    rgba[i][RCOMP] = FixedToInt(ffr);                   \
@@ -2017,8 +1970,7 @@ static void lambda_textured_spec_triangle1( GLcontext *ctx,
                    s[i] = ss*invQ;                                     \
                    t[i] = tt*invQ;                                     \
                    u[i] = uu*invQ;                                     \
-                   lambda[i] = compute_lambda( dsdx, dsdy, dtdx, dtdy, \
-                                               invQ, twidth, theight );\
+                    COMPUTE_LAMBDA(lambda[i], invQ);                   \
                    fffog += fdfogdx;                                   \
                    ffz += fdzdx;                                       \
                    ffr += fdrdx;                                       \
@@ -2034,7 +1986,7 @@ static void lambda_textured_spec_triangle1( GLcontext *ctx,
                    vv += dvdx;                                         \
                 }                                                      \
               }                                                                \
-             gl_write_texture_span( ctx, n, LEFT, Y, zspan, fogspan,   \
+             _mesa_write_texture_span( ctx, n, LEFT, Y, zspan, fogspan,        \
                                      s, t, u, lambda,                  \
                                     rgba, (CONST GLchan (*)[4]) spec,  \
                                      GL_POLYGON );                     \
@@ -2052,9 +2004,9 @@ static void lambda_textured_spec_triangle1( GLcontext *ctx,
  */
 static void 
 lambda_multitextured_triangle1( GLcontext *ctx,
-                               SWvertex *v0,
-                               SWvertex *v1,
-                               SWvertex *v2,
+                               const SWvertex *v0,
+                               const SWvertex *v1,
+                               const SWvertex *v2,
                                GLfloat s[MAX_TEXTURE_UNITS][MAX_WIDTH],
                                GLfloat t[MAX_TEXTURE_UNITS][MAX_WIDTH],
                                GLfloat u[MAX_TEXTURE_UNITS][MAX_WIDTH])
@@ -2064,113 +2016,105 @@ lambda_multitextured_triangle1( GLcontext *ctx,
 #define INTERP_RGB 1
 #define INTERP_ALPHA 1
 #define INTERP_MULTITEX 1
+#define INTERP_MULTILAMBDA 1
 
-#define SETUP_CODE                                                             \
-   GLchan rgba[MAX_WIDTH][4];                                                  \
-   const GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT);              \
-   GLfloat twidth[MAX_TEXTURE_UNITS], theight[MAX_TEXTURE_UNITS];              \
-   GLint r, g, b, a;                                                           \
-   if (flat_shade) {                                                           \
-      r = v0->color[0];                                                \
-      g = v0->color[1];                                                \
-      b = v0->color[2];                                                \
-      a = v0->color[3];                                                \
-   }                                                                           \
-   {                                                                           \
-      GLuint unit;                                                             \
-      for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {              \
-         if (ctx->Texture.Unit[unit]._ReallyEnabled) {                         \
+#define SETUP_CODE                                                     \
+   GLchan rgba[MAX_WIDTH][4];                                          \
+   const GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT);      \
+   GLfloat twidth[MAX_TEXTURE_UNITS], theight[MAX_TEXTURE_UNITS];      \
+   GLint r, g, b, a;                                                   \
+   if (flat_shade) {                                                   \
+      r = v2->color[0];                                                        \
+      g = v2->color[1];                                                        \
+      b = v2->color[2];                                                        \
+      a = v2->color[3];                                                        \
+   }                                                                   \
+   {                                                                   \
+      GLuint unit;                                                     \
+      for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {      \
+         if (ctx->Texture.Unit[unit]._ReallyEnabled) {                 \
             const struct gl_texture_object *obj = ctx->Texture.Unit[unit]._Current; \
-            const GLint baseLevel = obj->BaseLevel;                            \
-            const struct gl_texture_image *texImage = obj->Image[baseLevel];   \
-            twidth[unit] = (GLfloat) texImage->Width;                          \
-            theight[unit] = (GLfloat) texImage->Height;                                \
-         }                                                                     \
-      }                                                                                \
+            const GLint baseLevel = obj->BaseLevel;                    \
+            const struct gl_texture_image *texImage = obj->Image[baseLevel];\
+            twidth[unit] = (GLfloat) texImage->Width;                  \
+            theight[unit] = (GLfloat) texImage->Height;                        \
+         }                                                             \
+      }                                                                        \
    }
 
-
-
-#define INNER_LOOP( LEFT, RIGHT, Y )                                           \
-   {                                                                           \
-      GLint i;                                                                 \
-      const GLint n = RIGHT-LEFT;                                              \
-      GLdepth zspan[MAX_WIDTH];                                                        \
-      GLfixed fogspan[MAX_WIDTH];                                              \
-      GLfloat lambda[MAX_TEXTURE_UNITS][MAX_WIDTH];                            \
-      if (n > 0) {                                                             \
-         if (flat_shade) {                                                     \
-           for (i=0;i<n;i++) {                                                 \
-              zspan[i] = FixedToDepth(ffz);                                    \
-              fogspan[i] = fffog / 256;                                        \
-               fffog += fdfogdx;                                               \
-              ffz += fdzdx;                                                    \
-              rgba[i][RCOMP] = r;                                              \
-              rgba[i][GCOMP] = g;                                              \
-              rgba[i][BCOMP] = b;                                              \
-              rgba[i][ACOMP] = a;                                              \
-              {                                                                \
-                 GLuint unit;                                                  \
-                 for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {   \
-                    if (ctx->Texture.Unit[unit]._ReallyEnabled) {              \
-                       GLdouble invQ = 1.0 / vv[unit];                         \
-                       s[unit][i] = ss[unit] * invQ;                           \
-                       t[unit][i] = tt[unit] * invQ;                           \
-                       u[unit][i] = uu[unit] * invQ;                           \
-                       lambda[unit][i] = compute_lambda(dsdx[unit], dsdy[unit],\
-                                  dtdx[unit], dtdy[unit], invQ,                \
-                                  twidth[unit], theight[unit] );               \
-                       ss[unit] += dsdx[unit];                                 \
-                       tt[unit] += dtdx[unit];                                 \
-                       uu[unit] += dudx[unit];                                 \
-                       vv[unit] += dvdx[unit];                                 \
-                    }                                                          \
-                 }                                                             \
-              }                                                                \
-           }                                                                   \
-        }                                                                      \
-        else { /* smooth shade */                                              \
-           for (i=0;i<n;i++) {                                                 \
-              zspan[i] = FixedToDepth(ffz);                                    \
-              fogspan[i] = fffog / 256;                                        \
-              ffz += fdzdx;                                                    \
-              fffog += fdfogdx;                                                \
-              rgba[i][RCOMP] = FixedToInt(ffr);                                \
-              rgba[i][GCOMP] = FixedToInt(ffg);                                \
-              rgba[i][BCOMP] = FixedToInt(ffb);                                \
-              rgba[i][ACOMP] = FixedToInt(ffa);                                \
-              ffr += fdrdx;                                                    \
-              ffg += fdgdx;                                                    \
-              ffb += fdbdx;                                                    \
-              ffa += fdadx;                                                    \
-              {                                                                \
-                 GLuint unit;                                                  \
-                 for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {   \
-                    if (ctx->Texture.Unit[unit]._ReallyEnabled) {              \
-                       GLdouble invQ = 1.0 / vv[unit];                         \
-                       s[unit][i] = ss[unit] * invQ;                           \
-                       t[unit][i] = tt[unit] * invQ;                           \
-                       u[unit][i] = uu[unit] * invQ;                           \
-                       lambda[unit][i] = compute_lambda(dsdx[unit], dsdy[unit],\
-                                  dtdx[unit], dtdy[unit], invQ,                \
-                                  twidth[unit], theight[unit] );               \
-                       ss[unit] += dsdx[unit];                                 \
-                       tt[unit] += dtdx[unit];                                 \
-                       uu[unit] += dudx[unit];                                 \
-                       vv[unit] += dvdx[unit];                                 \
-                    }                                                          \
-                 }                                                             \
-              }                                                                \
-           }                                                                   \
-        }                                                                      \
-        gl_write_multitexture_span( ctx, n, LEFT, Y, zspan, fogspan,           \
-                                    (const GLfloat (*)[MAX_WIDTH]) s,          \
-                                    (const GLfloat (*)[MAX_WIDTH]) t,          \
-                                    (const GLfloat (*)[MAX_WIDTH]) u,          \
-                                    (GLfloat (*)[MAX_WIDTH]) lambda,           \
-                                    rgba, NULL, GL_POLYGON );                  \
-      }                                                                                \
+#define INNER_LOOP( LEFT, RIGHT, Y )                                   \
+   {                                                                   \
+      GLint i;                                                         \
+      const GLint n = RIGHT-LEFT;                                      \
+      GLdepth zspan[MAX_WIDTH];                                                \
+      GLfixed fogspan[MAX_WIDTH];                                      \
+      GLfloat lambda[MAX_TEXTURE_UNITS][MAX_WIDTH];                    \
+      if (n > 0) {                                                     \
+         if (flat_shade) {                                             \
+           for (i=0;i<n;i++) {                                         \
+               GLuint unit;                                            \
+              zspan[i] = FixedToDepth(ffz);                            \
+              fogspan[i] = fffog / 256;                                \
+               fffog += fdfogdx;                                       \
+              ffz += fdzdx;                                            \
+              rgba[i][RCOMP] = r;                                      \
+              rgba[i][GCOMP] = g;                                      \
+              rgba[i][BCOMP] = b;                                      \
+              rgba[i][ACOMP] = a;                                      \
+              for (unit=0; unit < ctx->Const.MaxTextureUnits; unit++) {\
+                  if (ctx->Texture.Unit[unit]._ReallyEnabled) {                \
+                    GLdouble invQ = 1.0 / vv[unit];                    \
+                    s[unit][i] = ss[unit] * invQ;                      \
+                    t[unit][i] = tt[unit] * invQ;                      \
+                    u[unit][i] = uu[unit] * invQ;                      \
+                     COMPUTE_MULTILAMBDA(lambda[unit][i], invQ, unit); \
+                    ss[unit] += dsdx[unit];                            \
+                    tt[unit] += dtdx[unit];                            \
+                    uu[unit] += dudx[unit];                            \
+                    vv[unit] += dvdx[unit];                            \
+                 }                                                     \
+              }                                                        \
+           }                                                           \
+        }                                                              \
+        else { /* smooth shade */                                      \
+           for (i=0;i<n;i++) {                                         \
+               GLuint unit;                                            \
+              zspan[i] = FixedToDepth(ffz);                            \
+              fogspan[i] = fffog / 256;                                \
+              ffz += fdzdx;                                            \
+              fffog += fdfogdx;                                        \
+              rgba[i][RCOMP] = FixedToInt(ffr);                        \
+              rgba[i][GCOMP] = FixedToInt(ffg);                        \
+              rgba[i][BCOMP] = FixedToInt(ffb);                        \
+              rgba[i][ACOMP] = FixedToInt(ffa);                        \
+              ffr += fdrdx;                                            \
+              ffg += fdgdx;                                            \
+              ffb += fdbdx;                                            \
+              ffa += fdadx;                                            \
+               for (unit=0; unit < ctx->Const.MaxTextureUnits; unit++) {\
+                 if (ctx->Texture.Unit[unit]._ReallyEnabled) {         \
+                    GLdouble invQ = 1.0 / vv[unit];                    \
+                    s[unit][i] = ss[unit] * invQ;                      \
+                    t[unit][i] = tt[unit] * invQ;                      \
+                    u[unit][i] = uu[unit] * invQ;                      \
+                     COMPUTE_MULTILAMBDA(lambda[unit][i], invQ, unit);  \
+                    ss[unit] += dsdx[unit];                            \
+                    tt[unit] += dtdx[unit];                            \
+                    uu[unit] += dudx[unit];                            \
+                    vv[unit] += dvdx[unit];                            \
+                 }                                                     \
+              }                                                        \
+           }                                                           \
+        }                                                              \
+        _mesa_write_multitexture_span(ctx, n, LEFT, Y, zspan, fogspan, \
+                                      (const GLfloat (*)[MAX_WIDTH]) s,\
+                                       (const GLfloat (*)[MAX_WIDTH]) t,\
+                                       (const GLfloat (*)[MAX_WIDTH]) u,\
+                                       (GLfloat (*)[MAX_WIDTH]) lambda,        \
+                                       rgba, NULL, GL_POLYGON );       \
+      }                                                                        \
    }
+
 #include "s_tritemp.h"
 }
 
@@ -2181,9 +2125,9 @@ lambda_multitextured_triangle1( GLcontext *ctx,
  */
 
 static void general_textured_spec_triangle(GLcontext *ctx,
-                                          SWvertex *v0,
-                                          SWvertex *v1,
-                                          SWvertex *v2 )
+                                          const SWvertex *v0,
+                                          const SWvertex *v1,
+                                          const SWvertex *v2 )
 {
    GLdepth zspan[MAX_WIDTH];
    GLfixed fogspan[MAX_WIDTH];                    
@@ -2192,18 +2136,18 @@ static void general_textured_spec_triangle(GLcontext *ctx,
 }
 
 static void lambda_textured_triangle( GLcontext *ctx,
-                                     SWvertex *v0,
-                                     SWvertex *v1,
-                                     SWvertex *v2 )
+                                     const SWvertex *v0,
+                                     const SWvertex *v1,
+                                     const SWvertex *v2 )
 {
    GLfloat s[MAX_WIDTH], t[MAX_WIDTH], u[MAX_WIDTH];
    lambda_textured_triangle1(ctx,v0,v1,v2,s,t,u);
 }
 
 static void lambda_textured_spec_triangle( GLcontext *ctx,
-                                          SWvertex *v0,
-                                          SWvertex *v1,
-                                          SWvertex *v2 )
+                                          const SWvertex *v0,
+                                          const SWvertex *v1,
+                                          const SWvertex *v2 )
 {
    GLfloat s[MAX_WIDTH];
    GLfloat t[MAX_WIDTH];
@@ -2213,9 +2157,9 @@ static void lambda_textured_spec_triangle( GLcontext *ctx,
 
 
 static void lambda_multitextured_triangle( GLcontext *ctx,
-                                          SWvertex *v0,
-                                          SWvertex *v1,
-                                          SWvertex *v2 )
+                                          const SWvertex *v0,
+                                          const SWvertex *v1,
+                                          const SWvertex *v2 )
 {
 
    GLfloat s[MAX_TEXTURE_UNITS][MAX_WIDTH];
@@ -2231,9 +2175,9 @@ static void lambda_multitextured_triangle( GLcontext *ctx,
 
 
 static void occlusion_zless_triangle( GLcontext *ctx,
-                                     SWvertex *v0,
-                                     SWvertex *v1,
-                                     SWvertex *v2 )
+                                     const SWvertex *v0,
+                                     const SWvertex *v1,
+                                     const SWvertex *v2 )
 {
    if (ctx->OcclusionResult) {
       return;
@@ -2261,6 +2205,27 @@ static void occlusion_zless_triangle( GLcontext *ctx,
 
 
 
+void _swrast_add_spec_terms_triangle( GLcontext *ctx,
+                                     const SWvertex *v0,
+                                     const SWvertex *v1,
+                                     const SWvertex *v2 )
+{
+   SWvertex *ncv0 = (SWvertex *)v0; /* drop const qualifier */
+   SWvertex *ncv1 = (SWvertex *)v1;
+   SWvertex *ncv2 = (SWvertex *)v2;
+   GLchan c[3][4];
+   COPY_CHAN4( c[0], ncv0->color );
+   COPY_CHAN4( c[1], ncv1->color );
+   COPY_CHAN4( c[2], ncv2->color );
+   ACC_3V( ncv0->color, ncv0->specular );
+   ACC_3V( ncv1->color, ncv1->specular );
+   ACC_3V( ncv2->color, ncv2->specular );
+   SWRAST_CONTEXT(ctx)->SpecTriangle( ctx, ncv0, ncv1, ncv2 );
+   COPY_CHAN4( ncv0->color, c[0] );
+   COPY_CHAN4( ncv1->color, c[1] );
+   COPY_CHAN4( ncv2->color, c[2] );   
+}
+
 
 
 #if 0
@@ -2282,7 +2247,7 @@ void
 _swrast_choose_triangle( GLcontext *ctx )
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   const GLboolean rgbmode = ctx->Visual.RGBAflag;
+   const GLboolean rgbmode = ctx->Visual.rgbMode;
 
    if (ctx->RenderMode==GL_RENDER) {
 
@@ -2313,7 +2278,7 @@ _swrast_choose_triangle( GLcontext *ctx )
       if (ctx->Texture._ReallyEnabled) {
          /* Ugh, we do a _lot_ of tests to pick the best textured tri func */
         GLint format, filter;
-        const struct gl_texture_object *current2Dtex = ctx->Texture.Unit[0].CurrentD[2];
+        const struct gl_texture_object *current2Dtex = ctx->Texture.Unit[0].Current2D;
          const struct gl_texture_image *image;
          /* First see if we can used an optimized 2-D texture function */
          if (ctx->Texture._ReallyEnabled==TEXTURE0_2D
@@ -2322,7 +2287,9 @@ _swrast_choose_triangle( GLcontext *ctx )
              && ((image = current2Dtex->Image[current2Dtex->BaseLevel]) != 0)  /* correct! */
              && image->Border==0
              && ((format = image->Format)==GL_RGB || format==GL_RGBA)
+             && image->Type == CHAN_TYPE
             && (filter = current2Dtex->MinFilter)==current2Dtex->MagFilter
+            /* ==> current2Dtex->MinFilter != GL_XXX_MIPMAP_XXX */
             && ctx->Light.Model.ColorControl==GL_SINGLE_COLOR
             && ctx->Texture.Unit[0].EnvMode!=GL_COMBINE_EXT) {
 
@@ -2359,6 +2326,7 @@ _swrast_choose_triangle( GLcontext *ctx )
               }
            }
            else {
+#if 00 /* XXX these function have problems with texture coord interpolation */
               if (filter==GL_NEAREST) {
                 swrast->Triangle = near_persp_textured_triangle;
                 dputs("near_persp_textured_triangle");
@@ -2367,6 +2335,8 @@ _swrast_choose_triangle( GLcontext *ctx )
                 swrast->Triangle = lin_persp_textured_triangle;
                 dputs("lin_persp_textured_triangle");
               }
+#endif
+               swrast->Triangle = general_textured_triangle;
            }
         }
          else {
@@ -2378,13 +2348,11 @@ _swrast_choose_triangle( GLcontext *ctx )
                needLambda = GL_TRUE;
             else
                needLambda = GL_FALSE;
-            if (ctx->Texture._MultiTextureEnabled) {
+            if (swrast->_MultiTextureEnabled) {
                swrast->Triangle = lambda_multitextured_triangle;
               dputs("lambda_multitextured_triangle");
             }
-            else if ((ctx->Light.Enabled &&
-                     ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR)
-                    || ctx->Fog.ColorSumEnabled) {
+            else if (ctx->_TriangleCaps & DD_SEPERATE_SPECULAR) {
                /* separate specular color interpolation */
                if (needLambda) {
                   swrast->Triangle = lambda_textured_spec_triangle;
@@ -2397,7 +2365,7 @@ _swrast_choose_triangle( GLcontext *ctx )
             }
             else {
                if (needLambda) {
-                  swrast->Triangle = lambda_textured_triangle;
+                 swrast->Triangle = lambda_textured_triangle;
                  dputs("lambda_textured_triangle");
               }
                else {
@@ -2411,8 +2379,8 @@ _swrast_choose_triangle( GLcontext *ctx )
         if (ctx->Light.ShadeModel==GL_SMOOTH) {
            /* smooth shaded, no texturing, stippled or some raster ops */
             if (rgbmode) {
-               dputs("smooth_rgba_triangle");
-               swrast->Triangle = smooth_rgba_triangle;
+              dputs("smooth_rgba_triangle");
+              swrast->Triangle = smooth_rgba_triangle;
             }
             else {
                dputs("smooth_ci_triangle");
@@ -2422,8 +2390,8 @@ _swrast_choose_triangle( GLcontext *ctx )
         else {
            /* flat shaded, no texturing, stippled or some raster ops */
             if (rgbmode) {
-               dputs("flat_rgba_triangle");
-               swrast->Triangle = flat_rgba_triangle;
+              dputs("flat_rgba_triangle");
+              swrast->Triangle = flat_rgba_triangle;
             }
             else {
                dputs("flat_ci_triangle");
@@ -2433,10 +2401,10 @@ _swrast_choose_triangle( GLcontext *ctx )
       }
    }
    else if (ctx->RenderMode==GL_FEEDBACK) {
-      swrast->Triangle = gl_feedback_triangle;
+      swrast->Triangle = _mesa_feedback_triangle;
    }
    else {
       /* GL_SELECT mode */
-      swrast->Triangle = gl_select_triangle;
+      swrast->Triangle = _mesa_select_triangle;
    }
 }