Fix typo
[mesa.git] / src / mesa / swrast / s_triangle.c
index 4b00d8aff9a785f8325b6a43686fbf6968a3d6f7..2baa2b5d29a337890d659aebc3f4982dec959696 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: s_triangle.c,v 1.1 2000/10/31 18:00:04 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,7 +34,7 @@
 
 #include "glheader.h"
 #include "context.h"
-#include "feedback.h"
+#include "colormac.h"
 #include "macros.h"
 #include "mem.h"
 #include "mmath.h"
 #include "texstate.h"
 
 #include "s_aatriangle.h"
+#include "s_context.h"
 #include "s_depth.h"
+#include "s_feedback.h"
 #include "s_span.h"
-
-static GLboolean cull_triangle( GLcontext *ctx,
-                           GLuint v0, GLuint v1, GLuint v2, GLuint pv )
+#include "s_triangle.h"
+GLboolean _mesa_cull_triangle( GLcontext *ctx,
+                           const SWvertex *v0, 
+                           const SWvertex *v1, 
+                           const SWvertex *v2 )
 {
-   struct vertex_buffer *VB = ctx->VB;
-   GLfloat (*win)[4] = VB->Win.data;
-   GLfloat ex = win[v1][0] - win[v0][0];
-   GLfloat ey = win[v1][1] - win[v0][1];
-   GLfloat fx = win[v2][0] - win[v0][0];
-   GLfloat fy = win[v2][1] - win[v0][1];
+   GLfloat ex = v1->win[0] - v0->win[0];
+   GLfloat ey = v1->win[1] - v0->win[1];
+   GLfloat fx = v2->win[0] - v0->win[0];
+   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;
@@ -67,15 +70,11 @@ static GLboolean cull_triangle( GLcontext *ctx,
  * Render a flat-shaded color index triangle.
  */
 static void flat_ci_triangle( GLcontext *ctx,
-                              GLuint v0, GLuint v1, GLuint v2, GLuint pv )
+                             const SWvertex *v0, 
+                             const SWvertex *v1, 
+                             const SWvertex *v2 )
 {
 #define INTERP_Z 1
-#define SETUP_CODE                             \
-   GLuint index = VB->IndexPtr->data[pv];      \
-   if (1) {                                    \
-      /* set the color index */                        \
-      (*ctx->Driver.Index)( ctx, index );      \
-   }
 
 #define INNER_LOOP( LEFT, RIGHT, Y )                           \
        {                                                       \
@@ -90,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 );     \
           }                                                    \
        }
 
@@ -104,9 +103,10 @@ static void flat_ci_triangle( GLcontext *ctx,
  * Render a smooth-shaded color index triangle.
  */
 static void smooth_ci_triangle( GLcontext *ctx,
-                                GLuint v0, GLuint v1, GLuint v2, GLuint pv )
+                               const SWvertex *v0, 
+                               const SWvertex *v1, 
+                               const SWvertex *v2 )
 {
-   (void) pv;
 #define INTERP_Z 1
 #define INTERP_INDEX 1
 
@@ -126,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 );         \
           }                                                    \
        }
@@ -140,21 +140,13 @@ static void smooth_ci_triangle( GLcontext *ctx,
  * Render a flat-shaded RGBA triangle.
  */
 static void flat_rgba_triangle( GLcontext *ctx,
-                                GLuint v0, GLuint v1, GLuint v2, GLuint pv )
+                               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 = VB->ColorPtr->data[pv][0];    \
-      GLchan g = VB->ColorPtr->data[pv][1];    \
-      GLchan b = VB->ColorPtr->data[pv][2];    \
-      GLchan a = VB->ColorPtr->data[pv][3];    \
-      (*ctx->Driver.Color)( ctx, r, g, b, a ); \
-   }
-
 #define INNER_LOOP( LEFT, RIGHT, Y )                           \
        {                                                       \
           const GLint n = RIGHT-LEFT;                          \
@@ -168,16 +160,15 @@ static void flat_rgba_triangle( GLcontext *ctx,
                 fogspan[i] = fffog / 256;                      \
                 fffog += fdfogdx;                              \
              }                                                 \
-              gl_write_monocolor_span( ctx, n, LEFT, Y, zspan, \
-                                       fogspan, \
-                                       VB->ColorPtr->data[pv], \
+              _mesa_write_monocolor_span( ctx, n, LEFT, Y, zspan,      \
+                                       fogspan, v2->color,     \
                                       GL_POLYGON );            \
           }                                                    \
        }
 
 #include "s_tritemp.h"
 
-   ASSERT(!ctx->Texture.ReallyEnabled);  /* texturing must be off */
+   ASSERT(!ctx->Texture._ReallyEnabled);  /* texturing must be off */
    ASSERT(ctx->Light.ShadeModel==GL_FLAT);
 }
 
@@ -187,9 +178,11 @@ static void flat_rgba_triangle( GLcontext *ctx,
  * Render a smooth-shaded RGBA triangle.
  */
 static void smooth_rgba_triangle( GLcontext *ctx,
-                                  GLuint v0, GLuint v1, GLuint v2, GLuint pv )
+                                 const SWvertex *v0,
+                                 const SWvertex *v1,
+                                 const SWvertex *v2 )
 {
-   (void) pv;
+
 #define INTERP_Z 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
 #define INTERP_RGB 1
@@ -217,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 );           \
@@ -226,7 +219,7 @@ static void smooth_rgba_triangle( GLcontext *ctx,
 
 #include "s_tritemp.h"
 
-   ASSERT(!ctx->Texture.ReallyEnabled);  /* texturing must be off */
+   ASSERT(!ctx->Texture._ReallyEnabled);  /* texturing must be off */
    ASSERT(ctx->Light.ShadeModel==GL_SMOOTH);
 }
 
@@ -237,27 +230,26 @@ static void smooth_rgba_triangle( GLcontext *ctx,
  *
  * No fog.
  */
-static void simple_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
-                                      GLuint v2, GLuint pv )
+static void simple_textured_triangle( GLcontext *ctx,
+                                     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;                            \
-   (void) pv;                                                          \
    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 )                           \
@@ -295,8 +287,10 @@ static void simple_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  * 
  * No fog.
  */
-static void simple_z_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
-                                        GLuint v2, GLuint pv )
+static void simple_z_textured_triangle( GLcontext *ctx,
+                                       const SWvertex *v0,
+                                       const SWvertex *v1,
+                                       const SWvertex *v2 )
 {
 #define INTERP_Z 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
@@ -304,20 +298,17 @@ static void simple_z_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
 #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;                            \
-   (void) pv;                                                          \
    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 )                           \
@@ -363,8 +354,10 @@ static void simple_z_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
 /*
  * Render an RGB/RGBA textured triangle without perspective correction.
  */
-static void affine_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
-                                     GLuint v2, GLuint pv )
+static void affine_textured_triangle( GLcontext *ctx,
+                                     const SWvertex *v0,
+                                     const SWvertex *v1,
+                                     const SWvertex *v2 )
 {
 #define INTERP_Z 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
@@ -375,12 +368,12 @@ static void affine_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
 #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;                                \
@@ -390,17 +383,15 @@ static void affine_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
    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:                                                       \
@@ -418,12 +409,12 @@ static void affine_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
       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;                            \
    tsize = theight * tbytesline;
-   (void) pv;
+
 
   /* Instead of defining a function for each mode, a test is done 
    * between the outer and inner loops. This is to reduce code size
@@ -432,9 +423,9 @@ static void affine_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
    */ 
 
 #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                                                      \
@@ -447,10 +438,10 @@ static void affine_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
        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]) +                    \
@@ -463,34 +454,34 @@ static void affine_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
               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 */
 
@@ -503,7 +494,7 @@ static void affine_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
            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;                                         \
@@ -527,10 +518,10 @@ static void affine_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
            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;                              \
@@ -657,7 +648,7 @@ static void affine_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
                 }                                         \
                  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: */            \
@@ -683,8 +674,11 @@ static void affine_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  * This function written by Klaus Niederkrueger <klaus@math.leidenuniv.nl>
  * Send all questions and bug reports to him.
  */
-static void near_persp_textured_triangle(GLcontext *ctx, GLuint v0, GLuint v1,
-                                        GLuint v2, GLuint pv )
+#if 0 /* XXX disabled because of texcoord interpolation errors */
+static void near_persp_textured_triangle(GLcontext *ctx,
+                                        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
@@ -701,56 +695,32 @@ static void near_persp_textured_triangle(GLcontext *ctx, GLuint v0, GLuint v1,
 #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;                          \
    const GLint envmode = unit->EnvMode;                                 \
    GLfloat sscale, tscale;                                              \
-   /*GLint comp, tbytesline, tsize; */                                  \
    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]);                         \
    }                                                                    \
-   /*switch (format) {                                                  \
-   case GL_ALPHA:                                                       \
-   case GL_LUMINANCE:                                                   \
-   case GL_INTENSITY:                                                   \
-      comp = 1;                                                         \
-      break;                                                            \
-   case GL_LUMINANCE_ALPHA:                                             \
-      comp = 2;                                                         \
-      break;                                                            \
-   case GL_RGB:                                                         \
-      comp = 3;                                                         \
-      break;                                                            \
-   case GL_RGBA:                                                        \
-      comp = 4;                                                         \
-      break;                                                            \
-   default:                                                             \
-      gl_problem(NULL, "Bad texture format in near_persp_texture_triangle"); \
-      return;                                                           \
-      } */                                                              \
    sscale = twidth;                                                     \
    tscale = theight;                                                    \
-   /*tbytesline = obj->Image[b]->Width * comp;                          \
-   tsize = theight * tbytesline;*/
-   (void) pv;
+
 
 #define OLD_SPAN(DO_TEX,COMP)                         \
    for (i=0;i<n;i++) {                                \
@@ -758,7 +728,7 @@ static void near_persp_textured_triangle(GLcontext *ctx, GLuint v0, GLuint v1,
       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;                                         \
@@ -1415,7 +1385,7 @@ static void near_persp_textured_triangle(GLcontext *ctx, GLuint v0, GLuint v1,
                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;                                    \
       }                                                                        \
@@ -1432,7 +1402,7 @@ static void near_persp_textured_triangle(GLcontext *ctx, GLuint v0, GLuint v1,
 #undef DRAW_LINE
 #undef BIAS
 }
-
+#endif
 
 
 /*
@@ -1443,8 +1413,11 @@ static void near_persp_textured_triangle(GLcontext *ctx, GLuint v0, GLuint v1,
  * This function written by Klaus Niederkrueger <klaus@math.leidenuniv.nl>
  * Send all questions and bug reports to him.
  */
-static void lin_persp_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
-                                        GLuint v2, GLuint pv )
+#if 0 /* XXX disabled because of texcoord interpolation errors */
+static void lin_persp_textured_triangle( GLcontext *ctx,
+                                        const SWvertex *v0,
+                                        const SWvertex *v1,
+                                        const SWvertex *v2 )
 {
 #define INTERP_Z 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
@@ -1453,7 +1426,7 @@ static void lin_persp_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
 #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;            \
@@ -1468,16 +1441,13 @@ static void lin_persp_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
    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:                                                      \
@@ -1495,14 +1465,14 @@ static void lin_persp_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
       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;                                       \
    tscale = FIXED_SCALE * theight;                                      \
    tbytesline = obj->Image[b]->Width * comp;                            \
    tsize = theight * tbytesline;
-   (void) pv;
+
 
 #define SPAN(DO_TEX,COMP)                                  \
         for (i=0;i<n;i++) {                                \
@@ -1600,18 +1570,17 @@ static void lin_persp_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
                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
 
 
 /*
@@ -1620,8 +1589,10 @@ static void lin_persp_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  * Note: we use texture coordinates S,T,U,V instead of S,T,R,Q because
  * R is already used for red.
  */
-static void general_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
-                                       GLuint v2, GLuint pv )
+static void general_textured_triangle( GLcontext *ctx,
+                                      const SWvertex *v0,
+                                      const SWvertex *v1,
+                                      const SWvertex *v2 )
 {
 #define INTERP_Z 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
@@ -1632,10 +1603,10 @@ static void general_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
    GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT);    \
    GLint r, g, b, a;                                           \
    if (flat_shade) {                                           \
-      r = VB->ColorPtr->data[pv][0];                           \
-      g = VB->ColorPtr->data[pv][1];                           \
-      b = VB->ColorPtr->data[pv][2];                           \
-      a = VB->ColorPtr->data[pv][3];                           \
+      r = v2->color[RCOMP];                                    \
+      g = v2->color[GCOMP];                                    \
+      b = v2->color[BCOMP];                                    \
+      a = v2->color[ACOMP];                                    \
    }
 #define INNER_LOOP( LEFT, RIGHT, Y )                           \
        {                                                       \
@@ -1648,7 +1619,7 @@ static void general_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
           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;                         \
@@ -1668,7 +1639,7 @@ static void general_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
               }                                                        \
               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);           \
@@ -1690,7 +1661,7 @@ static void general_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
                    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 );       \
@@ -1708,8 +1679,10 @@ static void general_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  * Note: we use texture coordinates S,T,U,V instead of S,T,R,Q because
  * R is already used for red.
  */
-static void general_textured_spec_triangle1( GLcontext *ctx, GLuint v0,
-                                             GLuint v1, GLuint v2, GLuint pv,
+static void general_textured_spec_triangle1( GLcontext *ctx,
+                                            const SWvertex *v0,
+                                            const SWvertex *v1,
+                                            const SWvertex *v2,
                                              GLdepth zspan[MAX_WIDTH],
                                              GLfixed fogspan[MAX_WIDTH],
                                              GLchan rgba[MAX_WIDTH][4],
@@ -1725,13 +1698,13 @@ static void general_textured_spec_triangle1( GLcontext *ctx, GLuint v0,
    GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT);    \
    GLint r, g, b, a, sr, sg, sb;                               \
    if (flat_shade) {                                           \
-      r = VB->ColorPtr->data[pv][0];                           \
-      g = VB->ColorPtr->data[pv][1];                           \
-      b = VB->ColorPtr->data[pv][2];                           \
-      a = VB->ColorPtr->data[pv][3];                           \
-      sr = VB->SecondaryColorPtr->data[pv][0];                         \
-      sg = VB->SecondaryColorPtr->data[pv][1];                         \
-      sb = VB->SecondaryColorPtr->data[pv][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 )                           \
        {                                                       \
@@ -1741,7 +1714,7 @@ static void general_textured_spec_triangle1( GLcontext *ctx, GLuint v0,
           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;                         \
@@ -1764,7 +1737,7 @@ static void general_textured_spec_triangle1( GLcontext *ctx, GLuint v0,
               }                                                        \
               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);           \
@@ -1792,7 +1765,7 @@ static void general_textured_spec_triangle1( GLcontext *ctx, GLuint v0,
                    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, \
@@ -1804,26 +1777,6 @@ static void general_textured_spec_triangle1( GLcontext *ctx, GLuint v0,
 }
 
 
-
-/*
- * 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,8 +1784,10 @@ compute_lambda( GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
  * minification or magnification filter.  If minification and using
  * mipmaps, lambda is also used to select the texture level of detail.
  */
-static void lambda_textured_triangle1( GLcontext *ctx, GLuint v0, GLuint v1,
-                                       GLuint v2, GLuint pv,
+static void lambda_textured_triangle1( GLcontext *ctx,
+                                      const SWvertex *v0,
+                                      const SWvertex *v1,
+                                      const SWvertex *v2, 
                                        GLfloat s[MAX_WIDTH],
                                        GLfloat t[MAX_WIDTH],
                                        GLfloat u[MAX_WIDTH] )
@@ -1841,10 +1796,11 @@ static void lambda_textured_triangle1( GLcontext *ctx, GLuint v0, GLuint v1,
 #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                                                     \
-   const struct gl_texture_object *obj = ctx->Texture.Unit[0].Current; \
+   const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;        \
    const GLint baseLevel = obj->BaseLevel;                             \
    const struct gl_texture_image *texImage = obj->Image[baseLevel];    \
    const GLfloat twidth = (GLfloat) texImage->Width;                   \
@@ -1852,10 +1808,10 @@ static void lambda_textured_triangle1( GLcontext *ctx, GLuint v0, GLuint v1,
    const GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT);      \
    GLint r, g, b, a;                                                   \
    if (flat_shade) {                                                   \
-      r = VB->ColorPtr->data[pv][0];                                   \
-      g = VB->ColorPtr->data[pv][1];                                   \
-      b = VB->ColorPtr->data[pv][2];                                   \
-      a = VB->ColorPtr->data[pv][3];                                   \
+      r = v2->color[RCOMP];                                            \
+      g = v2->color[GCOMP];                                            \
+      b = v2->color[BCOMP];                                            \
+      a = v2->color[ACOMP];                                            \
    }
 
 #define INNER_LOOP( LEFT, RIGHT, Y )                                   \
@@ -1869,7 +1825,7 @@ static void lambda_textured_triangle1( GLcontext *ctx, GLuint v0, GLuint v1,
           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;                                 \
@@ -1879,8 +1835,7 @@ static void lambda_textured_triangle1( GLcontext *ctx, GLuint v0, GLuint v1,
                    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;                                         \
@@ -1891,7 +1846,7 @@ static void lambda_textured_triangle1( GLcontext *ctx, GLuint v0, GLuint v1,
               }                                                                \
               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);                   \
@@ -1901,8 +1856,7 @@ static void lambda_textured_triangle1( GLcontext *ctx, GLuint v0, GLuint v1,
                    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;                                       \
@@ -1915,7 +1869,7 @@ static void lambda_textured_triangle1( GLcontext *ctx, GLuint v0, GLuint v1,
                    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 );          \
           }                                                            \
@@ -1933,8 +1887,10 @@ static void lambda_textured_triangle1( GLcontext *ctx, GLuint v0, GLuint v1,
  * minification or magnification filter.  If minification and using
  * mipmaps, lambda is also used to select the texture level of detail.
  */
-static void lambda_textured_spec_triangle1( GLcontext *ctx, GLuint v0,
-                                            GLuint v1, GLuint v2, GLuint pv,
+static void lambda_textured_spec_triangle1( GLcontext *ctx,
+                                           const SWvertex *v0,
+                                           const SWvertex *v1,
+                                           const SWvertex *v2,
                                             GLfloat s[MAX_WIDTH],
                                             GLfloat t[MAX_WIDTH],
                                             GLfloat u[MAX_WIDTH] )
@@ -1945,9 +1901,10 @@ static void lambda_textured_spec_triangle1( GLcontext *ctx, GLuint v0,
 #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; \
+   const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;        \
    const GLint baseLevel = obj->BaseLevel;                             \
    const struct gl_texture_image *texImage = obj->Image[baseLevel];    \
    const GLfloat twidth = (GLfloat) texImage->Width;                   \
@@ -1955,13 +1912,13 @@ static void lambda_textured_spec_triangle1( GLcontext *ctx, GLuint v0,
    const GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT);      \
    GLint r, g, b, a, sr, sg, sb;                                       \
    if (flat_shade) {                                                   \
-      r = VB->ColorPtr->data[pv][0];                                   \
-      g = VB->ColorPtr->data[pv][1];                                   \
-      b = VB->ColorPtr->data[pv][2];                                   \
-      a = VB->ColorPtr->data[pv][3];                                   \
-      sr = VB->SecondaryColorPtr->data[pv][0];                         \
-      sg = VB->SecondaryColorPtr->data[pv][1];                         \
-      sb = VB->SecondaryColorPtr->data[pv][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 )                                   \
@@ -1976,7 +1933,7 @@ static void lambda_textured_spec_triangle1( GLcontext *ctx, GLuint v0,
           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;                                 \
@@ -1989,8 +1946,7 @@ static void lambda_textured_spec_triangle1( GLcontext *ctx, GLuint v0,
                    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;                                         \
@@ -2001,7 +1957,7 @@ static void lambda_textured_spec_triangle1( GLcontext *ctx, GLuint v0,
               }                                                                \
               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);                   \
@@ -2014,8 +1970,7 @@ static void lambda_textured_spec_triangle1( GLcontext *ctx, GLuint v0,
                    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;                                       \
@@ -2031,7 +1986,7 @@ static void lambda_textured_spec_triangle1( GLcontext *ctx, GLuint v0,
                    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 );                     \
@@ -2047,125 +2002,119 @@ static void lambda_textured_spec_triangle1( GLcontext *ctx, GLuint v0,
  * Interpolate Z, RGB, Alpha, and two sets of texture coordinates.
  * Yup, it's slow.
  */
-static void lambda_multitextured_triangle1( GLcontext *ctx, GLuint v0,
-                                      GLuint v1, GLuint v2, GLuint pv,
-                                      GLfloat s[MAX_TEXTURE_UNITS][MAX_WIDTH],
-                                      GLfloat t[MAX_TEXTURE_UNITS][MAX_WIDTH],
-                                      GLfloat u[MAX_TEXTURE_UNITS][MAX_WIDTH]
-                                      )
+static void 
+lambda_multitextured_triangle1( GLcontext *ctx,
+                               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])
 {
 #define INTERP_Z 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
 #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 = VB->ColorPtr->data[pv][0];                                           \
-      g = VB->ColorPtr->data[pv][1];                                           \
-      b = VB->ColorPtr->data[pv][2];                                           \
-      a = VB->ColorPtr->data[pv][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;                                \
-         }                                                                     \
-      }                                                                                \
+#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;                        \
+         }                                                             \
+      }                                                                        \
    }
 
-
-
-#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"
 }
 
@@ -2175,34 +2124,42 @@ static void lambda_multitextured_triangle1( GLcontext *ctx, GLuint v0,
  * on Mac / PowerPC systems.
  */
 
-static void general_textured_spec_triangle(GLcontext *ctx, GLuint v0,
-                                           GLuint v1, GLuint v2, GLuint pv)
+static void general_textured_spec_triangle(GLcontext *ctx,
+                                          const SWvertex *v0,
+                                          const SWvertex *v1,
+                                          const SWvertex *v2 )
 {
    GLdepth zspan[MAX_WIDTH];
    GLfixed fogspan[MAX_WIDTH];                    
    GLchan rgba[MAX_WIDTH][4], spec[MAX_WIDTH][4];
-   general_textured_spec_triangle1(ctx,v0,v1,v2,pv,zspan,fogspan,rgba,spec);
+   general_textured_spec_triangle1(ctx,v0,v1,v2,zspan,fogspan,rgba,spec);
 }
 
-static void lambda_textured_triangle( GLcontext *ctx, GLuint v0,
-                                      GLuint v1, GLuint v2, GLuint pv )
+static void lambda_textured_triangle( GLcontext *ctx,
+                                     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,pv,s,t,u);
+   lambda_textured_triangle1(ctx,v0,v1,v2,s,t,u);
 }
 
-static void lambda_textured_spec_triangle( GLcontext *ctx, GLuint v0,
-                                           GLuint v1, GLuint v2, GLuint pv )
+static void lambda_textured_spec_triangle( GLcontext *ctx,
+                                          const SWvertex *v0,
+                                          const SWvertex *v1,
+                                          const SWvertex *v2 )
 {
    GLfloat s[MAX_WIDTH];
    GLfloat t[MAX_WIDTH];
    GLfloat u[MAX_WIDTH];
-   lambda_textured_spec_triangle1(ctx,v0,v1,v2,pv,s,t,u);
+   lambda_textured_spec_triangle1(ctx,v0,v1,v2,s,t,u);
 }
 
 
-static void lambda_multitextured_triangle( GLcontext *ctx, GLuint v0,
-                                           GLuint v1, GLuint v2, GLuint pv)
+static void lambda_multitextured_triangle( GLcontext *ctx,
+                                          const SWvertex *v0,
+                                          const SWvertex *v1,
+                                          const SWvertex *v2 )
 {
 
    GLfloat s[MAX_TEXTURE_UNITS][MAX_WIDTH];
@@ -2210,17 +2167,18 @@ static void lambda_multitextured_triangle( GLcontext *ctx, GLuint v0,
    DEFMARRAY(GLfloat,u,MAX_TEXTURE_UNITS,MAX_WIDTH);
    CHECKARRAY(u,return);
    
-   lambda_multitextured_triangle1(ctx,v0,v1,v2,pv,s,t,u);
+   lambda_multitextured_triangle1(ctx,v0,v1,v2,s,t,u);
    
    UNDEFARRAY(u);
 }
 
 
 
-static void occlusion_zless_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
-                                      GLuint v2, GLuint pv )
+static void occlusion_zless_triangle( GLcontext *ctx,
+                                     const SWvertex *v0,
+                                     const SWvertex *v1,
+                                     const SWvertex *v2 )
 {
-   (void)pv;
    if (ctx->OcclusionResult) {
       return;
    }
@@ -2247,20 +2205,29 @@ static void occlusion_zless_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
 
 
 
-/*
- * Null rasterizer for measuring transformation speed.
- */
-static void null_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
-                           GLuint v2, GLuint pv )
+void _swrast_add_spec_terms_triangle( GLcontext *ctx,
+                                     const SWvertex *v0,
+                                     const SWvertex *v1,
+                                     const SWvertex *v2 )
 {
-   (void) ctx;
-   (void) v0;
-   (void) v1;
-   (void) v2;
-   (void) pv;
+   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
 # define dputs(s) puts(s)
 #else
@@ -2277,24 +2244,16 @@ static void null_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  * remove tests to this code.
  */
 void 
-_swrast_set_triangle_function( GLcontext *ctx )
+_swrast_choose_triangle( GLcontext *ctx )
 {
-   const GLboolean rgbmode = ctx->Visual.RGBAflag;
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+   const GLboolean rgbmode = ctx->Visual.rgbMode;
 
    if (ctx->RenderMode==GL_RENDER) {
-      if (ctx->NoRaster) {
-         ctx->Driver.TriangleFunc = null_triangle;
-         return;
-      }
-      if (ctx->Driver.TriangleFunc) {
-         /* Device driver will draw triangles. */
-         dputs("Driver triangle");
-        return;
-      }
 
       if (ctx->Polygon.SmoothFlag) {
          _mesa_set_aa_triangle_function(ctx);
-         ASSERT(ctx->Driver.TriangleFunc);
+         ASSERT(swrast->Triangle);
          return;
       }
 
@@ -2311,24 +2270,26 @@ _swrast_set_triangle_function( GLcontext *ctx )
              ||
              (!rgbmode && ctx->Color.IndexMask == 0)) {
             dputs("occlusion_test_triangle");
-            ctx->Driver.TriangleFunc = occlusion_zless_triangle;
+            swrast->Triangle = occlusion_zless_triangle;
             return;
          }
       }
 
-      if (ctx->Texture.ReallyEnabled) {
+      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
+         if (ctx->Texture._ReallyEnabled==TEXTURE0_2D
              && current2Dtex->WrapS==GL_REPEAT
             && current2Dtex->WrapT==GL_REPEAT
              && ((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) {
 
@@ -2338,76 +2299,77 @@ _swrast_set_triangle_function( GLcontext *ctx )
                   && format==GL_RGB
                   && (ctx->Texture.Unit[0].EnvMode==GL_REPLACE
                       || ctx->Texture.Unit[0].EnvMode==GL_DECAL)
-                  && ((ctx->RasterMask==DEPTH_BIT
+                  && ((swrast->_RasterMask==DEPTH_BIT
                        && ctx->Depth.Func==GL_LESS
                        && ctx->Depth.Mask==GL_TRUE)
-                      || ctx->RasterMask==0)
+                      || swrast->_RasterMask==0)
                   && ctx->Polygon.StippleFlag==GL_FALSE) {
 
-                 if (ctx->RasterMask==DEPTH_BIT) {
-                    ctx->Driver.TriangleFunc = simple_z_textured_triangle;
+                 if (swrast->_RasterMask==DEPTH_BIT) {
+                    swrast->Triangle = simple_z_textured_triangle;
                     dputs("simple_z_textured_triangle");
                  }
                  else {
-                    ctx->Driver.TriangleFunc = simple_textured_triangle;
+                    swrast->Triangle = simple_textured_triangle;
                     dputs("simple_textured_triangle");
                  }
               }
               else {
                   if (ctx->Texture.Unit[0].EnvMode==GL_ADD) {
-                     ctx->Driver.TriangleFunc = general_textured_triangle;
+                     swrast->Triangle = general_textured_triangle;
                      dputs("general_textured_triangle");
                   }
                   else {
-                     ctx->Driver.TriangleFunc = affine_textured_triangle;
+                     swrast->Triangle = affine_textured_triangle;
                      dputs("affine_textured_triangle");
                   }
               }
            }
            else {
+#if 00 /* XXX these function have problems with texture coord interpolation */
               if (filter==GL_NEAREST) {
-                ctx->Driver.TriangleFunc = near_persp_textured_triangle;
+                swrast->Triangle = near_persp_textured_triangle;
                 dputs("near_persp_textured_triangle");
               }
               else {
-                ctx->Driver.TriangleFunc = lin_persp_textured_triangle;
+                swrast->Triangle = lin_persp_textured_triangle;
                 dputs("lin_persp_textured_triangle");
               }
+#endif
+               swrast->Triangle = general_textured_triangle;
            }
         }
          else {
             /* More complicated textures (mipmap, multi-tex, sep specular) */
             GLboolean needLambda;
             /* if mag filter != min filter we need to compute lambda */
-            const struct gl_texture_object *obj = ctx->Texture.Unit[0].Current;
+            const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
             if (obj && obj->MinFilter != obj->MagFilter)
                needLambda = GL_TRUE;
             else
                needLambda = GL_FALSE;
-            if (ctx->Texture.MultiTextureEnabled) {
-               ctx->Driver.TriangleFunc = lambda_multitextured_triangle;
+            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) {
-                  ctx->Driver.TriangleFunc = lambda_textured_spec_triangle;
+                  swrast->Triangle = lambda_textured_spec_triangle;
                  dputs("lambda_textured_spec_triangle");
               }
                else {
-                  ctx->Driver.TriangleFunc = general_textured_spec_triangle;
+                  swrast->Triangle = general_textured_spec_triangle;
                  dputs("general_textured_spec_triangle");
               }
             }
             else {
                if (needLambda) {
-                  ctx->Driver.TriangleFunc = lambda_textured_triangle;
+                 swrast->Triangle = lambda_textured_triangle;
                  dputs("lambda_textured_triangle");
               }
                else {
-                  ctx->Driver.TriangleFunc = general_textured_triangle;
+                  swrast->Triangle = general_textured_triangle;
                  dputs("general_textured_triangle");
               }
             }
@@ -2417,32 +2379,32 @@ _swrast_set_triangle_function( GLcontext *ctx )
         if (ctx->Light.ShadeModel==GL_SMOOTH) {
            /* smooth shaded, no texturing, stippled or some raster ops */
             if (rgbmode) {
-               dputs("smooth_rgba_triangle");
-               ctx->Driver.TriangleFunc = smooth_rgba_triangle;
+              dputs("smooth_rgba_triangle");
+              swrast->Triangle = smooth_rgba_triangle;
             }
             else {
                dputs("smooth_ci_triangle");
-               ctx->Driver.TriangleFunc = smooth_ci_triangle;
+               swrast->Triangle = smooth_ci_triangle;
             }
         }
         else {
            /* flat shaded, no texturing, stippled or some raster ops */
             if (rgbmode) {
-               dputs("flat_rgba_triangle");
-               ctx->Driver.TriangleFunc = flat_rgba_triangle;
+              dputs("flat_rgba_triangle");
+              swrast->Triangle = flat_rgba_triangle;
             }
             else {
                dputs("flat_ci_triangle");
-               ctx->Driver.TriangleFunc = flat_ci_triangle;
+               swrast->Triangle = flat_ci_triangle;
             }
         }
       }
    }
    else if (ctx->RenderMode==GL_FEEDBACK) {
-      ctx->Driver.TriangleFunc = gl_feedback_triangle;
+      swrast->Triangle = _mesa_feedback_triangle;
    }
    else {
       /* GL_SELECT mode */
-      ctx->Driver.TriangleFunc = gl_select_triangle;
+      swrast->Triangle = _mesa_select_triangle;
    }
 }