Committing in .
[mesa.git] / src / mesa / swrast / s_lines.c
index 1cb9559683649e7d94f4702630b595ca9d4d2a72..4d9fe5892064acb9243034b5e19bae864646ef1d 100644 (file)
@@ -1,10 +1,8 @@
-/* $Id: s_lines.c,v 1.32 2002/10/30 19:59:33 brianp Exp $ */
-
 /*
  * Mesa 3-D graphics library
- * Version:  5.0
+ * 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"),
 
 
 #include "glheader.h"
+#include "context.h"
 #include "colormac.h"
 #include "macros.h"
-#include "mmath.h"
+#include "nvfragprog.h"
 #include "s_aaline.h"
 #include "s_context.h"
 #include "s_depth.h"
@@ -90,11 +89,11 @@ draw_wide_line( GLcontext *ctx, struct sw_span *span, GLboolean xMajor )
                y[i]++;
          }
          if ((span->interpMask | span->arrayMask) & SPAN_TEXTURE)
-            _mesa_write_texture_span(ctx, span);
+            _swrast_write_texture_span(ctx, span);
          else if ((span->interpMask | span->arrayMask) & SPAN_RGBA)
-            _mesa_write_rgba_span(ctx, span);
+            _swrast_write_rgba_span(ctx, span);
          else
-            _mesa_write_index_span(ctx, span);
+            _swrast_write_index_span(ctx, span);
       }
    }
    else {
@@ -111,11 +110,11 @@ draw_wide_line( GLcontext *ctx, struct sw_span *span, GLboolean xMajor )
                x[i]++;
          }
          if ((span->interpMask | span->arrayMask) & SPAN_TEXTURE)
-            _mesa_write_texture_span(ctx, span);
+            _swrast_write_texture_span(ctx, span);
          else if ((span->interpMask | span->arrayMask) & SPAN_RGBA)
-            _mesa_write_rgba_span(ctx, span);
+            _swrast_write_rgba_span(ctx, span);
          else
-            _mesa_write_index_span(ctx, span);
+            _swrast_write_index_span(ctx, span);
       }
    }
 }
@@ -126,608 +125,103 @@ draw_wide_line( GLcontext *ctx, struct sw_span *span, GLboolean xMajor )
 /*****                    Rasterization                           *****/
 /**********************************************************************/
 
-
-/* Flat, color index line */
-static void flat_ci_line( GLcontext *ctx,
-                          const SWvertex *vert0,
-                         const SWvertex *vert1 )
-{
-   GLint *x, *y;
-   struct sw_span span;
-
-   ASSERT(ctx->Light.ShadeModel == GL_FLAT);
-   ASSERT(!ctx->Line.StippleFlag);
-   ASSERT(ctx->Line.Width == 1.0F);
-
-   INIT_SPAN(span, GL_LINE, 0, SPAN_INDEX, SPAN_XY);
-   span.index = IntToFixed(vert1->index);
-   span.indexStep = 0;
-   x = span.array->x;
-   y = span.array->y;
-
-#define INTERP_XY 1
-#define PLOT(X,Y)              \
-   {                           \
-      x[span.end] = X;         \
-      y[span.end] = Y;         \
-      span.end++;              \
-   }
-
-#include "s_linetemp.h"
-
-   _mesa_write_index_span(ctx, &span);
-}
-
-
-/* Flat-shaded, RGBA line */
-static void flat_rgba_line( GLcontext *ctx,
-                            const SWvertex *vert0,
-                           const SWvertex *vert1 )
-{
-   struct sw_span span;
-   GLint *x, *y;
-
-   ASSERT(ctx->Light.ShadeModel == GL_FLAT);
-   ASSERT(!ctx->Line.StippleFlag);
-   ASSERT(ctx->Line.Width == 1.0F);
-
-   INIT_SPAN(span, GL_LINE, 0, SPAN_RGBA, SPAN_XY);
-   span.red = ChanToFixed(vert1->color[0]);
-   span.green = ChanToFixed(vert1->color[1]);
-   span.blue = ChanToFixed(vert1->color[2]);
-   span.alpha = ChanToFixed(vert1->color[3]);
-   span.redStep = 0;
-   span.greenStep = 0;
-   span.blueStep = 0;
-   span.alphaStep = 0;
-   x = span.array->x;
-   y = span.array->y;
-
-#define INTERP_XY 1
-#define PLOT(X,Y)              \
-   {                           \
-      x[span.end] = X;         \
-      y[span.end] = Y;         \
-      span.end++;              \
-   }
-
-#include "s_linetemp.h"
-
-   _mesa_write_rgba_span(ctx, &span);
-}
-
-
-/* Smooth shaded, color index line */
-static void smooth_ci_line( GLcontext *ctx,
-                            const SWvertex *vert0,
-                           const SWvertex *vert1 )
-{
-   struct sw_span span;
-   GLint *x, *y;
-   GLuint *index;
-
-   ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
-   ASSERT(!ctx->Line.StippleFlag);
-   ASSERT(ctx->Line.Width == 1.0F);
-
-   INIT_SPAN(span, GL_LINE, 0, 0, SPAN_XY | SPAN_INDEX);
-   x = span.array->x;
-   y = span.array->y;
-   index = span.array->index;
-
-#define INTERP_XY 1
-#define INTERP_INDEX 1
-#define PLOT(X,Y)              \
-   {                           \
-      x[span.end] = X;         \
-      y[span.end] = Y;         \
-      index[span.end] = I;     \
-      span.end++;              \
-   }
-
-#include "s_linetemp.h"
-
-   _mesa_write_index_span(ctx, &span);
-}
-
-
-/* Smooth-shaded, RGBA line */
-static void smooth_rgba_line( GLcontext *ctx,
-                                     const SWvertex *vert0,
-                             const SWvertex *vert1 )
-{
-   struct sw_span span;
-   GLint *x, *y;
-   GLchan (*rgba)[4];
-
-   ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
-   ASSERT(!ctx->Line.StippleFlag);
-   ASSERT(ctx->Line.Width == 1.0F);
-
-   INIT_SPAN(span, GL_LINE, 0, 0, SPAN_XY | SPAN_RGBA);
-   x = span.array->x;
-   y = span.array->y;
-   rgba = span.array->rgba;
-
-#define INTERP_XY 1
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define PLOT(X,Y)                              \
-   {                                           \
-      x[span.end] = X;                         \
-      y[span.end] = Y;                         \
-      rgba[span.end][RCOMP] = FixedToInt(r0);  \
-      rgba[span.end][GCOMP] = FixedToInt(g0);  \
-      rgba[span.end][BCOMP] = FixedToInt(b0);  \
-      rgba[span.end][ACOMP] = FixedToInt(a0);  \
-      span.end++;                              \
-   }
-
-#include "s_linetemp.h"
-
-   _mesa_write_rgba_span(ctx, &span);
-}
-
-
-/* Smooth shaded, color index, any width, maybe stippled */
-static void general_smooth_ci_line( GLcontext *ctx,
-                                   const SWvertex *vert0,
-                                   const SWvertex *vert1 )
-{
-   GLboolean xMajor = GL_FALSE;
-   struct sw_span span;
-   GLint *x, *y;
-   GLdepth *z;
-   GLfloat *fog;
-   GLuint *index;
-
-   ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
-
-   INIT_SPAN(span, GL_LINE, 0, 0,
-            SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_INDEX);
-   x = span.array->x;
-   y = span.array->y;
-   z = span.array->z;
-   fog = span.array->fog;
-   index = span.array->index;
-
-#define SET_XMAJOR 1
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_INDEX 1
-#define PLOT(X,Y)              \
-   {                           \
-      x[span.end] = X;         \
-      y[span.end] = Y;         \
-      z[span.end] = Z;         \
-      fog[span.end] = fog0;    \
-      index[span.end] = I;     \
-      span.end++;              \
-   }
-#include "s_linetemp.h"
-
-   if (ctx->Line.StippleFlag) {
-      span.arrayMask |= SPAN_MASK;
-      compute_stipple_mask(ctx, span.end, span.array->mask);
-   }
-
-   if (ctx->Line.Width > 1.0) {
-      draw_wide_line(ctx, &span, xMajor);
-   }
-   else {
-      _mesa_write_index_span(ctx, &span);
-   }
-}
-
-
-/* Flat shaded, color index, any width, maybe stippled */
-static void general_flat_ci_line( GLcontext *ctx,
-                                  const SWvertex *vert0,
-                                 const SWvertex *vert1 )
-{
-   GLboolean xMajor = GL_FALSE;
-   struct sw_span span;
-   GLint *x, *y;
-   GLdepth *z;
-   GLfloat *fog;
-
-   ASSERT(ctx->Light.ShadeModel == GL_FLAT);
-
-   INIT_SPAN(span, GL_LINE, 0, SPAN_INDEX,
-            SPAN_XY | SPAN_Z | SPAN_FOG);
-   span.index = IntToFixed(vert1->index);
-   span.indexStep = 0;
-   x = span.array->x;
-   y = span.array->y;
-   z = span.array->z;
-   fog = span.array->fog;
-
-#define SET_XMAJOR 1
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define PLOT(X,Y)              \
-   {                           \
-      x[span.end] = X;         \
-      y[span.end] = Y;         \
-      z[span.end] = Z;         \
-      fog[span.end] = fog0;    \
-      span.end++;              \
-   }
-#include "s_linetemp.h"
-
-   if (ctx->Line.StippleFlag) {
-      span.arrayMask |= SPAN_MASK;
-      compute_stipple_mask(ctx, span.end, span.array->mask);
-   }
-
-   if (ctx->Line.Width > 1.0) {
-      draw_wide_line(ctx, &span, xMajor);
-   }
-   else {
-      _mesa_write_index_span(ctx, &span);
-   }
-}
-
-
-
-static void general_smooth_rgba_line( GLcontext *ctx,
-                                      const SWvertex *vert0,
-                                     const SWvertex *vert1 )
-{
-   GLboolean xMajor = GL_FALSE;
-   struct sw_span span;
-   GLint *x, *y;
-   GLdepth *z;
-   GLchan (*rgba)[4];
-   GLfloat *fog;
-
-   ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
-
-   INIT_SPAN(span, GL_LINE, 0, 0,
-            SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_RGBA);
-   x = span.array->x;
-   y = span.array->y;
-   z = span.array->z;
-   rgba = span.array->rgba;
-   fog = span.array->fog;
-
-#define SET_XMAJOR 1
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define PLOT(X,Y)                              \
-   {                                           \
-      x[span.end] = X;                         \
-      y[span.end] = Y;                         \
-      z[span.end] = Z;                         \
-      rgba[span.end][RCOMP] = FixedToInt(r0);  \
-      rgba[span.end][GCOMP] = FixedToInt(g0);  \
-      rgba[span.end][BCOMP] = FixedToInt(b0);  \
-      rgba[span.end][ACOMP] = FixedToInt(a0);  \
-      fog[span.end] = fog0;                    \
-      span.end++;                              \
-   }
+/* Simple color index line (no stipple, width=1, no Z, no fog, no tex)*/
+#define NAME simple_ci_line
+#define INTERP_INDEX
+#define RENDER_SPAN(span) _swrast_write_index_span(ctx, &span)
 #include "s_linetemp.h"
 
-   if (ctx->Line.StippleFlag) {
-      span.arrayMask |= SPAN_MASK;
-      compute_stipple_mask(ctx, span.end, span.array->mask);
-   }
-
-   if (ctx->Line.Width > 1.0) {
-      draw_wide_line(ctx, &span, xMajor);
-   }
-   else {
-      _mesa_write_rgba_span(ctx, &span);
-   }
-}
-
-
-static void general_flat_rgba_line( GLcontext *ctx,
-                                    const SWvertex *vert0,
-                                   const SWvertex *vert1 )
-{
-   GLboolean xMajor = GL_FALSE;
-   struct sw_span span;
-   GLint *x, *y;
-   GLdepth *z;
-   GLfloat *fog;
-
-   ASSERT(ctx->Light.ShadeModel == GL_FLAT);
-
-   INIT_SPAN(span, GL_LINE, 0, SPAN_RGBA,
-            SPAN_XY | SPAN_Z | SPAN_FOG);
-   span.red = ChanToFixed(vert1->color[0]);
-   span.green = ChanToFixed(vert1->color[1]);
-   span.blue = ChanToFixed(vert1->color[2]);
-   span.alpha = ChanToFixed(vert1->color[3]);
-   span.redStep = 0;
-   span.greenStep = 0;
-   span.blueStep = 0;
-   span.alphaStep = 0;
-   x = span.array->x;
-   y = span.array->y;
-   z = span.array->z;
-   fog = span.array->fog;
-
-#define SET_XMAJOR 1
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define PLOT(X,Y)              \
-   {                           \
-      x[span.end] = X;         \
-      y[span.end] = Y;         \
-      z[span.end] = Z;         \
-      fog[span.end] = fog0;    \
-      span.end++;              \
-   }
+/* Simple RGBA index line (no stipple, width=1, no Z, no fog, no tex)*/
+#define NAME simple_rgba_line
+#define INTERP_RGBA
+#define RENDER_SPAN(span) _swrast_write_rgba_span(ctx, &span);
 #include "s_linetemp.h"
 
-   if (ctx->Line.StippleFlag) {
-      span.arrayMask |= SPAN_MASK;
-      compute_stipple_mask(ctx, span.end, span.array->mask);
-   }
-
-   if (ctx->Line.Width > 1.0) {
-      draw_wide_line(ctx, &span, xMajor);
-   }
-   else {
-      _mesa_write_rgba_span(ctx, &span);
-   }
-}
-
 
-/* Flat-shaded, textured, any width, maybe stippled */
-static void flat_textured_line( GLcontext *ctx,
-                                const SWvertex *vert0,
-                               const SWvertex *vert1 )
-{
-   GLboolean xMajor = GL_FALSE;
-   struct sw_span span;
-
-   ASSERT(ctx->Light.ShadeModel == GL_FLAT);
-
-   INIT_SPAN(span, GL_LINE, 0, SPAN_RGBA | SPAN_SPEC,
-            SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_TEXTURE | SPAN_LAMBDA);
-   span.red = ChanToFixed(vert1->color[0]);
-   span.green = ChanToFixed(vert1->color[1]);
-   span.blue = ChanToFixed(vert1->color[2]);
-   span.alpha = ChanToFixed(vert1->color[3]);
-   span.redStep = 0;
-   span.greenStep = 0;
-   span.blueStep = 0;
-   span.alphaStep = 0;
-   span.specRed = ChanToFixed(vert1->specular[0]);
-   span.specGreen = ChanToFixed(vert1->specular[1]);
-   span.specBlue = ChanToFixed(vert1->specular[2]);
-   span.specRedStep = 0;
-   span.specGreenStep = 0;
-   span.specBlueStep = 0;
-
-#define SET_XMAJOR 1
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_TEX 1
-#define PLOT(X,Y)                                              \
-   {                                                           \
-      span.array->x[span.end] = X;                             \
-      span.array->y[span.end] = Y;                             \
-      span.array->z[span.end] = Z;                             \
-      span.array->fog[span.end] = fog0;                                \
-      span.array->texcoords[0][span.end][0] = fragTexcoord[0]; \
-      span.array->texcoords[0][span.end][1] = fragTexcoord[1]; \
-      span.array->texcoords[0][span.end][2] = fragTexcoord[2]; \
-      span.array->lambda[0][span.end] = 0.0;                   \
-      span.end++;                                              \
+/* Z, fog, wide, stipple color index line */
+#define NAME general_ci_line
+#define INTERP_INDEX
+#define INTERP_Z
+#define INTERP_FOG
+#define RENDER_SPAN(span)                                      \
+   if (ctx->Line.StippleFlag) {                                        \
+      span.arrayMask |= SPAN_MASK;                             \
+      compute_stipple_mask(ctx, span.end, span.array->mask);    \
+   }                                                           \
+   if (ctx->Line.Width > 1.0) {                                        \
+      draw_wide_line(ctx, &span, (GLboolean)(dx > dy));                \
+   }                                                           \
+   else {                                                      \
+      _swrast_write_index_span(ctx, &span);                    \
    }
 #include "s_linetemp.h"
 
-   if (ctx->Line.StippleFlag) {
-      span.arrayMask |= SPAN_MASK;
-      compute_stipple_mask(ctx, span.end, span.array->mask);
-   }
 
-   if (ctx->Line.Width > 1.0) {
-      draw_wide_line(ctx, &span, xMajor);
-   }
-   else {
-      _mesa_write_texture_span(ctx, &span);
-   }
-}
-
-
-
-/* Smooth-shaded, textured, any width, maybe stippled */
-static void smooth_textured_line( GLcontext *ctx,
-                                  const SWvertex *vert0,
-                                 const SWvertex *vert1 )
-{
-   GLboolean xMajor = GL_FALSE;
-   struct sw_span span;
-
-   ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
-
-   INIT_SPAN(span, GL_LINE, 0, 0,
-            SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_RGBA | SPAN_TEXTURE | SPAN_LAMBDA);
-
-#define SET_XMAJOR 1
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define INTERP_TEX 1
-#define PLOT(X,Y)                                              \
-   {                                                           \
-      span.array->x[span.end] = X;                             \
-      span.array->y[span.end] = Y;                             \
-      span.array->z[span.end] = Z;                             \
-      span.array->fog[span.end] = fog0;                                \
-      span.array->rgba[span.end][RCOMP] = FixedToInt(r0);      \
-      span.array->rgba[span.end][GCOMP] = FixedToInt(g0);      \
-      span.array->rgba[span.end][BCOMP] = FixedToInt(b0);      \
-      span.array->rgba[span.end][ACOMP] = FixedToInt(a0);      \
-      span.array->texcoords[0][span.end][0] = fragTexcoord[0]; \
-      span.array->texcoords[0][span.end][1] = fragTexcoord[1]; \
-      span.array->texcoords[0][span.end][2] = fragTexcoord[2]; \
-      span.array->lambda[0][span.end] = 0.0;                   \
-      span.end++;                                              \
+/* Z, fog, wide, stipple RGBA line */
+#define NAME general_rgba_line
+#define INTERP_RGBA
+#define INTERP_Z
+#define INTERP_FOG
+#define RENDER_SPAN(span)                                      \
+   if (ctx->Line.StippleFlag) {                                        \
+      span.arrayMask |= SPAN_MASK;                             \
+      compute_stipple_mask(ctx, span.end, span.array->mask);   \
+   }                                                           \
+   if (ctx->Line.Width > 1.0) {                                        \
+      draw_wide_line(ctx, &span, (GLboolean)(dx > dy));                \
+   }                                                           \
+   else {                                                      \
+      _swrast_write_rgba_span(ctx, &span);                     \
    }
 #include "s_linetemp.h"
 
-   if (ctx->Line.StippleFlag) {
-      span.arrayMask |= SPAN_MASK;
-      compute_stipple_mask(ctx, span.end, span.array->mask);
-   }
 
-   if (ctx->Line.Width > 1.0) {
-      draw_wide_line(ctx, &span, xMajor);
-   }
-   else {
-      _mesa_write_texture_span(ctx, &span);
-   }
-}
-
-
-/* Smooth-shaded, multitextured, any width, maybe stippled, separate specular
- * color interpolation.
- */
-static void smooth_multitextured_line( GLcontext *ctx,
-                                      const SWvertex *vert0,
-                                      const SWvertex *vert1 )
-{
-   GLboolean xMajor = GL_FALSE;
-   struct sw_span span;
-   GLuint u;
-
-   ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
-
-   INIT_SPAN(span, GL_LINE, 0, 0,
-            SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_RGBA | SPAN_SPEC | SPAN_TEXTURE | SPAN_LAMBDA);
-
-#define SET_XMAJOR 1
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_RGB 1
-#define INTERP_SPEC 1
-#define INTERP_ALPHA 1
-#define INTERP_MULTITEX 1
-#define PLOT(X,Y)                                                      \
-   {                                                                   \
-      span.array->x[span.end] = X;                                     \
-      span.array->y[span.end] = Y;                                     \
-      span.array->z[span.end] = Z;                                     \
-      span.array->fog[span.end] = fog0;                                        \
-      span.array->rgba[span.end][RCOMP] = FixedToInt(r0);              \
-      span.array->rgba[span.end][GCOMP] = FixedToInt(g0);              \
-      span.array->rgba[span.end][BCOMP] = FixedToInt(b0);              \
-      span.array->rgba[span.end][ACOMP] = FixedToInt(a0);              \
-      span.array->spec[span.end][RCOMP] = FixedToInt(sr0);             \
-      span.array->spec[span.end][GCOMP] = FixedToInt(sg0);             \
-      span.array->spec[span.end][BCOMP] = FixedToInt(sb0);             \
-      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {               \
-         if (ctx->Texture.Unit[u]._ReallyEnabled) {                    \
-            span.array->texcoords[u][span.end][0] = fragTexcoord[u][0];        \
-            span.array->texcoords[u][span.end][1] = fragTexcoord[u][1];        \
-            span.array->texcoords[u][span.end][2] = fragTexcoord[u][2];        \
-            span.array->lambda[u][span.end] = 0.0;                     \
-         }                                                             \
-      }                                                                        \
-      span.end++;                                                      \
+/* Single-texture line, w/ fog, Z, specular, etc. */
+#define NAME textured_line
+#define INTERP_RGBA
+#define INTERP_Z
+#define INTERP_FOG
+#define INTERP_TEX
+#define RENDER_SPAN(span)                                      \
+   if (ctx->Line.StippleFlag) {                                        \
+      span.arrayMask |= SPAN_MASK;                             \
+      compute_stipple_mask(ctx, span.end, span.array->mask);   \
+   }                                                           \
+   if (ctx->Line.Width > 1.0) {                                        \
+      draw_wide_line(ctx, &span, (GLboolean)(dx > dy));                \
+   }                                                           \
+   else {                                                      \
+      _swrast_write_texture_span(ctx, &span);                  \
    }
 #include "s_linetemp.h"
 
-   if (ctx->Line.StippleFlag) {
-      span.arrayMask |= SPAN_MASK;
-      compute_stipple_mask(ctx, span.end, span.array->mask);
-   }
 
-   if (ctx->Line.Width > 1.0) {
-      draw_wide_line(ctx, &span, xMajor);
-   }
-   else {
-      _mesa_write_texture_span(ctx, &span);
-   }
-}
-
-
-/* Flat-shaded, multitextured, any width, maybe stippled, separate specular
- * color interpolation.
- */
-static void flat_multitextured_line( GLcontext *ctx,
-                                     const SWvertex *vert0,
-                                    const SWvertex *vert1 )
-{
-   GLboolean xMajor = GL_FALSE;
-   struct sw_span span;
-   GLuint u;
-
-   ASSERT(ctx->Light.ShadeModel == GL_FLAT);
-
-   INIT_SPAN(span, GL_LINE, 0, SPAN_RGBA | SPAN_SPEC,
-            SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_TEXTURE | SPAN_LAMBDA);
-   span.red = ChanToFixed(vert1->color[0]);
-   span.green = ChanToFixed(vert1->color[1]);
-   span.blue = ChanToFixed(vert1->color[2]);
-   span.alpha = ChanToFixed(vert1->color[3]);
-   span.redStep = 0;
-   span.greenStep = 0;
-   span.blueStep = 0;
-   span.alphaStep = 0;
-   span.specRed = ChanToFixed(vert1->specular[0]);
-   span.specGreen = ChanToFixed(vert1->specular[1]);
-   span.specBlue = ChanToFixed(vert1->specular[2]);
-   span.specRedStep = 0;
-   span.specGreenStep = 0;
-   span.specBlueStep = 0;
-
-#define SET_XMAJOR 1
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_MULTITEX 1
-#define PLOT(X,Y)                                                      \
-   {                                                                   \
-      span.array->x[span.end] = X;                                     \
-      span.array->y[span.end] = Y;                                     \
-      span.array->z[span.end] = Z;                                     \
-      span.array->fog[span.end] = fog0;                                        \
-      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {               \
-         if (ctx->Texture.Unit[u]._ReallyEnabled) {                    \
-            span.array->texcoords[u][span.end][0] = fragTexcoord[u][0];        \
-            span.array->texcoords[u][span.end][1] = fragTexcoord[u][1];        \
-            span.array->texcoords[u][span.end][2] = fragTexcoord[u][2];        \
-            span.array->lambda[u][span.end] = 0.0;                     \
-         }                                                             \
-      }                                                                        \
-      span.end++;                                                      \
+/* Multi-texture or separate specular line, w/ fog, Z, specular, etc. */
+#define NAME multitextured_line
+#define INTERP_RGBA
+#define INTERP_SPEC
+#define INTERP_Z
+#define INTERP_FOG
+#define INTERP_MULTITEX
+#define RENDER_SPAN(span)                                      \
+   if (ctx->Line.StippleFlag) {                                        \
+      span.arrayMask |= SPAN_MASK;                             \
+      compute_stipple_mask(ctx, span.end, span.array->mask);   \
+   }                                                           \
+   if (ctx->Line.Width > 1.0) {                                        \
+      draw_wide_line(ctx, &span, (GLboolean)(dx > dy));                \
+   }                                                           \
+   else {                                                      \
+      _swrast_write_texture_span(ctx, &span);                  \
    }
 #include "s_linetemp.h"
 
-   if (ctx->Line.StippleFlag) {
-      span.arrayMask |= SPAN_MASK;
-      compute_stipple_mask(ctx, span.end, span.array->mask);
-   }
-
-   if (ctx->Line.Width > 1.0) {
-      draw_wide_line(ctx, &span, xMajor);
-   }
-   else {
-      _mesa_write_texture_span(ctx, &span);
-   }
-}
 
 
-void _swrast_add_spec_terms_line( GLcontext *ctx,
-                                 const SWvertex *v0,
-                                 const SWvertex *v1 )
+void
+_swrast_add_spec_terms_line( GLcontext *ctx,
+                             const SWvertex *v0,
+                             const SWvertex *v1 )
 {
    SWvertex *ncv0 = (SWvertex *)v0;
    SWvertex *ncv1 = (SWvertex *)v1;
@@ -751,30 +245,18 @@ _mesa_print_line_function(GLcontext *ctx)
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
    _mesa_printf("Line Func == ");
-   if (swrast->Line == flat_ci_line)
-      _mesa_printf("flat_ci_line\n");
-   else if (swrast->Line == flat_rgba_line)
-      _mesa_printf("flat_rgba_line\n");
-   else if (swrast->Line == smooth_ci_line)
-      _mesa_printf("smooth_ci_line\n");
-   else if (swrast->Line == smooth_rgba_line)
-      _mesa_printf("smooth_rgba_line\n");
-   else if (swrast->Line == general_smooth_ci_line)
-      _mesa_printf("general_smooth_ci_line\n");
-   else if (swrast->Line == general_flat_ci_line)
-      _mesa_printf("general_flat_ci_line\n");
-   else if (swrast->Line == general_smooth_rgba_line)
-      _mesa_printf("general_smooth_rgba_line\n");
-   else if (swrast->Line == general_flat_rgba_line)
-      _mesa_printf("general_flat_rgba_line\n");
-   else if (swrast->Line == flat_textured_line)
-      _mesa_printf("flat_textured_line\n");
-   else if (swrast->Line == smooth_textured_line)
-      _mesa_printf("smooth_textured_line\n");
-   else if (swrast->Line == smooth_multitextured_line)
-      _mesa_printf("smooth_multitextured_line\n");
-   else if (swrast->Line == flat_multitextured_line)
-      _mesa_printf("flat_multitextured_line\n");
+   if (swrast->Line == simple_ci_line)
+      _mesa_printf("simple_ci_line\n");
+   else if (swrast->Line == simple_rgba_line)
+      _mesa_printf("simple_rgba_line\n");
+   else if (swrast->Line == general_ci_line)
+      _mesa_printf("general_ci_line\n");
+   else if (swrast->Line == general_rgba_line)
+      _mesa_printf("general_rgba_line\n");
+   else if (swrast->Line == textured_line)
+      _mesa_printf("textured_line\n");
+   else if (swrast->Line == multitextured_line)
+      _mesa_printf("multitextured_line\n");
    else
       _mesa_printf("Driver func %p\n", (void *) swrast->Line);
 }
@@ -819,65 +301,41 @@ _swrast_choose_line( GLcontext *ctx )
       if (ctx->Line.SmoothFlag) {
          /* antialiased lines */
          _swrast_choose_aa_line_function(ctx);
-         ASSERT(swrast->Triangle);
+         ASSERT(swrast->Line);
       }
-      else if (ctx->Texture._EnabledUnits) {
-         if (ctx->Texture._EnabledUnits > 1 ||      
-            (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)) {
+      else if (ctx->Texture._EnabledCoordUnits) {
+         /* textured lines */
+         if (ctx->Texture._EnabledCoordUnits > 0x1
+             || NEED_SECONDARY_COLOR(ctx)) {
             /* multi-texture and/or separate specular color */
-            if (ctx->Light.ShadeModel == GL_SMOOTH)
-               USE(smooth_multitextured_line);
-            else
-               USE(flat_multitextured_line);
+            USE(multitextured_line);
          }
          else {
-            if (ctx->Light.ShadeModel == GL_SMOOTH) {
-                USE(smooth_textured_line);
-            }
-            else {
-                USE(flat_textured_line);
-            }
+            USE(textured_line);
          }
       }
+      else if (ctx->Depth.Test || ctx->Fog.Enabled || ctx->Line.Width != 1.0
+               || ctx->Line.StippleFlag) {
+         /* no texture, but Z, fog, width>1, stipple, etc. */
+         if (rgbmode)
+            USE(general_rgba_line);
+         else
+            USE(general_ci_line);
+      }
       else {
-        if (ctx->Light.ShadeModel == GL_SMOOTH) {
-            if (ctx->Depth.Test || ctx->Fog.Enabled || ctx->Line.Width != 1.0
-                || ctx->Line.StippleFlag) {
-               if (rgbmode)
-                  USE(general_smooth_rgba_line);
-               else
-                  USE(general_smooth_ci_line);
-            }
-            else {
-               if (rgbmode)
-                  USE(smooth_rgba_line);
-               else
-                  USE(smooth_ci_line);
-            }
-        }
-         else {
-            if (ctx->Depth.Test || ctx->Fog.Enabled || ctx->Line.Width != 1.0
-                || ctx->Line.StippleFlag) {
-               if (rgbmode)
-                  USE(general_flat_rgba_line);
-               else
-                  USE(general_flat_ci_line);
-            }
-            else {
-               if (rgbmode)
-                  USE(flat_rgba_line);
-               else
-                  USE(flat_ci_line);
-            }
-         }
+         /* simplest lines */
+         if (rgbmode)
+            USE(simple_rgba_line);
+         else
+            USE(simple_ci_line);
       }
    }
    else if (ctx->RenderMode == GL_FEEDBACK) {
-      USE(_mesa_feedback_line);
+      USE(_swrast_feedback_line);
    }
    else {
       ASSERT(ctx->RenderMode == GL_SELECT);
-      USE(_mesa_select_line);
+      USE(_swrast_select_line);
    }
 
    /*_mesa_print_line_function(ctx);*/