fix typo
[mesa.git] / src / mesa / swrast / s_triangle.c
index cc5fc5b0d628cffa2a142a0e3baa84b27d598293..ebbba34af5c12b0f126c95a6cd8ed57e9984aa57 100644 (file)
@@ -1,10 +1,8 @@
-/* $Id: s_triangle.c,v 1.45 2002/01/09 00:09:33 brianp Exp $ */
-
 /*
  * Mesa 3-D graphics library
- * Version:  4.1
+ * Version:  5.1
  *
- * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2003  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,9 +32,8 @@
 #include "glheader.h"
 #include "context.h"
 #include "colormac.h"
+#include "imports.h"
 #include "macros.h"
-#include "mem.h"
-#include "mmath.h"
 #include "texformat.h"
 #include "teximage.h"
 #include "texstate.h"
 #include "s_triangle.h"
 
 
-
-GLboolean _mesa_cull_triangle( GLcontext *ctx,
+/*
+ * Just used for feedback mode.
+ */
+GLboolean _swrast_culltriangle( GLcontext *ctx,
                            const SWvertex *v0,
                            const SWvertex *v1,
                            const SWvertex *v2 )
@@ -61,7 +60,7 @@ GLboolean _mesa_cull_triangle( GLcontext *ctx,
    GLfloat fy = v2->win[1] - v0->win[1];
    GLfloat c = ex*fy-ey*fx;
 
-   if (c * SWRAST_CONTEXT(ctx)->_backface_sign > 0)
+   if (c * SWRAST_CONTEXT(ctx)->_BackfaceSign > 0)
       return 0;
 
    return 1;
@@ -72,106 +71,72 @@ GLboolean _mesa_cull_triangle( GLcontext *ctx,
 /*
  * Render a flat-shaded color index triangle.
  */
-static void flat_ci_triangle( GLcontext *ctx,
-                             const SWvertex *v0,
-                             const SWvertex *v1,
-                             const SWvertex *v2 )
-{
+#define NAME flat_ci_triangle
 #define INTERP_Z 1
 #define INTERP_FOG 1
-
-#define RENDER_SPAN( span )                                            \
-   _mesa_write_monoindex_span(ctx, &span, v2->index, GL_POLYGON );
-
+#define SETUP_CODE                     \
+   span.interpMask |= SPAN_INDEX;      \
+   span.index = IntToFixed(v2->index); \
+   span.indexStep = 0;
+#define RENDER_SPAN( span )  _swrast_write_index_span(ctx, &span);
 #include "s_tritemp.h"
-}
 
 
 
 /*
  * Render a smooth-shaded color index triangle.
  */
-static void smooth_ci_triangle( GLcontext *ctx,
-                               const SWvertex *v0,
-                               const SWvertex *v1,
-                               const SWvertex *v2 )
-{
+#define NAME smooth_ci_triangle
 #define INTERP_Z 1
 #define INTERP_FOG 1
 #define INTERP_INDEX 1
-
-#define RENDER_SPAN( span )                                            \
-   GLuint i;                                                           \
-   SW_SPAN_SET_FLAG(span.filledColor);                                 \
-   for (i = 0; i < span.end; i++) {                                    \
-      span.color.index[i] = FixedToInt(span.index);                    \
-      span.index += span.indexStep;                                    \
-   }                                                                   \
-   _mesa_write_index_span(ctx, &span, GL_POLYGON);
-
+#define RENDER_SPAN( span )  _swrast_write_index_span(ctx, &span);
 #include "s_tritemp.h"
-}
 
 
 
 /*
  * Render a flat-shaded RGBA triangle.
  */
-static void flat_rgba_triangle( GLcontext *ctx,
-                               const SWvertex *v0,
-                               const SWvertex *v1,
-                               const SWvertex *v2 )
-{
+#define NAME flat_rgba_triangle
 #define INTERP_Z 1
 #define INTERP_FOG 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-
-#define RENDER_SPAN( span )                                            \
-   _mesa_write_monocolor_span(ctx, &span, v2->color, GL_POLYGON );
-
+#define SETUP_CODE                             \
+   ASSERT(ctx->Texture._EnabledCoordUnits == 0);\
+   ASSERT(ctx->Light.ShadeModel==GL_FLAT);     \
+   span.interpMask |= SPAN_RGBA;               \
+   span.red = ChanToFixed(v2->color[0]);       \
+   span.green = ChanToFixed(v2->color[1]);     \
+   span.blue = ChanToFixed(v2->color[2]);      \
+   span.alpha = ChanToFixed(v2->color[3]);     \
+   span.redStep = 0;                           \
+   span.greenStep = 0;                         \
+   span.blueStep = 0;                          \
+   span.alphaStep = 0;
+#define RENDER_SPAN( span )  _swrast_write_rgba_span(ctx, &span);
 #include "s_tritemp.h"
 
-   ASSERT(!ctx->Texture._ReallyEnabled);  /* texturing must be off */
-   ASSERT(ctx->Light.ShadeModel==GL_FLAT);
-}
-
 
 
 /*
  * Render a smooth-shaded RGBA triangle.
  */
-static void smooth_rgba_triangle( GLcontext *ctx,
-                                 const SWvertex *v0,
-                                 const SWvertex *v1,
-                                 const SWvertex *v2 )
-{
-
+#define NAME smooth_rgba_triangle
 #define INTERP_Z 1
 #define INTERP_FOG 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
 #define INTERP_RGB 1
 #define INTERP_ALPHA 1
-
-#define RENDER_SPAN( span )                                    \
-   GLuint i;                                                   \
-   SW_SPAN_SET_FLAG(span.filledColor);                         \
-   for (i = 0; i < span.end; i++) {                            \
-      span.color.rgba[i][RCOMP] = FixedToChan(span.red);       \
-      span.color.rgba[i][GCOMP] = FixedToChan(span.green);     \
-      span.color.rgba[i][BCOMP] = FixedToChan(span.blue);      \
-      span.color.rgba[i][ACOMP] = FixedToChan(span.alpha);     \
-      span.red += span.redStep;                                        \
-      span.green += span.greenStep;                            \
-      span.blue += span.blueStep;                              \
-      span.alpha += span.alphaStep;                            \
-   }                                                           \
-   _mesa_write_rgba_span(ctx, &span, GL_POLYGON);
-
+#define SETUP_CODE                             \
+   {                                           \
+      /* texturing must be off */              \
+      ASSERT(ctx->Texture._EnabledCoordUnits == 0);    \
+      ASSERT(ctx->Light.ShadeModel==GL_SMOOTH);        \
+   }
+#define RENDER_SPAN( span )  _swrast_write_rgba_span(ctx, &span);
 #include "s_tritemp.h"
 
-   ASSERT(!ctx->Texture._ReallyEnabled);  /* texturing must be off */
-   ASSERT(ctx->Light.ShadeModel==GL_SMOOTH);
-}
 
 
 /*
@@ -180,11 +145,7 @@ static void smooth_rgba_triangle( GLcontext *ctx,
  *
  * No fog.
  */
-static void simple_textured_triangle( GLcontext *ctx,
-                                     const SWvertex *v0,
-                                     const SWvertex *v1,
-                                     const SWvertex *v2 )
-{
+#define NAME simple_textured_triangle
 #define INTERP_INT_TEX 1
 #define S_SCALE twidth
 #define T_SCALE theight
@@ -192,13 +153,13 @@ static void simple_textured_triangle( GLcontext *ctx,
 #define SETUP_CODE                                                     \
    SWcontext *swrast = SWRAST_CONTEXT(ctx);                             \
    struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D;     \
-   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;                 \
-   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 b = obj->BaseLevel;                                     \
+   const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width;           \
+   const GLfloat theight = (GLfloat) obj->Image[0][b]->Height;         \
+   const GLint twidth_log2 = obj->Image[0][b]->WidthLog2;                      \
+   const GLchan *texture = (const GLchan *) obj->Image[0][b]->Data;    \
+   const GLint smask = obj->Image[0][b]->Width - 1;                    \
+   const GLint tmask = obj->Image[0][b]->Height - 1;                   \
    if (!texture) {                                                     \
       /* this shouldn't happen */                                      \
       return;                                                          \
@@ -206,7 +167,6 @@ static void simple_textured_triangle( GLcontext *ctx,
 
 #define RENDER_SPAN( span  )                                           \
    GLuint i;                                                           \
-   SW_SPAN_SET_FLAG(span.filledColor);                                 \
    span.intTex[0] -= FIXED_HALF; /* off-by-one error? */               \
    span.intTex[1] -= FIXED_HALF;                                       \
    for (i = 0; i < span.end; i++) {                                    \
@@ -214,17 +174,17 @@ static void simple_textured_triangle( GLcontext *ctx,
       GLint t = FixedToInt(span.intTex[1]) & tmask;                    \
       GLint pos = (t << twidth_log2) + s;                              \
       pos = pos + pos + pos;  /* multiply by 3 */                      \
-      span.color.rgb[i][RCOMP] = texture[pos];                         \
-      span.color.rgb[i][GCOMP] = texture[pos+1];                       \
-      span.color.rgb[i][BCOMP] = texture[pos+2];                       \
+      span.array->rgb[i][RCOMP] = texture[pos];                                \
+      span.array->rgb[i][GCOMP] = texture[pos+1];                      \
+      span.array->rgb[i][BCOMP] = texture[pos+2];                      \
       span.intTex[0] += span.intTexStep[0];                            \
       span.intTex[1] += span.intTexStep[1];                            \
    }                                                                   \
    (*swrast->Driver.WriteRGBSpan)(ctx, span.end, span.x, span.y,       \
-                                  (CONST GLchan (*)[3]) span.color.rgb, NULL );
-
+                                  (CONST GLchan (*)[3]) span.array->rgb,\
+                                  NULL );
 #include "s_tritemp.h"
-}
+
 
 
 /*
@@ -234,11 +194,7 @@ static void simple_textured_triangle( GLcontext *ctx,
  *
  * No fog.
  */
-static void simple_z_textured_triangle( GLcontext *ctx,
-                                       const SWvertex *v0,
-                                       const SWvertex *v1,
-                                       const SWvertex *v2 )
-{
+#define NAME simple_z_textured_triangle
 #define INTERP_Z 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
 #define INTERP_INT_TEX 1
@@ -248,13 +204,13 @@ static void simple_z_textured_triangle( GLcontext *ctx,
 #define SETUP_CODE                                                     \
    SWcontext *swrast = SWRAST_CONTEXT(ctx);                             \
    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;                       \
-   const GLchan *texture = (const GLchan *) obj->Image[b]->Data;       \
-   GLint smask = obj->Image[b]->Width - 1;                             \
-   GLint tmask = obj->Image[b]->Height - 1;                            \
+   const GLint b = obj->BaseLevel;                                     \
+   const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width;           \
+   const GLfloat theight = (GLfloat) obj->Image[0][b]->Height;         \
+   const GLint twidth_log2 = obj->Image[0][b]->WidthLog2;                      \
+   const GLchan *texture = (const GLchan *) obj->Image[0][b]->Data;    \
+   const GLint smask = obj->Image[0][b]->Width - 1;                    \
+   const GLint tmask = obj->Image[0][b]->Height - 1;                   \
    if (!texture) {                                                     \
       /* this shouldn't happen */                                      \
       return;                                                          \
@@ -264,7 +220,6 @@ static void simple_z_textured_triangle( GLcontext *ctx,
    GLuint i;                                                           \
    span.intTex[0] -= FIXED_HALF; /* off-by-one error? */               \
    span.intTex[1] -= FIXED_HALF;                                       \
-   SW_SPAN_SET_FLAG(span.filledColor);                                 \
    for (i = 0; i < span.end; i++) {                                    \
       const GLdepth z = FixedToDepth(span.z);                          \
       if (z < zRow[i]) {                                               \
@@ -272,24 +227,24 @@ static void simple_z_textured_triangle( GLcontext *ctx,
          GLint t = FixedToInt(span.intTex[1]) & tmask;                 \
          GLint pos = (t << twidth_log2) + s;                           \
          pos = pos + pos + pos;  /* multiply by 3 */                   \
-         span.color.rgb[i][RCOMP] = texture[pos];                      \
-         span.color.rgb[i][GCOMP] = texture[pos+1];                    \
-         span.color.rgb[i][BCOMP] = texture[pos+2];                    \
+         span.array->rgb[i][RCOMP] = texture[pos];                     \
+         span.array->rgb[i][GCOMP] = texture[pos+1];                   \
+         span.array->rgb[i][BCOMP] = texture[pos+2];                   \
          zRow[i] = z;                                                  \
-         span.mask[i] = 1;                                             \
+         span.array->mask[i] = 1;                                      \
       }                                                                        \
       else {                                                           \
-         span.mask[i] = 0;                                             \
+         span.array->mask[i] = 0;                                      \
       }                                                                        \
       span.intTex[0] += span.intTexStep[0];                            \
       span.intTex[1] += span.intTexStep[1];                            \
       span.z += span.zStep;                                            \
    }                                                                   \
    (*swrast->Driver.WriteRGBSpan)(ctx, span.end, span.x, span.y,       \
-                                  (CONST GLchan (*)[3]) span.color.rgb, span.mask );
-
+                                  (CONST GLchan (*)[3]) span.array->rgb,\
+                                  span.array->mask );
 #include "s_tritemp.h"
-}
+
 
 
 #if CHAN_TYPE != GL_FLOAT
@@ -392,7 +347,12 @@ affine_span(GLcontext *ctx, struct sw_span *span,
 
 /* shortcuts */
 
-#define NEAREST_RGB_REPLACE  NEAREST_RGB;REPLACE
+#define NEAREST_RGB_REPLACE            \
+   NEAREST_RGB;                                \
+   dest[0] = sample[0];                        \
+   dest[1] = sample[1];                        \
+   dest[2] = sample[2];                        \
+   dest[3] = FixedToInt(span->alpha);
 
 #define NEAREST_RGBA_REPLACE  COPY_CHAN4(dest, tex00)
 
@@ -449,9 +409,7 @@ affine_span(GLcontext *ctx, struct sw_span *span,
 
 
    GLuint i;
-   GLchan *dest = span->color.rgba[0];
-
-   SW_SPAN_SET_FLAG(span->filledColor);
+   GLchan *dest = span->array->rgba[0];
 
    span->intTex[0] -= FIXED_HALF;
    span->intTex[1] -= FIXED_HALF;
@@ -474,7 +432,8 @@ affine_span(GLcontext *ctx, struct sw_span *span,
             SPAN_NEAREST(NEAREST_RGB;ADD,3);
             break;
          default:
-            abort();
+            _mesa_problem(ctx, "bad tex env mode in SPAN_LINEAR");
+            return;
          }
          break;
       case GL_RGBA:
@@ -495,7 +454,8 @@ affine_span(GLcontext *ctx, struct sw_span *span,
             SPAN_NEAREST(NEAREST_RGBA_REPLACE,4);
             break;
          default:
-            abort();
+            _mesa_problem(ctx, "bad tex env mode (2) in SPAN_LINEAR");
+            return;
          }
          break;
       }
@@ -521,7 +481,8 @@ affine_span(GLcontext *ctx, struct sw_span *span,
             SPAN_LINEAR(LINEAR_RGB;ADD,3);
             break;
          default:
-            abort();
+            _mesa_problem(ctx, "bad tex env mode (3) in SPAN_LINEAR");
+            return;
          }
          break;
       case GL_RGBA:
@@ -542,12 +503,16 @@ affine_span(GLcontext *ctx, struct sw_span *span,
             SPAN_LINEAR(LINEAR_RGBA;REPLACE,4);
             break;
          default:
-            abort();
-         }                 break;
+            _mesa_problem(ctx, "bad tex env mode (4) in SPAN_LINEAR");
+            return;
+         }
+         break;
       }
       break;
    }
-   _mesa_write_rgba_span(ctx, span, GL_POLYGON);
+   span->interpMask &= ~SPAN_RGBA;
+   ASSERT(span->arrayMask & SPAN_RGBA);
+   _swrast_write_rgba_span(ctx, span);
 
 #undef SPAN_NEAREST
 #undef SPAN_LINEAR
@@ -558,11 +523,7 @@ affine_span(GLcontext *ctx, struct sw_span *span,
 /*
  * Render an RGB/RGBA textured triangle without perspective correction.
  */
-static void affine_textured_triangle( GLcontext *ctx,
-                                     const SWvertex *v0,
-                                     const SWvertex *v1,
-                                     const SWvertex *v2 )
-{
+#define NAME affine_textured_triangle
 #define INTERP_Z 1
 #define INTERP_FOG 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
@@ -576,16 +537,17 @@ static void affine_textured_triangle( GLcontext *ctx,
    struct affine_info info;                                            \
    struct gl_texture_unit *unit = ctx->Texture.Unit+0;                 \
    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;                  \
-   info.texture = (const GLchan *) obj->Image[b]->Data;                        \
-   info.twidth_log2 = obj->Image[b]->WidthLog2;                                \
-   info.smask = obj->Image[b]->Width - 1;                              \
-   info.tmask = obj->Image[b]->Height - 1;                             \
-   info.format = obj->Image[b]->Format;                                        \
+   const GLint b = obj->BaseLevel;                                     \
+   const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width;           \
+   const GLfloat theight = (GLfloat) obj->Image[0][b]->Height;         \
+   info.texture = (const GLchan *) obj->Image[0][b]->Data;                     \
+   info.twidth_log2 = obj->Image[0][b]->WidthLog2;                             \
+   info.smask = obj->Image[0][b]->Width - 1;                           \
+   info.tmask = obj->Image[0][b]->Height - 1;                          \
+   info.format = obj->Image[0][b]->Format;                                     \
    info.filter = obj->MinFilter;                                       \
    info.envmode = unit->EnvMode;                                       \
+   span.arrayMask |= SPAN_RGBA;                                                \
                                                                        \
    if (info.envmode == GL_BLEND) {                                     \
       /* potential off-by-one error here? (1.0f -> 2048 -> 0) */       \
@@ -603,29 +565,27 @@ static void affine_textured_triangle( GLcontext *ctx,
    case GL_ALPHA:                                                      \
    case GL_LUMINANCE:                                                  \
    case GL_INTENSITY:                                                  \
-      info.tbytesline = obj->Image[b]->Width;                          \
+      info.tbytesline = obj->Image[0][b]->Width;                               \
       break;                                                           \
    case GL_LUMINANCE_ALPHA:                                            \
-      info.tbytesline = obj->Image[b]->Width * 2;                      \
+      info.tbytesline = obj->Image[0][b]->Width * 2;                   \
       break;                                                           \
    case GL_RGB:                                                                \
-      info.tbytesline = obj->Image[b]->Width * 3;                      \
+      info.tbytesline = obj->Image[0][b]->Width * 3;                   \
       break;                                                           \
    case GL_RGBA:                                                       \
-      info.tbytesline = obj->Image[b]->Width * 4;                      \
+      info.tbytesline = obj->Image[0][b]->Width * 4;                   \
       break;                                                           \
    default:                                                            \
       _mesa_problem(NULL, "Bad texture format in affine_texture_triangle");\
       return;                                                          \
    }                                                                   \
-   info.tsize = obj->Image[b]->Height * info.tbytesline;
+   info.tsize = obj->Image[0][b]->Height * info.tbytesline;
 
 #define RENDER_SPAN( span )   affine_span(ctx, &span, &info);
 
 #include "s_tritemp.h"
 
-}
-
 
 
 struct persp_info
@@ -715,17 +675,15 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span,
 
    GLuint i;
    GLfloat tex_coord[3], tex_step[3];
-   GLchan *dest = span->color.rgba[0];
-
-   SW_SPAN_SET_FLAG(span->filledColor);
+   GLchan *dest = span->array->rgba[0];
 
-   tex_coord[0] = span->tex[0][0]  * (info->smask + 1),
-     tex_step[0] = span->texStep[0][0] * (info->smask + 1);
-   tex_coord[1] = span->tex[0][1] * (info->tmask + 1),
-     tex_step[1] = span->texStep[0][1] * (info->tmask + 1);
+   tex_coord[0] = span->tex[0][0]  * (info->smask + 1);
+   tex_step[0] = span->texStepX[0][0] * (info->smask + 1);
+   tex_coord[1] = span->tex[0][1] * (info->tmask + 1);
+   tex_step[1] = span->texStepX[0][1] * (info->tmask + 1);
    /* span->tex[0][2] only if 3D-texturing, here only 2D */
-   tex_coord[2] = span->tex[0][3],
-     tex_step[2] = span->texStep[0][3];
+   tex_coord[2] = span->tex[0][3];
+   tex_step[2] = span->texStepX[0][3];
 
    switch (info->filter) {
    case GL_NEAREST:
@@ -746,7 +704,8 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span,
             SPAN_NEAREST(NEAREST_RGB;ADD,3);
             break;
          default:
-            abort();
+            _mesa_problem(ctx, "bad tex env mode (5) in SPAN_LINEAR");
+            return;
          }
          break;
       case GL_RGBA:
@@ -767,7 +726,8 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span,
             SPAN_NEAREST(NEAREST_RGBA_REPLACE,4);
             break;
          default:
-            abort();
+            _mesa_problem(ctx, "bad tex env mode (6) in SPAN_LINEAR");
+            return;
          }
          break;
       }
@@ -791,7 +751,8 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span,
             SPAN_LINEAR(LINEAR_RGB;ADD,3);
             break;
          default:
-            abort();
+            _mesa_problem(ctx, "bad tex env mode (7) in SPAN_LINEAR");
+            return;
          }
          break;
       case GL_RGBA:
@@ -812,15 +773,16 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span,
             SPAN_LINEAR(LINEAR_RGBA;REPLACE,4);
             break;
          default:
-            abort();
+            _mesa_problem(ctx, "bad tex env mode (8) in SPAN_LINEAR");
+            return;
          }
          break;
       }
       break;
    }
    
-   _mesa_write_rgba_span(ctx, span, GL_POLYGON);
-
+   ASSERT(span->arrayMask & SPAN_RGBA);
+   _swrast_write_rgba_span(ctx, span);
 
 #undef SPAN_NEAREST
 #undef SPAN_LINEAR
@@ -833,11 +795,7 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span,
  * by interpolated Q/W comes out right.
  *
  */
-static void persp_textured_triangle( GLcontext *ctx,
-                                    const SWvertex *v0,
-                                    const SWvertex *v1,
-                                    const SWvertex *v2 )
-{
+#define NAME persp_textured_triangle
 #define INTERP_Z 1
 #define INTERP_FOG 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
@@ -847,14 +805,14 @@ static void persp_textured_triangle( GLcontext *ctx,
 
 #define SETUP_CODE                                                     \
    struct persp_info info;                                             \
-   struct gl_texture_unit *unit = ctx->Texture.Unit+0;                 \
-   struct gl_texture_object *obj = unit->Current2D;                    \
-   GLint b = obj->BaseLevel;                                           \
-   info.texture = (const GLchan *) obj->Image[b]->Data;                        \
-   info.twidth_log2 = obj->Image[b]->WidthLog2;                                \
-   info.smask = obj->Image[b]->Width - 1;                              \
-   info.tmask = obj->Image[b]->Height - 1;                             \
-   info.format = obj->Image[b]->Format;                                        \
+   const struct gl_texture_unit *unit = ctx->Texture.Unit+0;           \
+   const struct gl_texture_object *obj = unit->Current2D;              \
+   const GLint b = obj->BaseLevel;                                     \
+   info.texture = (const GLchan *) obj->Image[0][b]->Data;                     \
+   info.twidth_log2 = obj->Image[0][b]->WidthLog2;                             \
+   info.smask = obj->Image[0][b]->Width - 1;                           \
+   info.tmask = obj->Image[0][b]->Height - 1;                          \
+   info.format = obj->Image[0][b]->Format;                                     \
    info.filter = obj->MinFilter;                                       \
    info.envmode = unit->EnvMode;                                       \
                                                                        \
@@ -874,29 +832,30 @@ static void persp_textured_triangle( GLcontext *ctx,
    case GL_ALPHA:                                                      \
    case GL_LUMINANCE:                                                  \
    case GL_INTENSITY:                                                  \
-      info.tbytesline = obj->Image[b]->Width;                          \
+      info.tbytesline = obj->Image[0][b]->Width;                               \
       break;                                                           \
    case GL_LUMINANCE_ALPHA:                                            \
-      info.tbytesline = obj->Image[b]->Width * 2;                      \
+      info.tbytesline = obj->Image[0][b]->Width * 2;                   \
       break;                                                           \
    case GL_RGB:                                                                \
-      info.tbytesline = obj->Image[b]->Width * 3;                      \
+      info.tbytesline = obj->Image[0][b]->Width * 3;                   \
       break;                                                           \
    case GL_RGBA:                                                       \
-      info.tbytesline = obj->Image[b]->Width * 4;                      \
+      info.tbytesline = obj->Image[0][b]->Width * 4;                   \
       break;                                                           \
    default:                                                            \
       _mesa_problem(NULL, "Bad texture format in persp_textured_triangle");\
       return;                                                          \
    }                                                                   \
-   info.tsize = obj->Image[b]->Height * info.tbytesline;
+   info.tsize = obj->Image[0][b]->Height * info.tbytesline;
 
-#define RENDER_SPAN( span )   fast_persp_span(ctx, &span, &info);
+#define RENDER_SPAN( span )                    \
+   span.interpMask &= ~SPAN_RGBA;              \
+   span.arrayMask |= SPAN_RGBA;                        \
+   fast_persp_span(ctx, &span, &info);
 
 #include "s_tritemp.h"
 
-}
-
 
 #endif /* CHAN_BITS != GL_FLOAT */
 
@@ -907,240 +866,69 @@ static void persp_textured_triangle( GLcontext *ctx,
  * Render a smooth-shaded, textured, RGBA triangle.
  * Interpolate S,T,R with perspective correction, w/out mipmapping.
  */
-static void general_textured_triangle( GLcontext *ctx,
-                                      const SWvertex *v0,
-                                      const SWvertex *v1,
-                                      const SWvertex *v2 )
-{
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define INTERP_TEX 1
-
-#define SETUP_CODE                                                     \
-   const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;        \
-   const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];\
-   span.texWidth[0] = (GLfloat) texImage->Width;                       \
-   span.texHeight[0] = (GLfloat) texImage->Height;                     \
-   (void) fixedToDepthShift;
-
-#define RENDER_SPAN( span )                                            \
-   GLfloat fogSpan[MAX_WIDTH];                                         \
-   GLuint i;                                                           \
-   SW_SPAN_SET_FLAG(span.filledColor);                                 \
-   SW_SPAN_SET_FLAG(span.filledTex[0]);                                        \
-   /* NOTE: we could just call rasterize_span() here instead */                \
-   for (i = 0; i < span.end; i++) {                                    \
-      GLdouble invQ = span.tex[0][3] ? (1.0 / span.tex[0][3]) : 1.0;   \
-      span.depth[i] = FixedToDepth(span.z);                            \
-      span.z += span.zStep;                                            \
-      fogSpan[i] = span.fog;                                           \
-      span.fog += span.fogStep;                                        \
-      span.color.rgba[i][RCOMP] = FixedToChan(span.red);               \
-      span.color.rgba[i][GCOMP] = FixedToChan(span.green);             \
-      span.color.rgba[i][BCOMP] = FixedToChan(span.blue);              \
-      span.color.rgba[i][ACOMP] = FixedToChan(span.alpha);             \
-      span.red += span.redStep;                                        \
-      span.green += span.greenStep;                                    \
-      span.blue += span.blueStep;                                      \
-      span.alpha += span.alphaStep;                                    \
-      span.texcoords[0][i][0] = (GLfloat) (span.tex[0][0] * invQ);     \
-      span.texcoords[0][i][1] = (GLfloat) (span.tex[0][1] * invQ);     \
-      span.texcoords[0][i][2] = (GLfloat) (span.tex[0][2] * invQ);     \
-      span.tex[0][0] += span.texStep[0][0];                            \
-      span.tex[0][1] += span.texStep[0][1];                            \
-      span.tex[0][2] += span.texStep[0][2];                            \
-      span.tex[0][3] += span.texStep[0][3];                            \
-   }                                                                   \
-   _old_write_texture_span( ctx, span.end, span.x, span.y,             \
-                            span.depth, fogSpan,                       \
-                           span.texcoords[0],                          \
-                            NULL, span.color.rgba, NULL, NULL, GL_POLYGON );
-
-#define CLEANUP_CODE                           \
-   UNDEFARRAY(sSpan);  /* mac 32k limitation */        \
-   UNDEFARRAY(tSpan);                          \
-   UNDEFARRAY(uSpan);
-
-#include "s_tritemp.h"
-}
-
-
-/*
- * Render a smooth-shaded, textured, RGBA triangle with separate specular
- * color interpolation.
- * Interpolate texcoords with perspective correction, w/out mipmapping.
- */
-static void general_textured_spec_triangle( GLcontext *ctx,
-                                           const SWvertex *v0,
-                                           const SWvertex *v1,
-                                           const SWvertex *v2 )
-{
+#define NAME general_textured_triangle
 #define INTERP_Z 1
+#define INTERP_W 1
 #define INTERP_FOG 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
 #define INTERP_RGB 1
 #define INTERP_SPEC 1
 #define INTERP_ALPHA 1
 #define INTERP_TEX 1
-
-#define SETUP_CODE                                                     \
-   const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;        \
-   const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];\
-   span.texWidth[0] = (GLfloat) texImage->Width;                       \
-   span.texHeight[0] = (GLfloat) texImage->Height;                     \
-   (void) fixedToDepthShift;
-
-#define RENDER_SPAN( span )   _mesa_rasterize_span(ctx, &span);
-
+#define RENDER_SPAN( span )   _swrast_write_texture_span(ctx, &span);
 #include "s_tritemp.h"
-}
-
-
-/*
- * Render a smooth-shaded, textured, RGBA triangle.
- * Interpolate S,T,R with perspective correction and compute lambda for
- * each fragment.  Lambda is used to determine whether to use the
- * minification or magnification filter.  If minification and using
- * mipmaps, lambda is also used to select the texture level of detail.
- */
-static void lambda_textured_triangle( GLcontext *ctx,
-                                     const SWvertex *v0,
-                                     const SWvertex *v1,
-                                     const SWvertex *v2 )
-{
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#define INTERP_RGB 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_image *texImage = obj->Image[obj->BaseLevel];\
-   span.texWidth[0] = (GLfloat) texImage->Width;                       \
-   span.texHeight[0] = (GLfloat) texImage->Height;                     \
-   (void) fixedToDepthShift;
-
-#define RENDER_SPAN( span )   _mesa_rasterize_span(ctx, &span);
-
-#include "s_tritemp.h"
-}
-
-
-/*
- * Render a smooth-shaded, textured, RGBA triangle with separate specular
- * interpolation.
- * Interpolate S,T,R with perspective correction and compute lambda for
- * each fragment.  Lambda is used to determine whether to use the
- * 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_triangle( GLcontext *ctx,
-                                          const SWvertex *v0,
-                                          const SWvertex *v1,
-                                          const SWvertex *v2 )
-{
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#define INTERP_RGB 1
-#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_image *texImage = obj->Image[obj->BaseLevel];\
-   span.texWidth[0] = (GLfloat) texImage->Width;                       \
-   span.texHeight[0] = (GLfloat) texImage->Height;                     \
-   (void) fixedToDepthShift;
 
-#define RENDER_SPAN( span )   _mesa_rasterize_span(ctx, &span);
-
-#include "s_tritemp.h"
-}
 
 
 /*
  * This is the big one!
- * Interpolate Z, RGB, Alpha, specular, fog, and N sets of texture coordinates
- * with lambda (LOD).
+ * Interpolate Z, RGB, Alpha, specular, fog, and N sets of texture coordinates.
  * Yup, it's slow.
  */
-static void
-lambda_multitextured_triangle( GLcontext *ctx,
-                               const SWvertex *v0,
-                               const SWvertex *v1,
-                               const SWvertex *v2 )
-{
-
+#define NAME multitextured_triangle
 #define INTERP_Z 1
+#define INTERP_W 1
 #define INTERP_FOG 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
 #define INTERP_RGB 1
 #define INTERP_ALPHA 1
 #define INTERP_SPEC 1
 #define INTERP_MULTITEX 1
-#define INTERP_LAMBDA 1
-
-#define SETUP_CODE                                                     \
-   GLuint u;                                                           \
-   for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {                  \
-      if (ctx->Texture.Unit[u]._ReallyEnabled) {                       \
-         const struct gl_texture_object *texObj;                       \
-         const struct gl_texture_image *texImage;                      \
-         texObj = ctx->Texture.Unit[u]._Current;                       \
-         texImage = texObj->Image[texObj->BaseLevel];                  \
-         span.texWidth[u] = (GLfloat) texImage->Width;                 \
-         span.texHeight[u] = (GLfloat) texImage->Height;               \
-      }                                                                        \
-   }                                                                   \
-   (void) fixedToDepthShift;
-
-#define RENDER_SPAN( span )   _mesa_rasterize_span(ctx, &span);
-
+#define RENDER_SPAN( span )   _swrast_write_texture_span(ctx, &span);
 #include "s_tritemp.h"
 
-}
 
 
-static void occlusion_zless_triangle( GLcontext *ctx,
-                                     const SWvertex *v0,
-                                     const SWvertex *v1,
-                                     const SWvertex *v2 )
-{
-   if (ctx->OcclusionResult) {
-      return;
-   }
-
+/*
+ * Special tri function for occlusion testing
+ */
+#define NAME occlusion_zless_triangle
 #define DO_OCCLUSION_TEST
 #define INTERP_Z 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-
+#define SETUP_CODE                                             \
+   if (ctx->OcclusionResult && !ctx->Occlusion.Active) {       \
+      return;                                                  \
+   }
 #define RENDER_SPAN( span )                            \
    GLuint i;                                           \
    for (i = 0; i < span.end; i++) {                    \
-      GLdepth z = FixedToDepth(span.z);                \
+      GLdepth z = FixedToDepth(span.z);                        \
       if (z < zRow[i]) {                               \
          ctx->OcclusionResult = GL_TRUE;               \
-         return;                                       \
+         ctx->Occlusion.PassedCounter++;               \
       }                                                        \
       span.z += span.zStep;                            \
    }
-
 #include "s_tritemp.h"
-}
 
-static void nodraw_triangle( GLcontext *ctx,
-                            const SWvertex *v0,
-                            const SWvertex *v1,
-                            const SWvertex *v2 )
+
+
+static void
+nodraw_triangle( GLcontext *ctx,
+                 const SWvertex *v0,
+                 const SWvertex *v1,
+                 const SWvertex *v2 )
 {
    (void) (ctx && v0 && v1 && v2);
 }
@@ -1206,11 +994,11 @@ void _swrast_add_spec_terms_triangle( GLcontext *ctx,
 /* record the current triangle function name */
 const char *_mesa_triFuncName = NULL;
 
-#define USE(triFunc)                   \
-do {                                   \
-    _mesa_triFuncName = #triFunc;      \
-    /*printf("%s\n", triFuncName);*/   \
-    swrast->Triangle = triFunc;        \
+#define USE(triFunc)                           \
+do {                                           \
+    _mesa_triFuncName = #triFunc;              \
+    /*printf("%s\n", _mesa_triFuncName);*/     \
+    swrast->Triangle = triFunc;                        \
 } while (0)
 
 #else
@@ -1244,12 +1032,13 @@ _swrast_choose_triangle( GLcontext *ctx )
    if (ctx->RenderMode==GL_RENDER) {
 
       if (ctx->Polygon.SmoothFlag) {
-         _mesa_set_aa_triangle_function(ctx);
+         _swrast_set_aa_triangle_function(ctx);
          ASSERT(swrast->Triangle);
          return;
       }
 
-      if (ctx->Depth.OcclusionTest &&
+      /* special case for occlusion testing */
+      if ((ctx->Depth.OcclusionTest || ctx->Occlusion.Active) &&
           ctx->Depth.Test &&
           ctx->Depth.Mask == GL_FALSE &&
           ctx->Depth.Func == GL_LESS &&
@@ -1266,24 +1055,28 @@ _swrast_choose_triangle( GLcontext *ctx )
          }
       }
 
-      if (ctx->Texture._ReallyEnabled) {
+      if (ctx->Texture._EnabledCoordUnits || ctx->FragmentProgram.Enabled) {
          /* Ugh, we do a _lot_ of tests to pick the best textured tri func */
         const struct gl_texture_object *texObj2D;
          const struct gl_texture_image *texImg;
          GLenum minFilter, magFilter, envMode;
          GLint format;
          texObj2D = ctx->Texture.Unit[0].Current2D;
-         texImg = texObj2D ? texObj2D->Image[texObj2D->BaseLevel] : NULL;
+         texImg = texObj2D ? texObj2D->Image[0][texObj2D->BaseLevel] : NULL;
          format = texImg ? texImg->TexFormat->MesaFormat : -1;
          minFilter = texObj2D ? texObj2D->MinFilter : (GLenum) 0;
          magFilter = texObj2D ? texObj2D->MagFilter : (GLenum) 0;
          envMode = ctx->Texture.Unit[0].EnvMode;
 
-         /* First see if we can used an optimized 2-D texture function */
-         if (ctx->Texture._ReallyEnabled==TEXTURE0_2D
+         /* First see if we can use an optimized 2-D texture function */
+         if (ctx->Texture._EnabledCoordUnits == 1
+             && !ctx->FragmentProgram.Enabled
+             && ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT
              && texObj2D->WrapS==GL_REPEAT
             && texObj2D->WrapT==GL_REPEAT
+             && texObj2D->_IsPowerOfTwo
              && texImg->Border==0
+             && texImg->Width == texImg->RowStride
              && (format == MESA_FORMAT_RGB || format == MESA_FORMAT_RGBA)
             && minFilter == magFilter
             && ctx->Light.Model.ColorControl == GL_SINGLE_COLOR
@@ -1305,7 +1098,7 @@ _swrast_choose_triangle( GLcontext *ctx )
                  }
               }
               else {
-#if CHAN_TYPE == GL_FLOAT
+#if (CHAN_BITS == 16 || CHAN_BITS == 32)
                   USE(general_textured_triangle);
 #else
                   USE(affine_textured_triangle);
@@ -1313,7 +1106,7 @@ _swrast_choose_triangle( GLcontext *ctx )
               }
            }
            else {
-#if CHAN_TYPE == GL_FLOAT
+#if (CHAN_BITS == 16 || CHAN_BITS == 32)
                USE(general_textured_triangle);
 #else
                USE(persp_textured_triangle);
@@ -1321,38 +1114,17 @@ _swrast_choose_triangle( GLcontext *ctx )
            }
         }
          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;
-            if (obj && obj->MinFilter != obj->MagFilter)
-               needLambda = GL_TRUE;
-            else
-               needLambda = GL_FALSE;
-            if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) {
-               USE(lambda_multitextured_triangle);
-            }
-            else if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
-               /* separate specular color interpolation */
-               if (needLambda) {
-                  USE(lambda_textured_spec_triangle);
-              }
-               else {
-                  USE(general_textured_spec_triangle);
-              }
+            /* general case textured triangles */
+            if (ctx->Texture._EnabledCoordUnits > 1) {
+               USE(multitextured_triangle);
             }
             else {
-               if (needLambda) {
-                 USE(lambda_textured_triangle);
-              }
-               else {
-                  USE(general_textured_triangle);
-              }
+               USE(general_textured_triangle);
             }
          }
       }
       else {
-         ASSERT(!ctx->Texture._ReallyEnabled);
+         ASSERT(!ctx->Texture._EnabledCoordUnits);
         if (ctx->Light.ShadeModel==GL_SMOOTH) {
            /* smooth shaded, no texturing, stippled or some raster ops */
             if (rgbmode) {
@@ -1374,10 +1146,10 @@ _swrast_choose_triangle( GLcontext *ctx )
       }
    }
    else if (ctx->RenderMode==GL_FEEDBACK) {
-      USE(_mesa_feedback_triangle);
+      USE(_swrast_feedback_triangle);
    }
    else {
       /* GL_SELECT mode */
-      USE(_mesa_select_triangle);
+      USE(_swrast_select_triangle);
    }
 }