swrast: Fix fixed-function fragment processing
[mesa.git] / src / mesa / swrast / s_lines.c
index 1abe85c541b6c4d899df0c6fcc9dd0bc479e5047..ee997b08a7b1c5c285a49da050dcf89063928b0e 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5
+ * Version:  7.1
  *
- * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  */
 
 
-#include "glheader.h"
-#include "context.h"
-#include "colormac.h"
-#include "macros.h"
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/colormac.h"
+#include "main/macros.h"
 #include "s_aaline.h"
 #include "s_context.h"
-#include "s_depth.h"
 #include "s_feedback.h"
 #include "s_lines.h"
 #include "s_span.h"
@@ -39,7 +38,7 @@
  * Init the mask[] array to implement a line stipple.
  */
 static void
-compute_stipple_mask( GLcontext *ctx, GLuint len, GLubyte mask[] )
+compute_stipple_mask( struct gl_context *ctx, GLuint len, GLubyte mask[] )
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    GLuint i;
@@ -61,14 +60,15 @@ compute_stipple_mask( GLcontext *ctx, GLuint len, GLubyte mask[] )
  * To draw a wide line we can simply redraw the span N times, side by side.
  */
 static void
-draw_wide_line( GLcontext *ctx, struct sw_span *span, GLboolean xMajor )
+draw_wide_line( struct gl_context *ctx, SWspan *span, GLboolean xMajor )
 {
-   GLint width, start;
+   const GLint width = (GLint) CLAMP(ctx->Line.Width,
+                                     ctx->Const.MinLineWidth,
+                                     ctx->Const.MaxLineWidth);
+   GLint start;
 
    ASSERT(span->end < MAX_WIDTH);
 
-   width = (GLint) CLAMP( ctx->Line._Width, MIN_LINE_WIDTH, MAX_LINE_WIDTH );
-
    if (width & 1)
       start = width / 2;
    else
@@ -87,10 +87,7 @@ draw_wide_line( GLcontext *ctx, struct sw_span *span, GLboolean xMajor )
             for (i = 0; i < span->end; i++)
                y[i]++;
          }
-         if (ctx->Visual.rgbMode)
-            _swrast_write_rgba_span(ctx, span);
-         else
-            _swrast_write_index_span(ctx, span);
+        _swrast_write_rgba_span(ctx, span);
       }
    }
    else {
@@ -106,10 +103,7 @@ draw_wide_line( GLcontext *ctx, struct sw_span *span, GLboolean xMajor )
             for (i = 0; i < span->end; i++)
                x[i]++;
          }
-         if (ctx->Visual.rgbMode)
-            _swrast_write_rgba_span(ctx, span);
-         else
-            _swrast_write_index_span(ctx, span);
+        _swrast_write_rgba_span(ctx, span);
       }
    }
 }
@@ -120,49 +114,23 @@ draw_wide_line( GLcontext *ctx, struct sw_span *span, GLboolean xMajor )
 /*****                    Rasterization                           *****/
 /**********************************************************************/
 
-/* 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"
-
 /* Simple RGBA index line (no stipple, width=1, no Z, no fog, no tex)*/
-#define NAME simple_rgba_line
+#define NAME simple_no_z_rgba_line
 #define INTERP_RGBA
 #define RENDER_SPAN(span) _swrast_write_rgba_span(ctx, &span);
 #include "s_linetemp.h"
 
 
-/* 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"
-
-
 /* Z, fog, wide, stipple RGBA line */
-#define NAME general_rgba_line
+#define NAME 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) {                                       \
+   if (ctx->Line.Width > 1.0) {                                        \
       draw_wide_line(ctx, &span, (GLboolean)(dx > dy));                \
    }                                                           \
    else {                                                      \
@@ -171,39 +139,17 @@ draw_wide_line( GLcontext *ctx, struct sw_span *span, GLboolean xMajor )
 #include "s_linetemp.h"
 
 
-/* Single-texture line, w/ fog, Z, specular, etc. */
-#define NAME textured_line
+/* General-purpose line (any/all features). */
+#define NAME general_line
 #define INTERP_RGBA
 #define INTERP_Z
-#define INTERP_FOG
-#define INTERP_TEX
+#define INTERP_ATTRIBS
 #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"
-
-
-/* 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) {                                       \
+   if (ctx->Line.Width > 1.0) {                                        \
       draw_wide_line(ctx, &span, (GLboolean)(dx > dy));                \
    }                                                           \
    else {                                                      \
@@ -214,50 +160,39 @@ draw_wide_line( GLcontext *ctx, struct sw_span *span, GLboolean xMajor )
 
 
 void
-_swrast_add_spec_terms_line( GLcontext *ctx,
-                             const SWvertex *v0,
-                             const SWvertex *v1 )
+_swrast_add_spec_terms_line(struct gl_context *ctx,
+                            const SWvertex *v0, const SWvertex *v1)
 {
    SWvertex *ncv0 = (SWvertex *)v0;
    SWvertex *ncv1 = (SWvertex *)v1;
-   GLchan c[2][4];
-   COPY_CHAN4( c[0], ncv0->color );
-   COPY_CHAN4( c[1], ncv1->color );
-   ACC_3V( ncv0->color, ncv0->specular );
-   ACC_3V( ncv1->color, ncv1->specular );
+   GLfloat rSum, gSum, bSum;
+   GLchan cSave[2][4];
+
+   /* save original colors */
+   COPY_CHAN4(cSave[0], ncv0->color);
+   COPY_CHAN4(cSave[1], ncv1->color);
+   /* sum v0 */
+   rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[FRAG_ATTRIB_COL1][0];
+   gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[FRAG_ATTRIB_COL1][1];
+   bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2];
+   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum);
+   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum);
+   UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum);
+   /* sum v1 */
+   rSum = CHAN_TO_FLOAT(ncv1->color[0]) + ncv1->attrib[FRAG_ATTRIB_COL1][0];
+   gSum = CHAN_TO_FLOAT(ncv1->color[1]) + ncv1->attrib[FRAG_ATTRIB_COL1][1];
+   bSum = CHAN_TO_FLOAT(ncv1->color[2]) + ncv1->attrib[FRAG_ATTRIB_COL1][2];
+   UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[0], rSum);
+   UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[1], gSum);
+   UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[2], bSum);
+   /* draw */
    SWRAST_CONTEXT(ctx)->SpecLine( ctx, ncv0, ncv1 );
-   COPY_CHAN4( ncv0->color, c[0] );
-   COPY_CHAN4( ncv1->color, c[1] );
+   /* restore original colors */
+   COPY_CHAN4( ncv0->attrib[FRAG_ATTRIB_COL0], cSave[0] );
+   COPY_CHAN4( ncv1->attrib[FRAG_ATTRIB_COL0], cSave[1] );
 }
 
 
-#ifdef DEBUG
-extern void
-_mesa_print_line_function(GLcontext *ctx);  /* silence compiler warning */
-void
-_mesa_print_line_function(GLcontext *ctx)
-{
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
-
-   _mesa_printf("Line Func == ");
-   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);
-}
-#endif
-
-
 
 #ifdef DEBUG
 
@@ -267,7 +202,7 @@ static const char *lineFuncName = NULL;
 #define USE(lineFunc)                   \
 do {                                    \
     lineFuncName = #lineFunc;           \
-    /*_mesa_printf("%s\n", lineFuncName);*/   \
+    /*printf("%s\n", lineFuncName);*/   \
     swrast->Line = lineFunc;            \
 } while (0)
 
@@ -279,7 +214,7 @@ do {                                    \
 
 
 
-/*
+/**
  * Determine which line drawing function to use given the current
  * rendering context.
  *
@@ -287,10 +222,12 @@ do {                                    \
  * tests to this code.
  */
 void
-_swrast_choose_line( GLcontext *ctx )
+_swrast_choose_line( struct gl_context *ctx )
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   const GLboolean rgbmode = ctx->Visual.rgbMode;
+   GLboolean specular = (ctx->Fog.ColorSumEnabled ||
+                         (ctx->Light.Enabled &&
+                          ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR));
 
    if (ctx->RenderMode == GL_RENDER) {
       if (ctx->Line.SmoothFlag) {
@@ -298,31 +235,27 @@ _swrast_choose_line( GLcontext *ctx )
          _swrast_choose_aa_line_function(ctx);
          ASSERT(swrast->Line);
       }
-      else if (ctx->Texture._EnabledCoordUnits) {
-         /* textured lines */
-         if (ctx->Texture._EnabledCoordUnits > 0x1
-             || NEED_SECONDARY_COLOR(ctx)) {
-            /* multi-texture and/or separate specular color */
-            USE(multitextured_line);
-         }
-         else {
-            USE(textured_line);
-         }
+      else if (ctx->Texture._EnabledCoordUnits
+               || _swrast_use_fragment_program(ctx)
+               || swrast->_FogEnabled
+               || specular) {
+         USE(general_line);
       }
-      else if (ctx->Depth.Test || swrast->_FogEnabled || ctx->Line._Width != 1.0
+      else if (ctx->Depth.Test
+               || 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);
+#if CHAN_BITS == 32
+         USE(general_line);
+#else
+         USE(rgba_line);
+#endif
       }
       else {
-         /* simplest lines */
-         if (rgbmode)
-            USE(simple_rgba_line);
-         else
-            USE(simple_ci_line);
+         ASSERT(!ctx->Depth.Test);
+         ASSERT(ctx->Line.Width == 1.0);
+         /* simple lines */
+         USE(simple_no_z_rgba_line);
       }
    }
    else if (ctx->RenderMode == GL_FEEDBACK) {
@@ -332,6 +265,4 @@ _swrast_choose_line( GLcontext *ctx )
       ASSERT(ctx->RenderMode == GL_SELECT);
       USE(_swrast_select_line);
    }
-
-   /*_mesa_print_line_function(ctx);*/
 }