Overhaul/simplify SWvertex and SWspan attribute handling.
authorBrian <brian@yutani.localnet.net>
Sun, 20 May 2007 18:27:39 +0000 (12:27 -0600)
committerBrian <brian@yutani.localnet.net>
Sun, 20 May 2007 18:27:39 +0000 (12:27 -0600)
Instead of separate fog/specular/texcoord/varying code, just treat all of
them as generic attributes.  Simplifies the point/line/triangle functions.

34 files changed:
src/mesa/drivers/dri/ffb/ffb_tris.c
src/mesa/drivers/dri/mach64/mach64_native_vb.c
src/mesa/drivers/dri/s3v/s3v_tritmp.h
src/mesa/drivers/dri/tdfx/tdfx_tris.c
src/mesa/drivers/x11/xm_line.c
src/mesa/swrast/s_aaline.c
src/mesa/swrast/s_aalinetemp.h
src/mesa/swrast/s_aatriangle.c
src/mesa/swrast/s_aatritemp.h
src/mesa/swrast/s_alpha.c
src/mesa/swrast/s_bitmap.c
src/mesa/swrast/s_context.c
src/mesa/swrast/s_context.h
src/mesa/swrast/s_copypix.c
src/mesa/swrast/s_drawpix.c
src/mesa/swrast/s_feedback.c
src/mesa/swrast/s_fog.c
src/mesa/swrast/s_lines.c
src/mesa/swrast/s_linetemp.h
src/mesa/swrast/s_logic.c
src/mesa/swrast/s_masking.c
src/mesa/swrast/s_points.c
src/mesa/swrast/s_pointtemp.h
src/mesa/swrast/s_span.c
src/mesa/swrast/s_span.h
src/mesa/swrast/s_texcombine.c
src/mesa/swrast/s_triangle.c
src/mesa/swrast/s_tritemp.h
src/mesa/swrast/s_zoom.c
src/mesa/swrast/swrast.h
src/mesa/swrast_setup/ss_context.c
src/mesa/swrast_setup/ss_triangle.c
src/mesa/swrast_setup/ss_tritmp.h
src/mesa/tnl_dd/t_dd_vb.c

index ca0e514..9fae8c8 100644 (file)
@@ -138,10 +138,10 @@ static void ffb_translate_vertex(GLcontext *ctx, const ffb_vertex *src,
        const GLfloat ty = m[13];
        const GLfloat tz = m[14];
 
-       dst->win[0] = sx * src->x + tx;
-       dst->win[1] = sy * src->y + ty;
-       dst->win[2] = sz * src->z + tz;
-       dst->win[3] = 1.0;
+       dst->attrib[FRAG_ATTRIB_WPOS][0] = sx * src->x + tx;
+       dst->attrib[FRAG_ATTRIB_WPOS][1] = sy * src->y + ty;
+       dst->attrib[FRAG_ATTRIB_WPOS][2] = sz * src->z + tz;
+       dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0;
       
        dst->color[0] = FFB_UBYTE_FROM_COLOR(src->color[0].red);
        dst->color[1] = FFB_UBYTE_FROM_COLOR(src->color[0].green);
index 81bcf80..75cf0e2 100644 (file)
@@ -44,7 +44,7 @@ void TAG(translate_vertex)(GLcontext *ctx,
    UNVIEWPORT_VARS;
    CARD32 *p = (CARD32 *)src + 10 - mmesa->vertex_size;
 
-   dst->win[3] = 1.0;
+   dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0;
    
    switch ( format ) {
       case TEX1_VERTEX_FORMAT:
@@ -75,17 +75,17 @@ void TAG(translate_vertex)(GLcontext *ctx,
         dst->attrib[FRAG_ATTRIB_TEX0][1] = LE32_IN_FLOAT( p++ );
 #endif
         dst->attrib[FRAG_ATTRIB_TEX0][3] = 1.0;
-        dst->win[3] = LE32_IN_FLOAT( p++ );
+        dst->attrib[FRAG_ATTRIB_WPOS][3] = LE32_IN_FLOAT( p++ );
        
       case NOTEX_VERTEX_FORMAT:
-        dst->specular[2] = ((GLubyte *)p)[0];
-        dst->specular[1] = ((GLubyte *)p)[1];
-        dst->specular[0] = ((GLubyte *)p)[2];
-        dst->attrib[FRAG_ATTRIB_FOGC][0] = ((GLubyte *)p)[3];
+        dst->attrib[FRAG_ATTRIB_COL1][2] = UBYTE_TO_FLOAT(((GLubyte *)p)[0]);
+        dst->attrib[FRAG_ATTRIB_COL1][1] = UBYTE_TO_FLOAT(((GLubyte *)p)[1]);
+        dst->attrib[FRAG_ATTRIB_COL1][0] = UBYTE_TO_FLOAT(((GLubyte *)p)[2]);
+        dst->attrib[FRAG_ATTRIB_FOGC][0] = ((GLubyte *)p)[3]; /*XXX int->float?*/
         p++;
 
       case TINY_VERTEX_FORMAT:
-        dst->win[2] = UNVIEWPORT_Z( LE32_IN( p++ ) );
+        dst->attrib[FRAG_ATTRIB_WPOS][2] = UNVIEWPORT_Z( LE32_IN( p++ ) );
 
         dst->color[2] = ((GLubyte *)p)[0];
         dst->color[1] = ((GLubyte *)p)[1];
@@ -96,8 +96,8 @@ void TAG(translate_vertex)(GLcontext *ctx,
         {
            GLuint xy = LE32_IN( p );
            
-           dst->win[0] = UNVIEWPORT_X( (GLfloat)(GLshort)( xy >> 16 ) );
-           dst->win[1] = UNVIEWPORT_Y( (GLfloat)(GLshort)( xy & 0xffff ) );
+           dst->attrib[FRAG_ATTRIB_WPOS][0] = UNVIEWPORT_X( (GLfloat)(GLshort)( xy >> 16 ) );
+           dst->attrib[FRAG_ATTRIB_WPOS][1] = UNVIEWPORT_Y( (GLfloat)(GLshort)( xy & 0xffff ) );
         }
    }
 
index 696fc02..2321bd4 100644 (file)
 
 #define SORT_LINE_VERT() \
 do { \
-       if(v[0].win[1] <= v[1].win[1]) { \
+       if(v[0].attrib[FRAG_ATTRIB_WPOS][1] <= v[1].attrib[FRAG_ATTRIB_WPOS][1]) { \
 \
                 idx[0] = 0; \
                 idx[1] = 1; \
 \
-        } else if (v[0].win[1] > v[1].win[1]) { \
+        } else if (v[0].attrib[FRAG_ATTRIB_WPOS][1] > v[1].attrib[FRAG_ATTRIB_WPOS][1]) { \
 \
                 idx[0] = 1; \
                 idx[1] = 0; \
@@ -58,19 +58,19 @@ do { \
 
 #define SET_LINE_VERT() \
 do { \
-        x[0] = (v[idx[0]].win[0] * 1024.0f * 1024.0f); /* 0x100000 */ \
-        y[0] = fy[0] = dPriv->h - v[idx[0]].win[1]; \
-        z[0] = (v[idx[0]].win[2]) * 1024.0f * 32.0f; /* 0x8000; */ \
+        x[0] = (v[idx[0]].attrib[FRAG_ATTRIB_WPOS][0] * 1024.0f * 1024.0f); /* 0x100000 */ \
+        y[0] = fy[0] = dPriv->h - v[idx[0]].attrib[FRAG_ATTRIB_WPOS][1]; \
+        z[0] = (v[idx[0]].attrib[FRAG_ATTRIB_WPOS][2]) * 1024.0f * 32.0f; /* 0x8000; */ \
 \
-        x[1] = (v[idx[1]].win[0] * 1024.0f * 1024.0f); /* 0x100000 */ \
-        y[1] = dPriv->h - v[idx[1]].win[1]; \
-        z[1] = (v[idx[1]].win[2]) * 1024.0f * 32.0f; /* 0x8000 */ \
+        x[1] = (v[idx[1]].attrib[FRAG_ATTRIB_WPOS][0] * 1024.0f * 1024.0f); /* 0x100000 */ \
+        y[1] = dPriv->h - v[idx[1]].attrib[FRAG_ATTRIB_WPOS][1]; \
+        z[1] = (v[idx[1]].attrib[FRAG_ATTRIB_WPOS][2]) * 1024.0f * 32.0f; /* 0x8000 */ \
 } while(0)
 
 #define SET_LINE_XY() \
 do { \
-       tmp = v[idx[0]].win[0]; \
-        tmp2 = v[idx[1]].win[0]; \
+       tmp = v[idx[0]].attrib[FRAG_ATTRIB_WPOS][0]; \
+        tmp2 = v[idx[1]].attrib[FRAG_ATTRIB_WPOS][0]; \
 \
        dx01 = x[0] - x[1]; \
         dy01 = y[0] - y[1]; \
@@ -265,7 +265,7 @@ do { \
 #define SORT_VERT() \
 do { \
        for (i=0; i<3; i++) \
-               fy[i] = v[i].win[1]; \
+               fy[i] = v[i].attrib[FRAG_ATTRIB_WPOS][1]; \
 \
                if (fy[1] > fy[0]) {  /* (fy[1] > fy[0]) */ \
 \
@@ -305,9 +305,9 @@ do { \
 do { \
        for (i=0; i<3; i++) \
        { \
-               x[i] = ((v[idx[i]].win[0]) * /* 0x100000*/  1024.0 * 1024.0); \
-               y[i] = fy[i] = (dPriv->h - v[idx[i]].win[1]); \
-               z[i] = ((v[idx[i]].win[2]) * /* 0x8000 */ 1024.0 * 32.0); \
+               x[i] = ((v[idx[i]].attrib[FRAG_ATTRIB_WPOS][0]) * /* 0x100000*/  1024.0 * 1024.0); \
+               y[i] = fy[i] = (dPriv->h - v[idx[i]].attrib[FRAG_ATTRIB_WPOS][1]); \
+               z[i] = ((v[idx[i]].attrib[FRAG_ATTRIB_WPOS][2]) * /* 0x8000 */ 1024.0 * 32.0); \
        } \
 \
        ydiff = fy[0] - (float)y[0]; \
@@ -420,9 +420,9 @@ do { \
         v2 = (v[idx[2]].attrib[FRAG_ATTRIB_TEX0][1] \
                 * (GLfloat)(t->globj->Image[0][0]->Height) * 256.0); \
 \
-        w0 = (v[idx[0]].win[3]); \
-        w1 = (v[idx[1]].win[3]); \
-        w2 = (v[idx[2]].win[3]); \
+        w0 = (v[idx[0]].attrib[FRAG_ATTRIB_WPOS][3]); \
+        w1 = (v[idx[1]].attrib[FRAG_ATTRIB_WPOS][3]); \
+        w2 = (v[idx[2]].attrib[FRAG_ATTRIB_WPOS][3]); \
 } while (0)
 
 #define SET_BASEUV() \
@@ -732,8 +732,8 @@ DEBUG(("***\n"));
 
 #if (IND & S3V_RAST_CULL_BIT)
        cull = vmesa->backface_sign *
-               ((v[1].win[0] - v[0].win[0]) * (v[0].win[1] - v[2].win[1]) +
-                (v[1].win[1] - v[0].win[1]) * (v[2].win[0] - v[0].win[0]));
+               ((v[1].attrib[FRAG_ATTRIB_WPOS][0] - v[0].attrib[FRAG_ATTRIB_WPOS][0]) * (v[0].attrib[FRAG_ATTRIB_WPOS][1] - v[2].attrib[FRAG_ATTRIB_WPOS][1]) +
+                (v[1].attrib[FRAG_ATTRIB_WPOS][1] - v[0].attrib[FRAG_ATTRIB_WPOS][1]) * (v[2].attrib[FRAG_ATTRIB_WPOS][0] - v[0].attrib[FRAG_ATTRIB_WPOS][0]));
 
        if (cull < vmesa->cull_zero /* -0.02f */) return;
 #endif
@@ -842,8 +842,8 @@ static void TAG(s3v_quad)( s3vContextPtr vmesa,
 
 #if (IND & S3V_RAST_CULL_BIT)
        cull = vmesa->backface_sign *
-               ((v[1].win[0] - v[0].win[0]) * (v[0].win[1] - v[2].win[1]) +
-                (v[1].win[1] - v[0].win[1]) * (v[2].win[0] - v[0].win[0]));
+               ((v[1].attrib[FRAG_ATTRIB_WPOS][0] - v[0].attrib[FRAG_ATTRIB_WPOS][0]) * (v[0].attrib[FRAG_ATTRIB_WPOS][1] - v[2].attrib[FRAG_ATTRIB_WPOS][1]) +
+                (v[1].attrib[FRAG_ATTRIB_WPOS][1] - v[0].attrib[FRAG_ATTRIB_WPOS][1]) * (v[2].attrib[FRAG_ATTRIB_WPOS][0] - v[0].attrib[FRAG_ATTRIB_WPOS][0]));
 
        if (cull < vmesa->cull_zero /* -0.02f */) goto second; /* return; */ /* (a) */
 #endif
@@ -897,8 +897,8 @@ second:
 
 #if (IND & S3V_RAST_CULL_BIT)
        cull = vmesa->backface_sign *
-               ((v[1].win[0] - v[0].win[0]) * (v[0].win[1] - v[2].win[1]) +
-                (v[1].win[1] - v[0].win[1]) * (v[2].win[0] - v[0].win[0]));
+               ((v[1].attrib[FRAG_ATTRIB_WPOS][0] - v[0].attrib[FRAG_ATTRIB_WPOS][0]) * (v[0].attrib[FRAG_ATTRIB_WPOS][1] - v[2].attrib[FRAG_ATTRIB_WPOS][1]) +
+                (v[1].attrib[FRAG_ATTRIB_WPOS][1] - v[0].attrib[FRAG_ATTRIB_WPOS][1]) * (v[2].attrib[FRAG_ATTRIB_WPOS][0] - v[0].attrib[FRAG_ATTRIB_WPOS][0]));
                 
        if (cull < /* -0.02f */ vmesa->cull_zero) return;
 #endif
index 4ba2f40..96f9ae2 100644 (file)
@@ -142,10 +142,10 @@ tdfx_translate_vertex( GLcontext *ctx, const tdfxVertex *src, SWvertex *dst)
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
    if (fxMesa->vertexFormat == TDFX_LAYOUT_TINY) {
-      dst->win[0] = src->x - fxMesa->x_offset;
-      dst->win[1] = src->y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset);
-      dst->win[2] = src->z;
-      dst->win[3] = 1.0;
+      dst->attrib[FRAG_ATTRIB_WPOS][0] = src->x - fxMesa->x_offset;
+      dst->attrib[FRAG_ATTRIB_WPOS][1] = src->y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset);
+      dst->attrib[FRAG_ATTRIB_WPOS][2] = src->z;
+      dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0;
 
       dst->color[0] = src->color[2];
       dst->color[1] = src->color[1];
@@ -155,10 +155,10 @@ tdfx_translate_vertex( GLcontext *ctx, const tdfxVertex *src, SWvertex *dst)
    else {
       GLfloat w = 1.0 / src->rhw;
 
-      dst->win[0] = src->x - fxMesa->x_offset;
-      dst->win[1] = src->y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset);
-      dst->win[2] = src->z;
-      dst->win[3] = src->rhw;
+      dst->attrib[FRAG_ATTRIB_WPOS][0] = src->x - fxMesa->x_offset;
+      dst->attrib[FRAG_ATTRIB_WPOS][1] = src->y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset);
+      dst->attrib[FRAG_ATTRIB_WPOS][2] = src->z;
+      dst->attrib[FRAG_ATTRIB_WPOS][3] = src->rhw;
 
       dst->color[0] = src->color[2];
       dst->color[1] = src->color[1];
index 8537256..deeae50 100644 (file)
@@ -556,10 +556,10 @@ xor_line(GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1)
                                               vert1->color[0], vert1->color[1],
                                               vert1->color[2], vert1->color[3],
                                               xmesa->pixelformat);
-   int x0 = (int) vert0->win[0];
-   int y0 = YFLIP(xrb, (GLint) vert0->win[1]);
-   int x1 = (int) vert1->win[0];
-   int y1 = YFLIP(xrb, (GLint) vert1->win[1]);
+   int x0 =            (GLint) vert0->attrib[FRAG_ATTRIB_WPOS][0];
+   int y0 = YFLIP(xrb, (GLint) vert0->attrib[FRAG_ATTRIB_WPOS][1]);
+   int x1 =            (GLint) vert1->attrib[FRAG_ATTRIB_WPOS][0];
+   int y1 = YFLIP(xrb, (GLint) vert1->attrib[FRAG_ATTRIB_WPOS][1]);
    XMesaSetForeground(dpy, gc, pixel);
    XMesaSetFunction(dpy, gc, GXxor);
    XSetLineAttributes(dpy, gc, (int) ctx->Line.Width,
index 3bb53dc..d6a9afb 100644 (file)
@@ -59,19 +59,13 @@ struct LineInfo
 
    /* DO_Z */
    GLfloat zPlane[4];
-   /* DO_FOG */
-   GLfloat fPlane[4];
    /* DO_RGBA */
    GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];
    /* DO_INDEX */
    GLfloat iPlane[4];
-   /* DO_SPEC */
-   GLfloat srPlane[4], sgPlane[4], sbPlane[4];
    /* DO_ATTRIBS */
-   GLfloat sPlane[FRAG_ATTRIB_MAX][4];
-   GLfloat tPlane[FRAG_ATTRIB_MAX][4];
-   GLfloat uPlane[FRAG_ATTRIB_MAX][4];
-   GLfloat vPlane[FRAG_ATTRIB_MAX][4];
+   GLfloat wPlane[4];
+   GLfloat attrPlane[FRAG_ATTRIB_MAX][4][4];
    GLfloat lambda[FRAG_ATTRIB_MAX];
    GLfloat texWidth[FRAG_ATTRIB_MAX];
    GLfloat texHeight[FRAG_ATTRIB_MAX];
@@ -483,35 +477,24 @@ segment(GLcontext *ctx,
 
 #define NAME(x) aa_ci_##x
 #define DO_Z
-#define DO_FOG
+#define DO_ATTRIBS /* for fog */
 #define DO_INDEX
 #include "s_aalinetemp.h"
 
 
 #define NAME(x) aa_rgba_##x
 #define DO_Z
-#define DO_FOG
 #define DO_RGBA
 #include "s_aalinetemp.h"
 
 
-#define NAME(x)  aa_tex_rgba_##x
+#define NAME(x)  aa_general_rgba_##x
 #define DO_Z
-#define DO_FOG
 #define DO_RGBA
 #define DO_ATTRIBS
 #include "s_aalinetemp.h"
 
 
-#define NAME(x)  aa_multitex_spec_##x
-#define DO_Z
-#define DO_FOG
-#define DO_RGBA
-#define DO_ATTRIBS
-#define DO_SPEC
-#include "s_aalinetemp.h"
-
-
 
 void
 _swrast_choose_aa_line_function(GLcontext *ctx)
@@ -523,14 +506,12 @@ _swrast_choose_aa_line_function(GLcontext *ctx)
    if (ctx->Visual.rgbMode) {
       /* RGBA */
       if (ctx->Texture._EnabledCoordUnits != 0
-          || ctx->FragmentProgram._Current) {
-
-         if (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR || 
-             ctx->Fog.ColorSumEnabled)
-            swrast->Line = aa_multitex_spec_line;
-         else
-            swrast->Line = aa_tex_rgba_line;
-
+          || ctx->FragmentProgram._Current
+          || (ctx->Light.Enabled &&
+              ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
+          || ctx->Fog.ColorSumEnabled
+          || swrast->_FogEnabled) {
+         swrast->Line = aa_general_rgba_line;
       }
       else {
          swrast->Line = aa_rgba_line;
index 80cec0b..8756f12 100644 (file)
@@ -63,9 +63,6 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy)
 #ifdef DO_Z
    line->span.array->z[i] = (GLuint) solve_plane(fx, fy, line->zPlane);
 #endif
-#ifdef DO_FOG
-   line->span.array->attribs[FRAG_ATTRIB_FOGC][i][0] = solve_plane(fx, fy, line->fPlane);
-#endif
 #ifdef DO_RGBA
    line->span.array->rgba[i][RCOMP] = solve_plane_chan(fx, fy, line->rPlane);
    line->span.array->rgba[i][GCOMP] = solve_plane_chan(fx, fy, line->gPlane);
@@ -75,31 +72,31 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy)
 #ifdef DO_INDEX
    line->span.array->index[i] = (GLint) solve_plane(fx, fy, line->iPlane);
 #endif
-#ifdef DO_SPEC
-   line->span.array->spec[i][RCOMP] = solve_plane_chan(fx, fy, line->srPlane);
-   line->span.array->spec[i][GCOMP] = solve_plane_chan(fx, fy, line->sgPlane);
-   line->span.array->spec[i][BCOMP] = solve_plane_chan(fx, fy, line->sbPlane);
-#endif
 #if defined(DO_ATTRIBS)
    ATTRIB_LOOP_BEGIN
       GLfloat (*attribArray)[4] = line->span.array->attribs[attr];
-      GLfloat invQ;
-      if (ctx->FragmentProgram._Active) {
-         invQ = 1.0F;
-      }
-      else {
-         invQ = solve_plane_recip(fx, fy, line->vPlane[attr]);
-      }
-      attribArray[i][0] = solve_plane(fx, fy, line->sPlane[attr]) * invQ;
-      attribArray[i][1] = solve_plane(fx, fy, line->tPlane[attr]) * invQ;
-      attribArray[i][2] = solve_plane(fx, fy, line->uPlane[attr]) * invQ;
-      if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) {
+      if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0
+          && !ctx->FragmentProgram._Active) {
+         /* texcoord w/ divide by Q */
          const GLuint unit = attr - FRAG_ATTRIB_TEX0;
+         const GLfloat invQ = solve_plane_recip(fx, fy, line->attrPlane[attr][3]);
+         GLuint c;
+         for (c = 0; c < 3; c++) {
+            attribArray[i][c] = solve_plane(fx, fy, line->attrPlane[attr][c]) * invQ;
+         }
          line->span.array->lambda[unit][i]
-            = compute_lambda(line->sPlane[attr],
-                             line->tPlane[attr], invQ,
+            = compute_lambda(line->attrPlane[attr][0],
+                             line->attrPlane[attr][1], invQ,
                              line->texWidth[attr], line->texHeight[attr]);
       }
+      else {
+         /* non-texture attrib */
+         const GLfloat invW = solve_plane_recip(fx, fy, line->wPlane);
+         GLuint c;
+         for (c = 0; c < 4; c++) {
+            attribArray[i][c] = solve_plane(fx, fy, line->attrPlane[attr][c]) * invW;
+         }
+      }
    ATTRIB_LOOP_END
 #endif
 
@@ -128,10 +125,10 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
 
    /* Init the LineInfo struct */
    struct LineInfo line;
-   line.x0 = v0->win[0];
-   line.y0 = v0->win[1];
-   line.x1 = v1->win[0];
-   line.y1 = v1->win[1];
+   line.x0 = v0->attrib[FRAG_ATTRIB_WPOS][0];
+   line.y0 = v0->attrib[FRAG_ATTRIB_WPOS][1];
+   line.x1 = v1->attrib[FRAG_ATTRIB_WPOS][0];
+   line.y1 = v1->attrib[FRAG_ATTRIB_WPOS][1];
    line.dx = line.x1 - line.x0;
    line.dy = line.y1 - line.y0;
    line.len = SQRTF(line.dx * line.dx + line.dy * line.dy);
@@ -148,14 +145,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
 #ifdef DO_Z
    line.span.arrayMask |= SPAN_Z;
    compute_plane(line.x0, line.y0, line.x1, line.y1,
-                 v0->win[2], v1->win[2], line.zPlane);
-#endif
-#ifdef DO_FOG
-   line.span.arrayMask |= SPAN_FOG;
-   compute_plane(line.x0, line.y0, line.x1, line.y1,
-                 v0->attrib[FRAG_ATTRIB_FOGC][0],
-                 v1->attrib[FRAG_ATTRIB_FOGC][0],
-                 line.fPlane);
+                 v0->attrib[FRAG_ATTRIB_WPOS][2], v1->attrib[FRAG_ATTRIB_WPOS][2], line.zPlane);
 #endif
 #ifdef DO_RGBA
    line.span.arrayMask |= SPAN_RGBA;
@@ -176,51 +166,32 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
       constant_plane(v1->color[ACOMP], line.aPlane);
    }
 #endif
-#ifdef DO_SPEC
-   line.span.arrayMask |= SPAN_SPEC;
-   if (ctx->Light.ShadeModel == GL_SMOOTH) {
-      compute_plane(line.x0, line.y0, line.x1, line.y1,
-                    v0->specular[RCOMP], v1->specular[RCOMP], line.srPlane);
-      compute_plane(line.x0, line.y0, line.x1, line.y1,
-                    v0->specular[GCOMP], v1->specular[GCOMP], line.sgPlane);
-      compute_plane(line.x0, line.y0, line.x1, line.y1,
-                    v0->specular[BCOMP], v1->specular[BCOMP], line.sbPlane);
-   }
-   else {
-      constant_plane(v1->specular[RCOMP], line.srPlane);
-      constant_plane(v1->specular[GCOMP], line.sgPlane);
-      constant_plane(v1->specular[BCOMP], line.sbPlane);
-   }
-#endif
 #ifdef DO_INDEX
    line.span.arrayMask |= SPAN_INDEX;
    if (ctx->Light.ShadeModel == GL_SMOOTH) {
       compute_plane(line.x0, line.y0, line.x1, line.y1,
-                    v0->index, v1->index, line.iPlane);
+                    v0->attrib[FRAG_ATTRIB_CI][0],
+                    v1->attrib[FRAG_ATTRIB_CI][0], line.iPlane);
    }
    else {
-      constant_plane(v1->index, line.iPlane);
+      constant_plane(v1->attrib[FRAG_ATTRIB_CI][0], line.iPlane);
    }
 #endif
 #if defined(DO_ATTRIBS)
    {
-      const GLfloat invW0 = v0->win[3];
-      const GLfloat invW1 = v1->win[3];
-      line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA | SPAN_VARYING);
+      const GLfloat invW0 = v0->attrib[FRAG_ATTRIB_WPOS][3];
+      const GLfloat invW1 = v1->attrib[FRAG_ATTRIB_WPOS][3];
+      line.span.arrayMask |= SPAN_LAMBDA;
+      compute_plane(line.x0, line.y0, line.x1, line.y1, invW0, invW1, line.wPlane);
       ATTRIB_LOOP_BEGIN
-         const GLfloat s0 = v0->attrib[attr][0] * invW0;
-         const GLfloat s1 = v1->attrib[attr][0] * invW1;
-         const GLfloat t0 = v0->attrib[attr][1] * invW0;
-         const GLfloat t1 = v1->attrib[attr][1] * invW1;
-         const GLfloat r0 = v0->attrib[attr][2] * invW0;
-         const GLfloat r1 = v1->attrib[attr][2] * invW1;
-         const GLfloat q0 = v0->attrib[attr][3] * invW0;
-         const GLfloat q1 = v1->attrib[attr][3] * invW1;
-         compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[attr]);
-         compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[attr]);
-         compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[attr]);
-         compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[attr]);
-         if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) {
+         GLuint c;
+         for (c = 0; c < 4; c++) {
+            const GLfloat a0 = v0->attrib[attr][c] * invW0;
+            const GLfloat a1 = v1->attrib[attr][c] * invW1;
+            compute_plane(line.x0, line.y0, line.x1, line.y1, a0, a1, line.attrPlane[attr][c]);
+         }
+         line.span.arrayAttribs |= (1 << attr);
+         if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) {
             const GLuint u = attr - FRAG_ATTRIB_TEX0;
             const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;
             const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel];
@@ -286,9 +257,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
 
 
 #undef DO_Z
-#undef DO_FOG
 #undef DO_RGBA
 #undef DO_INDEX
-#undef DO_SPEC
 #undef DO_ATTRIBS
 #undef NAME
index 0d95f06..66891f9 100644 (file)
@@ -144,6 +144,19 @@ solve_plane_chan(GLfloat x, GLfloat y, const GLfloat plane[4])
 }
 
 
+static INLINE GLfloat
+plane_dx(const GLfloat plane[4])
+{
+   return -plane[0] / plane[2];
+}
+
+static INLINE GLfloat
+plane_dy(const GLfloat plane[4])
+{
+   return -plane[1] / plane[2];
+}
+
+
 
 /*
  * Compute how much (area) of the given pixel is inside the triangle.
@@ -337,7 +350,6 @@ compute_coveragei(const GLfloat v0[3], const GLfloat v1[3],
 }
 
 
-
 static void
 rgba_aa_tri(GLcontext *ctx,
            const SWvertex *v0,
@@ -345,7 +357,6 @@ rgba_aa_tri(GLcontext *ctx,
            const SWvertex *v2)
 {
 #define DO_Z
-#define DO_FOG
 #define DO_RGBA
 #include "s_aatritemp.h"
 }
@@ -358,72 +369,21 @@ index_aa_tri(GLcontext *ctx,
             const SWvertex *v2)
 {
 #define DO_Z
-#define DO_FOG
-#define DO_INDEX
-#include "s_aatritemp.h"
-}
-
-
-/*
- * Compute mipmap level of detail.
- * XXX we should really include the R coordinate in this computation
- * in order to do 3-D texture mipmapping.
- */
-static INLINE GLfloat
-compute_lambda(const GLfloat sPlane[4], const GLfloat tPlane[4],
-               const GLfloat qPlane[4], GLfloat cx, GLfloat cy,
-               GLfloat invQ, GLfloat texWidth, GLfloat texHeight)
-{
-   const GLfloat s = solve_plane(cx, cy, sPlane);
-   const GLfloat t = solve_plane(cx, cy, tPlane);
-   const GLfloat invQ_x1 = solve_plane_recip(cx+1.0F, cy, qPlane);
-   const GLfloat invQ_y1 = solve_plane_recip(cx, cy+1.0F, qPlane);
-   const GLfloat s_x1 = s - sPlane[0] / sPlane[2];
-   const GLfloat s_y1 = s - sPlane[1] / sPlane[2];
-   const GLfloat t_x1 = t - tPlane[0] / tPlane[2];
-   const GLfloat t_y1 = t - tPlane[1] / tPlane[2];
-   GLfloat dsdx = s_x1 * invQ_x1 - s * invQ;
-   GLfloat dsdy = s_y1 * invQ_y1 - s * invQ;
-   GLfloat dtdx = t_x1 * invQ_x1 - t * invQ;
-   GLfloat dtdy = t_y1 * invQ_y1 - t * invQ;
-   GLfloat maxU, maxV, rho, lambda;
-   dsdx = FABSF(dsdx);
-   dsdy = FABSF(dsdy);
-   dtdx = FABSF(dtdx);
-   dtdy = FABSF(dtdy);
-   maxU = MAX2(dsdx, dsdy) * texWidth;
-   maxV = MAX2(dtdx, dtdy) * texHeight;
-   rho = MAX2(maxU, maxV);
-   lambda = LOG2(rho);
-   return lambda;
-}
-
-
-static void
-tex_aa_tri(GLcontext *ctx,
-          const SWvertex *v0,
-          const SWvertex *v1,
-          const SWvertex *v2)
-{
-#define DO_Z
-#define DO_FOG
-#define DO_RGBA
 #define DO_ATTRIBS
+#define DO_INDEX
 #include "s_aatritemp.h"
 }
 
 
 static void
-spec_tex_aa_tri(GLcontext *ctx,
-               const SWvertex *v0,
-               const SWvertex *v1,
-               const SWvertex *v2)
+general_aa_tri(GLcontext *ctx,
+               const SWvertex *v0,
+               const SWvertex *v1,
+               const SWvertex *v2)
 {
 #define DO_Z
-#define DO_FOG
 #define DO_RGBA
 #define DO_ATTRIBS
-#define DO_SPEC
 #include "s_aatritemp.h"
 }
 
@@ -436,16 +396,15 @@ spec_tex_aa_tri(GLcontext *ctx,
 void
 _swrast_set_aa_triangle_function(GLcontext *ctx)
 {
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
    ASSERT(ctx->Polygon.SmoothFlag);
 
    if (ctx->Texture._EnabledCoordUnits != 0
-       || ctx->FragmentProgram._Current) {
-      if (NEED_SECONDARY_COLOR(ctx)) {
-         SWRAST_CONTEXT(ctx)->Triangle = spec_tex_aa_tri;
-      }
-      else {
-         SWRAST_CONTEXT(ctx)->Triangle = tex_aa_tri;
-      }
+       || ctx->FragmentProgram._Current
+       || swrast->_FogEnabled
+       || NEED_SECONDARY_COLOR(ctx)) {
+      SWRAST_CONTEXT(ctx)->Triangle = general_aa_tri;
    }
    else if (ctx->Visual.rgbMode) {
       SWRAST_CONTEXT(ctx)->Triangle = rgba_aa_tri;
index 4162ed6..34a2305 100644 (file)
  *    DO_Z         - if defined, compute Z values
  *    DO_RGBA      - if defined, compute RGBA values
  *    DO_INDEX     - if defined, compute color index values
- *    DO_SPEC      - if defined, compute specular RGB values
  *    DO_ATTRIBS   - if defined, compute texcoords, varying, etc.
  */
 
 /*void triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv )*/
 {
    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   const GLfloat *p0 = v0->win;
-   const GLfloat *p1 = v1->win;
-   const GLfloat *p2 = v2->win;
+   const GLfloat *p0 = v0->attrib[FRAG_ATTRIB_WPOS];
+   const GLfloat *p1 = v1->attrib[FRAG_ATTRIB_WPOS];
+   const GLfloat *p2 = v2->attrib[FRAG_ATTRIB_WPOS];
    const SWvertex *vMin, *vMid, *vMax;
    GLint iyMin, iyMax;
    GLfloat yMin, yMax;
 #ifdef DO_Z
    GLfloat zPlane[4];
 #endif
-#ifdef DO_FOG
-   GLfloat fogPlane[4];
-#else
-   GLfloat *fog = NULL;
-#endif
 #ifdef DO_RGBA
    GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];
 #endif
 #ifdef DO_INDEX
    GLfloat iPlane[4];
 #endif
-#ifdef DO_SPEC
-   GLfloat srPlane[4], sgPlane[4], sbPlane[4];
-#endif
 #if defined(DO_ATTRIBS)
-   GLfloat sPlane[FRAG_ATTRIB_MAX][4];  /* texture S */
-   GLfloat tPlane[FRAG_ATTRIB_MAX][4];  /* texture T */
-   GLfloat uPlane[FRAG_ATTRIB_MAX][4];  /* texture R */
-   GLfloat vPlane[FRAG_ATTRIB_MAX][4];  /* texture Q */
-   GLfloat texWidth[FRAG_ATTRIB_MAX];
-   GLfloat texHeight[FRAG_ATTRIB_MAX];
+   GLfloat attrPlane[FRAG_ATTRIB_MAX][4][4];
+   GLfloat wPlane[4];  /* win[3] */
 #endif
    GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign;
    
@@ -86,9 +73,9 @@
 
    /* determine bottom to top order of vertices */
    {
-      GLfloat y0 = v0->win[1];
-      GLfloat y1 = v1->win[1];
-      GLfloat y2 = v2->win[1];
+      GLfloat y0 = v0->attrib[FRAG_ATTRIB_WPOS][1];
+      GLfloat y1 = v1->attrib[FRAG_ATTRIB_WPOS][1];
+      GLfloat y2 = v2->attrib[FRAG_ATTRIB_WPOS][1];
       if (y0 <= y1) {
         if (y1 <= y2) {
            vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
       }
    }
 
-   majDx = vMax->win[0] - vMin->win[0];
-   majDy = vMax->win[1] - vMin->win[1];
+   majDx = vMax->attrib[FRAG_ATTRIB_WPOS][0] - vMin->attrib[FRAG_ATTRIB_WPOS][0];
+   majDy = vMax->attrib[FRAG_ATTRIB_WPOS][1] - vMin->attrib[FRAG_ATTRIB_WPOS][1];
 
    {
-      const GLfloat botDx = vMid->win[0] - vMin->win[0];
-      const GLfloat botDy = vMid->win[1] - vMin->win[1];
+      const GLfloat botDx = vMid->attrib[FRAG_ATTRIB_WPOS][0] - vMin->attrib[FRAG_ATTRIB_WPOS][0];
+      const GLfloat botDy = vMid->attrib[FRAG_ATTRIB_WPOS][1] - vMin->attrib[FRAG_ATTRIB_WPOS][1];
       const GLfloat area = majDx * botDy - botDx * majDy;
       /* Do backface culling */
       if (area * bf < 0 || area == 0 || IS_INF_OR_NAN(area))
    compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
    span.arrayMask |= SPAN_Z;
 #endif
-#ifdef DO_FOG
-   compute_plane(p0, p1, p2,
-                 v0->attrib[FRAG_ATTRIB_FOGC][0],
-                 v1->attrib[FRAG_ATTRIB_FOGC][0],
-                 v2->attrib[FRAG_ATTRIB_FOGC][0],
-                 fogPlane);
-   span.arrayMask |= SPAN_FOG;
-#endif
 #ifdef DO_RGBA
    if (ctx->Light.ShadeModel == GL_SMOOTH) {
       compute_plane(p0, p1, p2, v0->color[RCOMP], v1->color[RCOMP], v2->color[RCOMP], rPlane);
 #endif
 #ifdef DO_INDEX
    if (ctx->Light.ShadeModel == GL_SMOOTH) {
-      compute_plane(p0, p1, p2, (GLfloat) v0->index,
-                    v1->index, v2->index, iPlane);
+      compute_plane(p0, p1, p2, (GLfloat) v0->attrib[FRAG_ATTRIB_CI][0],
+                    v1->attrib[FRAG_ATTRIB_CI][0], v2->attrib[FRAG_ATTRIB_CI][0], iPlane);
    }
    else {
-      constant_plane(v2->index, iPlane);
+      constant_plane(v2->attrib[FRAG_ATTRIB_CI][0], iPlane);
    }
    span.arrayMask |= SPAN_INDEX;
 #endif
-#ifdef DO_SPEC
-   if (ctx->Light.ShadeModel == GL_SMOOTH) {
-      compute_plane(p0, p1, p2, v0->specular[RCOMP], v1->specular[RCOMP], v2->specular[RCOMP], srPlane);
-      compute_plane(p0, p1, p2, v0->specular[GCOMP], v1->specular[GCOMP], v2->specular[GCOMP], sgPlane);
-      compute_plane(p0, p1, p2, v0->specular[BCOMP], v1->specular[BCOMP], v2->specular[BCOMP], sbPlane);
-   }
-   else {
-      constant_plane(v2->specular[RCOMP], srPlane);
-      constant_plane(v2->specular[GCOMP], sgPlane);
-      constant_plane(v2->specular[BCOMP], sbPlane);
-   }
-   span.arrayMask |= SPAN_SPEC;
-#endif
 #if defined(DO_ATTRIBS)
    {
-      const GLfloat invW0 = v0->win[3];
-      const GLfloat invW1 = v1->win[3];
-      const GLfloat invW2 = v2->win[3];
+      const GLfloat invW0 = v0->attrib[FRAG_ATTRIB_WPOS][3];
+      const GLfloat invW1 = v1->attrib[FRAG_ATTRIB_WPOS][3];
+      const GLfloat invW2 = v2->attrib[FRAG_ATTRIB_WPOS][3];
+      compute_plane(p0, p1, p2, invW0, invW1, invW2, wPlane);
+      span.attrStepX[FRAG_ATTRIB_WPOS][3] = plane_dx(wPlane);
+      span.attrStepY[FRAG_ATTRIB_WPOS][3] = plane_dy(wPlane);
       ATTRIB_LOOP_BEGIN
-         const GLfloat s0 = v0->attrib[attr][0] * invW0;
-         const GLfloat s1 = v1->attrib[attr][0] * invW1;
-         const GLfloat s2 = v2->attrib[attr][0] * invW2;
-         const GLfloat t0 = v0->attrib[attr][1] * invW0;
-         const GLfloat t1 = v1->attrib[attr][1] * invW1;
-         const GLfloat t2 = v2->attrib[attr][1] * invW2;
-         const GLfloat r0 = v0->attrib[attr][2] * invW0;
-         const GLfloat r1 = v1->attrib[attr][2] * invW1;
-         const GLfloat r2 = v2->attrib[attr][2] * invW2;
-         const GLfloat q0 = v0->attrib[attr][3] * invW0;
-         const GLfloat q1 = v1->attrib[attr][3] * invW1;
-         const GLfloat q2 = v2->attrib[attr][3] * invW2;
-         compute_plane(p0, p1, p2, s0, s1, s2, sPlane[attr]);
-         compute_plane(p0, p1, p2, t0, t1, t2, tPlane[attr]);
-         compute_plane(p0, p1, p2, r0, r1, r2, uPlane[attr]);
-         compute_plane(p0, p1, p2, q0, q1, q2, vPlane[attr]);
-         if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) {
-            const GLuint u = attr - FRAG_ATTRIB_TEX0;
-            const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;
-            const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel];
-            texWidth[attr]  = (GLfloat) texImage->Width;
-            texHeight[attr] = (GLfloat) texImage->Height;
+         GLuint c;
+         if (swrast->_InterpMode[attr] == GL_FLAT) {
+            for (c = 0; c < 4; c++) {
+               constant_plane(v2->attrib[attr][c] * invW2, attrPlane[attr][c]);
+            }
          }
          else {
-            texWidth[attr] = texHeight[attr] = 1.0;
+            for (c = 0; c < 4; c++) {
+               const GLfloat a0 = v0->attrib[attr][c] * invW0;
+               const GLfloat a1 = v1->attrib[attr][c] * invW1;
+               const GLfloat a2 = v2->attrib[attr][c] * invW2;
+               compute_plane(p0, p1, p2, a0, a1, a2, attrPlane[attr][c]);
+            }
+         }
+         for (c = 0; c < 4; c++) {
+            span.attrStepX[attr][c] = plane_dx(attrPlane[attr][c]);
+            span.attrStepY[attr][c] = plane_dy(attrPlane[attr][c]);
          }
       ATTRIB_LOOP_END
    }
-   span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA | SPAN_VARYING);
 #endif
 
    /* Begin bottom-to-top scan over the triangle.
     * edges, stopping when we find that coverage = 0.  If the long edge
     * is on the left we scan left-to-right.  Else, we scan right-to-left.
     */
-   yMin = vMin->win[1];
-   yMax = vMax->win[1];
+   yMin = vMin->attrib[FRAG_ATTRIB_WPOS][1];
+   yMax = vMax->attrib[FRAG_ATTRIB_WPOS][1];
    iyMin = (GLint) yMin;
    iyMax = (GLint) yMax + 1;
 
    if (ltor) {
       /* scan left to right */
-      const GLfloat *pMin = vMin->win;
-      const GLfloat *pMid = vMid->win;
-      const GLfloat *pMax = vMax->win;
+      const GLfloat *pMin = vMin->attrib[FRAG_ATTRIB_WPOS];
+      const GLfloat *pMid = vMid->attrib[FRAG_ATTRIB_WPOS];
+      const GLfloat *pMax = vMax->attrib[FRAG_ATTRIB_WPOS];
       const GLfloat dxdy = majDx / majDy;
       const GLfloat xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
       GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
 
          /* enter interior of triangle */
          ix = startX;
+
+#if defined(DO_ATTRIBS)
+         /* compute attributes at left-most fragment */
+         span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 0.5, iy + 0.5, wPlane);
+         ATTRIB_LOOP_BEGIN
+            GLuint c;
+            for (c = 0; c < 4; c++) {
+               span.attrStart[attr][c] = solve_plane(ix + 0.5, iy + 0.5, attrPlane[attr][c]);
+            }
+         ATTRIB_LOOP_END
+#endif
+
          count = 0;
          while (coverage > 0.0F) {
             /* (cx,cy) = center of fragment */
 #ifdef DO_Z
             array->z[count] = (GLuint) solve_plane(cx, cy, zPlane);
 #endif
-#ifdef DO_FOG
-           array->attribs[FRAG_ATTRIB_FOGC][count][0] = solve_plane(cx, cy, fogPlane);
-#endif
 #ifdef DO_RGBA
             array->rgba[count][RCOMP] = solve_plane_chan(cx, cy, rPlane);
             array->rgba[count][GCOMP] = solve_plane_chan(cx, cy, gPlane);
 #ifdef DO_INDEX
             array->index[count] = (GLint) solve_plane(cx, cy, iPlane);
 #endif
-#ifdef DO_SPEC
-            array->spec[count][RCOMP] = solve_plane_chan(cx, cy, srPlane);
-            array->spec[count][GCOMP] = solve_plane_chan(cx, cy, sgPlane);
-            array->spec[count][BCOMP] = solve_plane_chan(cx, cy, sbPlane);
-#endif
-#if defined(DO_ATTRIBS)
-            ATTRIB_LOOP_BEGIN
-               GLfloat invQ = solve_plane_recip(cx, cy, vPlane[attr]);
-               array->attribs[attr][count][0] = solve_plane(cx, cy, sPlane[attr]) * invQ;
-               array->attribs[attr][count][1] = solve_plane(cx, cy, tPlane[attr]) * invQ;
-               array->attribs[attr][count][2] = solve_plane(cx, cy, uPlane[attr]) * invQ;
-               if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) {
-                  const GLuint unit = attr - FRAG_ATTRIB_TEX0;
-                  array->lambda[unit][count] = compute_lambda(sPlane[attr], tPlane[attr],
-                                                              vPlane[attr], cx, cy, invQ,
-                                                              texWidth[attr], texHeight[attr]);
-               }
-            ATTRIB_LOOP_END
-#endif
             ix++;
             count++;
             coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
          span.x = startX;
          span.y = iy;
          span.end = (GLuint) ix - (GLuint) startX;
-         ASSERT(span.interpMask == 0);
 #if defined(DO_RGBA)
          _swrast_write_rgba_span(ctx, &span);
 #else
    }
    else {
       /* scan right to left */
-      const GLfloat *pMin = vMin->win;
-      const GLfloat *pMid = vMid->win;
-      const GLfloat *pMax = vMax->win;
+      const GLfloat *pMin = vMin->attrib[FRAG_ATTRIB_WPOS];
+      const GLfloat *pMid = vMid->attrib[FRAG_ATTRIB_WPOS];
+      const GLfloat *pMax = vMax->attrib[FRAG_ATTRIB_WPOS];
       const GLfloat dxdy = majDx / majDy;
       const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
       GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
 #ifdef DO_Z
             array->z[ix] = (GLuint) solve_plane(cx, cy, zPlane);
 #endif
-#ifdef DO_FOG
-            array->attribs[FRAG_ATTRIB_FOGC][ix][0] = solve_plane(cx, cy, fogPlane);
-#endif
 #ifdef DO_RGBA
             array->rgba[ix][RCOMP] = solve_plane_chan(cx, cy, rPlane);
             array->rgba[ix][GCOMP] = solve_plane_chan(cx, cy, gPlane);
 #ifdef DO_INDEX
             array->index[ix] = (GLint) solve_plane(cx, cy, iPlane);
 #endif
-#ifdef DO_SPEC
-            array->spec[ix][RCOMP] = solve_plane_chan(cx, cy, srPlane);
-            array->spec[ix][GCOMP] = solve_plane_chan(cx, cy, sgPlane);
-            array->spec[ix][BCOMP] = solve_plane_chan(cx, cy, sbPlane);
-#endif
-#if defined(DO_ATTRIBS)
-            ATTRIB_LOOP_BEGIN
-               GLfloat invQ = solve_plane_recip(cx, cy, vPlane[attr]);
-               array->attribs[attr][ix][0] = solve_plane(cx, cy, sPlane[attr]) * invQ;
-               array->attribs[attr][ix][1] = solve_plane(cx, cy, tPlane[attr]) * invQ;
-               array->attribs[attr][ix][2] = solve_plane(cx, cy, uPlane[attr]) * invQ;
-               if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) {
-                  const GLuint unit = attr - FRAG_ATTRIB_TEX0;
-                  array->lambda[unit][ix] = compute_lambda(sPlane[attr],
-                                                           tPlane[attr],
-                                                           vPlane[attr],
-                                                           cx, cy, invQ,
-                                                           texWidth[attr],
-                                                           texHeight[attr]);
-               }
-            ATTRIB_LOOP_END
-#endif
             ix--;
             count++;
             coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
          }
          
+#if defined(DO_ATTRIBS)
+         /* compute attributes at left-most fragment */
+         span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 1.5, iy + 0.5, wPlane);
+         ATTRIB_LOOP_BEGIN
+            GLuint c;
+            for (c = 0; c < 4; c++) {
+               span.attrStart[attr][c] = solve_plane(ix + 1.5, iy + 0.5, attrPlane[attr][c]);
+            }
+         ATTRIB_LOOP_END
+#endif
+
          if (startX <= ix)
             continue;
 
             SWspanarrays *array = span.array;
             GLint j;
             for (j = 0; j < (GLint) n; j++) {
+               array->coverage[j] = array->coverage[j + left];
 #ifdef DO_RGBA
                COPY_CHAN4(array->rgba[j], array->rgba[j + left]);
 #endif
-#ifdef DO_SPEC
-               COPY_CHAN4(array->spec[j], array->spec[j + left]);
-#endif
 #ifdef DO_INDEX
                array->index[j] = array->index[j + left];
 #endif
 #ifdef DO_Z
                array->z[j] = array->z[j + left];
 #endif
-#ifdef DO_FOG
-               array->attribs[FRAG_ATTRIB_FOGC][j][0]
-                  = array->attribs[FRAG_ATTRIB_FOGC][j + left][0];
-#endif
-#if defined(DO_ATTRIBS)
-               array->lambda[0][j] = array->lambda[0][j + left];
-#endif
-               array->coverage[j] = array->coverage[j + left];
             }
          }
-#ifdef DO_ATTRIBS
-         /* shift texcoords, varying */
-         {
-            SWspanarrays *array = span.array;
-            ATTRIB_LOOP_BEGIN
-               GLint j;
-               for (j = 0; j < (GLint) n; j++) {
-                  array->attribs[attr][j][0] = array->attribs[attr][j + left][0];
-                  array->attribs[attr][j][1] = array->attribs[attr][j + left][1];
-                  array->attribs[attr][j][2] = array->attribs[attr][j + left][2];
-                  /*array->lambda[unit][j] = array->lambda[unit][j + left];*/
-               }
-            ATTRIB_LOOP_END
-         }
-#endif
 
          span.x = left;
          span.y = iy;
          span.end = n;
-         ASSERT(span.interpMask == 0);
 #if defined(DO_RGBA)
          _swrast_write_rgba_span(ctx, &span);
 #else
 }
 
 
-#ifdef DO_Z
 #undef DO_Z
-#endif
-
-#ifdef DO_FOG
-#undef DO_FOG
-#endif
-
-#ifdef DO_RGBA
 #undef DO_RGBA
-#endif
-
-#ifdef DO_INDEX
 #undef DO_INDEX
-#endif
-
-#ifdef DO_SPEC
-#undef DO_SPEC
-#endif
-
-#ifdef DO_ATTRIBS
 #undef DO_ATTRIBS
-#endif
-
-#ifdef DO_OCCLUSION_TEST
 #undef DO_OCCLUSION_TEST
-#endif
index af8a6ba..3c55d3e 100644 (file)
@@ -111,13 +111,13 @@ _swrast_alpha_test(const GLcontext *ctx, SWspan *span)
    if (span->arrayMask & SPAN_RGBA) {
       /* Use array's alpha values */
       if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-         GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
+         GLubyte (*rgba)[4] = span->array->rgba8;
          GLubyte ref;
          CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef);
          ALPHA_TEST(rgba[i][ACOMP], ;);
       }
       else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-         GLushort (*rgba)[4] = span->array->color.sz2.rgba;
+         GLushort (*rgba)[4] = span->array->rgba16;
          GLushort ref;
          CLAMPED_FLOAT_TO_USHORT(ref, ctx->Color.AlphaRef);
          ALPHA_TEST(rgba[i][ACOMP], ;);
index 4c23705..563b5fe 100644 (file)
@@ -83,15 +83,7 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
       _swrast_validate_derived( ctx );
 
    INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_XY);
-
-   _swrast_span_default_color(ctx, &span);
-   _swrast_span_default_secondary_color(ctx, &span);
-   if (ctx->Depth.Test)
-      _swrast_span_default_z(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
-   if (ctx->Texture._EnabledCoordUnits)
-      _swrast_span_default_texcoords(ctx, &span);
+   _swrast_span_default_attribs(ctx, &span);
 
    for (row = 0; row < height; row++) {
       const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
@@ -189,20 +181,13 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
       _swrast_validate_derived( ctx );
 
    INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_MASK);
+   _swrast_span_default_attribs(ctx, &span);
 
    /*span.arrayMask |= SPAN_MASK;*/  /* we'll init span.mask[] */
    span.x = px;
    span.y = py;
    /*span.end = width;*/
 
-   _swrast_span_default_color(ctx, &span);
-   if (ctx->Depth.Test)
-      _swrast_span_default_z(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
-   if (ctx->Texture._EnabledCoordUnits)
-      _swrast_span_default_texcoords(ctx, &span);
-
    for (row=0; row<height; row++, span.y++) {
       const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
                  bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
index 2f25edb..d432119 100644 (file)
@@ -189,6 +189,37 @@ _swrast_update_texture_env( GLcontext *ctx )
 
 
 /**
+ * Determine if we can defer texturing/shading until after Z/stencil
+ * testing.  This potentially allows us to skip texturing/shading for
+ * lots of fragments.
+ */
+static void
+_swrast_update_deferred_texture(GLcontext *ctx)
+{
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+   if (ctx->Color.AlphaEnabled) {
+      /* alpha test depends on post-texture/shader colors */
+      swrast->_DeferredTexture = GL_FALSE;
+   }
+   else {
+      const struct gl_fragment_program *fprog
+         = ctx->FragmentProgram._Current;
+      if (fprog && (fprog->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR))) {
+         /* Z comes from fragment program/shader */
+         swrast->_DeferredTexture = GL_FALSE;
+      }
+      else if (ctx->Query.CurrentOcclusionObject) {
+         /* occlusion query depends on shader discard/kill results */
+         swrast->_DeferredTexture = GL_FALSE;
+      }
+      else {
+         swrast->_DeferredTexture = GL_TRUE;
+      }
+   }
+}
+
+
+/**
  * Update swrast->_FogColor and swrast->_FogEnable values.
  */
 static void
@@ -324,7 +355,6 @@ _swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
       swrast->Line = _swrast_add_spec_terms_line;
    }
 
-
    swrast->Line( ctx, v0, v1 );
 }
 
@@ -505,50 +535,58 @@ _swrast_update_texture_samplers(GLcontext *ctx)
 
 
 /**
- * Update swrast->_ActiveAttribs and swrast->_NumActiveAttribs
+ * Update swrast->_ActiveAttribs, swrast->_NumActiveAttribs, swrast->_ActiveAtttribMask.
  */
 static void
 _swrast_update_fragment_attribs(GLcontext *ctx)
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    GLuint attribsMask;
-   
+
+   /*
+    * Compute _ActiveAttribsMask = which fragment attributes are needed.
+    */
    if (ctx->FragmentProgram._Current) {
+      /* fragment program/shader */
       attribsMask = ctx->FragmentProgram._Current->Base.InputsRead;
    }
+   else if (ctx->ATIFragmentShader._Enabled) {
+      attribsMask = ~0;  /* XXX fix me */
+   }
    else {
-      GLuint u;
+      /* fixed function */
       attribsMask = 0x0;
 
-#if 0 /* not yet */
-      if (ctx->Depth.Test)
-         attribsMask |= FRAG_BIT_WPOS;
-      if (NEED_SECONDARY_COLOR(ctx))
-         attribsMask |= FRAG_BIT_COL1;
+#if CHAN_TYPE == GL_FLOAT
+      attribsMask |= FRAG_BIT_COL0;
 #endif
+
+      if (ctx->Fog.ColorSumEnabled ||
+          (ctx->Light.Enabled &&
+           ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
+         attribsMask |= FRAG_BIT_COL1;
+      }
+
       if (swrast->_FogEnabled)
          attribsMask |= FRAG_BIT_FOGC;
 
-      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
-         if (ctx->Texture.Unit[u]._ReallyEnabled) {
-            attribsMask |= FRAG_BIT_TEX(u);
-         }
-      }
+      attribsMask |= (ctx->Texture._EnabledUnits << FRAG_ATTRIB_TEX0);
    }
 
-   /* don't want to interpolate these generic attribs just yet */
-   /* XXX temporary */
-   attribsMask &= ~(FRAG_BIT_WPOS |
-                    FRAG_BIT_COL0 |
-                    FRAG_BIT_COL1 |
-                    FRAG_BIT_FOGC);
+   swrast->_ActiveAttribMask = attribsMask;
 
    /* Update _ActiveAttribs[] list */
    {
       GLuint i, num = 0;
       for (i = 0; i < FRAG_ATTRIB_MAX; i++) {
-         if (attribsMask & (1 << i))
+         if (attribsMask & (1 << i)) {
             swrast->_ActiveAttribs[num++] = i;
+            /* how should this attribute be interpolated? */
+            if (i == FRAG_ATTRIB_COL0 || i == FRAG_ATTRIB_COL1)
+               swrast->_InterpMode[i] = ctx->Light.ShadeModel;
+            else
+               swrast->_InterpMode[i] = GL_SMOOTH;
+         }
       }
       swrast->_NumActiveAttribs = num;
    }
@@ -627,14 +665,19 @@ _swrast_validate_derived( GLcontext *ctx )
       if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM))
          _swrast_update_texture_samplers( ctx );
 
-      if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM))
-         _swrast_validate_texture_images( ctx );
+      if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM)) {
+         _swrast_validate_texture_images(ctx);
+         if (swrast->NewState & (_NEW_COLOR)) {
+            _swrast_update_deferred_texture(ctx);
+         }
+      }
 
       if (swrast->NewState & _SWRAST_NEW_RASTERMASK)
         _swrast_update_rasterflags( ctx );
 
       if (swrast->NewState & (_NEW_DEPTH |
                               _NEW_FOG |
+                              _NEW_LIGHT |
                               _NEW_PROGRAM |
                               _NEW_TEXTURE))
          _swrast_update_fragment_attribs(ctx);
@@ -787,14 +830,11 @@ _swrast_CreateContext( GLcontext *ctx )
    }
    swrast->SpanArrays->ChanType = CHAN_TYPE;
 #if CHAN_TYPE == GL_UNSIGNED_BYTE
-   swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz1.rgba;
-   swrast->SpanArrays->spec = swrast->SpanArrays->color.sz1.spec;
+   swrast->SpanArrays->rgba = swrast->SpanArrays->rgba8;
 #elif CHAN_TYPE == GL_UNSIGNED_SHORT
-   swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz2.rgba;
-   swrast->SpanArrays->spec = swrast->SpanArrays->color.sz2.spec;
+   swrast->SpanArrays->rgba = swrast->SpanArrays->rgba16;
 #else
    swrast->SpanArrays->rgba = swrast->SpanArrays->attribs[FRAG_ATTRIB_COL0];
-   swrast->SpanArrays->spec = swrast->SpanArrays->attribs[FRAG_ATTRIB_COL1];
 #endif
 
    /* init point span buffer */
@@ -896,7 +936,10 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v )
 
    if (SWRAST_DEBUG_VERTICES) {
       _mesa_debug(ctx, "win %f %f %f %f\n",
-                  v->win[0], v->win[1], v->win[2], v->win[3]);
+                  v->attrib[FRAG_ATTRIB_WPOS][0],
+                  v->attrib[FRAG_ATTRIB_WPOS][1],
+                  v->attrib[FRAG_ATTRIB_WPOS][2],
+                  v->attrib[FRAG_ATTRIB_WPOS][3]);
 
       for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
         if (ctx->Texture.Unit[i]._ReallyEnabled)
@@ -909,18 +952,17 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v )
 #if CHAN_TYPE == GL_FLOAT
       _mesa_debug(ctx, "color %f %f %f %f\n",
                   v->color[0], v->color[1], v->color[2], v->color[3]);
-      _mesa_debug(ctx, "spec %f %f %f %f\n",
-                  v->specular[0], v->specular[1],
-                  v->specular[2], v->specular[3]);
 #else
       _mesa_debug(ctx, "color %d %d %d %d\n",
                   v->color[0], v->color[1], v->color[2], v->color[3]);
-      _mesa_debug(ctx, "spec %d %d %d %d\n",
-                  v->specular[0], v->specular[1],
-                  v->specular[2], v->specular[3]);
 #endif
+      _mesa_debug(ctx, "spec %g %g %g %g\n",
+                  v->attrib[FRAG_ATTRIB_COL1][0],
+                  v->attrib[FRAG_ATTRIB_COL1][1],
+                  v->attrib[FRAG_ATTRIB_COL1][2],
+                  v->attrib[FRAG_ATTRIB_COL1][3]);
       _mesa_debug(ctx, "fog %f\n", v->attrib[FRAG_ATTRIB_FOGC][0]);
-      _mesa_debug(ctx, "index %d\n", v->index);
+      _mesa_debug(ctx, "index %d\n", v->attrib[FRAG_ATTRIB_CI][0]);
       _mesa_debug(ctx, "pointsize %f\n", v->pointSize);
       _mesa_debug(ctx, "\n");
    }
index c8333b8..f118eb9 100644 (file)
@@ -132,6 +132,7 @@ typedef struct
    GLboolean _PreferPixelFog;    /* Compute fog blend factor per fragment? */
    GLboolean _AnyTextureCombine;
    GLboolean _FogEnabled;
+   GLboolean _DeferredTexture;
    GLenum _FogMode;  /* either GL_FOG_MODE or fragment program's fog mode */
 
    /** Multiple render targets */
@@ -140,8 +141,12 @@ typedef struct
 
    /** List/array of the fragment attributes to interpolate */
    GLuint _ActiveAttribs[FRAG_ATTRIB_MAX];
+   /** Same info, but as a bitmask */
+   GLbitfield _ActiveAttribMask;
    /** Number of fragment attributes to interpolate */
    GLuint _NumActiveAttribs;
+   /** Indicates how each attrib is to be interpolated (lines/tris) */
+   GLenum _InterpMode[FRAG_ATTRIB_MAX]; /* GL_FLAT or GL_SMOOTH (for now) */
 
    /* Accum buffer temporaries.
     */
index 012839c..53e584b 100644 (file)
@@ -94,7 +94,6 @@ static void
 copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
                       GLint width, GLint height, GLint destx, GLint desty)
 {
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
    GLint row;
    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
    const GLbitfield transferOps = ctx->_ImageTransferState;
@@ -104,12 +103,7 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
    SWspan span;
 
    INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
-
-   if (ctx->Depth.Test)
-      _swrast_span_default_z(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
-   _swrast_span_default_secondary_color(ctx, &span);
+   _swrast_span_default_attribs(ctx, &span);
 
    /* allocate space for GLfloat image */
    tmpImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
@@ -194,7 +188,6 @@ static void
 copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
                  GLint width, GLint height, GLint destx, GLint desty)
 {
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
    GLfloat *tmpImage, *p;
    GLint sy, dy, stepy, row;
    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
@@ -240,11 +233,7 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
    }
 
    INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
-   if (ctx->Depth.Test)
-      _swrast_span_default_z(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
-   _swrast_span_default_secondary_color(ctx, &span);
+   _swrast_span_default_attribs(ctx, &span);
 
    if (overlapping) {
       tmpImage = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat) * 4);
@@ -313,7 +302,6 @@ copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
                 GLint width, GLint height,
                 GLint destx, GLint desty )
 {
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
    GLuint *tmpImage,*p;
    GLint sy, dy, stepy;
    GLint j;
@@ -327,6 +315,7 @@ copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
    }
 
    INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_INDEX);
+   _swrast_span_default_attribs(ctx, &span);
 
    if (ctx->DrawBuffer == ctx->ReadBuffer) {
       overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
@@ -350,11 +339,6 @@ copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
       stepy = 1;
    }
 
-   if (ctx->Depth.Test)
-      _swrast_span_default_z(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
-
    if (overlapping) {
       GLint ssy = sy;
       tmpImage = (GLuint *) _mesa_malloc(width * height * sizeof(GLuint));
@@ -450,7 +434,6 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
                    GLint width, GLint height,
                    GLint destx, GLint desty )
 {
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
    struct gl_framebuffer *fb = ctx->ReadBuffer;
    struct gl_renderbuffer *readRb = fb->_DepthBuffer;
    GLfloat *p, *tmpImage;
@@ -466,6 +449,7 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
    }
 
    INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_Z);
+   _swrast_span_default_attribs(ctx, &span);
 
    if (ctx->DrawBuffer == ctx->ReadBuffer) {
       overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
@@ -489,11 +473,6 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
       stepy = 1;
    }
 
-   _swrast_span_default_color(ctx, &span);
-   _swrast_span_default_secondary_color(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
-
    if (overlapping) {
       GLint ssy = sy;
       tmpImage = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat));
index cd5b7bc..d971d90 100644 (file)
@@ -71,13 +71,7 @@ fast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y,
    }
 
    INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
-   _swrast_span_default_secondary_color(ctx, &span);
-   if (ctx->Depth.Test)
-      _swrast_span_default_z(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
-   if (ctx->Texture._EnabledCoordUnits)
-      _swrast_span_default_texcoords(ctx, &span);
+   _swrast_span_default_attribs(ctx, &span);
 
    /* copy input params since clipping may change them */
    unpack = *userUnpack;
@@ -274,9 +268,9 @@ fast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y,
             for (row = 0; row < drawHeight; row++) {
                ASSERT(drawWidth <= MAX_WIDTH);
                _mesa_map_ci8_to_rgba8(ctx, drawWidth, src,
-                                      span.array->color.sz1.rgba);
+                                      span.array->rgba8);
                rb->PutRow(ctx, rb, drawWidth, destX, destY,
-                          span.array->color.sz1.rgba, NULL);
+                          span.array->rgba8, NULL);
                src += unpack.RowLength;
                destY += yStep;
             }
@@ -287,12 +281,12 @@ fast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y,
             for (row = 0; row < drawHeight; row++) {
                ASSERT(drawWidth <= MAX_WIDTH);
                _mesa_map_ci8_to_rgba8(ctx, drawWidth, src,
-                                      span.array->color.sz1.rgba);
+                                      span.array->rgba8);
                span.x = destX;
                span.y = destY;
                span.end = drawWidth;
                _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span,
-                                              span.array->color.sz1.rgba);
+                                              span.array->rgba8);
                src += unpack.RowLength;
                destY++;
             }
@@ -333,18 +327,13 @@ draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
                    const struct gl_pixelstore_attrib *unpack,
                    const GLvoid *pixels )
 {
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
    const GLint imgX = x, imgY = y;
    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
    GLint row, skipPixels;
    SWspan span;
 
    INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_INDEX);
-
-   if (ctx->Depth.Test)
-      _swrast_span_default_z(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
+   _swrast_span_default_attribs(ctx, &span);
 
    /*
     * General solution
@@ -433,20 +422,13 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
                    const struct gl_pixelstore_attrib *unpack,
                    const GLvoid *pixels )
 {
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
    const GLboolean scaleOrBias
       = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
    SWspan span;
 
    INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_Z);
-
-   _swrast_span_default_color(ctx, &span);
-   _swrast_span_default_secondary_color(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
-   if (ctx->Texture._EnabledCoordUnits)
-      _swrast_span_default_texcoords(ctx, &span);
+   _swrast_span_default_attribs(ctx, &span);
 
    if (type == GL_UNSIGNED_SHORT
        && ctx->DrawBuffer->Visual.depthBits == 16
@@ -550,7 +532,6 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
                   const struct gl_pixelstore_attrib *unpack,
                   const GLvoid *pixels )
 {
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
    const GLint imgX = x, imgY = y;
    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
    GLfloat *convImage = NULL;
@@ -562,14 +543,8 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
                              unpack, pixels))
       return;
 
-   INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
-   _swrast_span_default_secondary_color(ctx, &span);
-   if (ctx->Depth.Test)
-      _swrast_span_default_z(ctx, &span);
-   if (swrast->_FogEnabled)
-      _swrast_span_default_fog(ctx, &span);
-   if (ctx->Texture._EnabledCoordUnits)
-      _swrast_span_default_texcoords(ctx, &span);
+   INIT_SPAN(span, GL_BITMAP, 0, 0x0, SPAN_RGBA);
+   _swrast_span_default_attribs(ctx, &span);
 
    if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) {
       /* Convolution has to be handled specially.  We'll create an
index 3a15d0c..606afc6 100644 (file)
@@ -42,17 +42,17 @@ feedback_vertex(GLcontext * ctx, const SWvertex * v, const SWvertex * pv)
    GLfloat color[4];
    const GLfloat *vtc = v->attrib[FRAG_ATTRIB_TEX0];
 
-   win[0] = v->win[0];
-   win[1] = v->win[1];
-   win[2] = v->win[2] / ctx->DrawBuffer->_DepthMaxF;
-   win[3] = 1.0F / v->win[3];
+   win[0] = v->attrib[FRAG_ATTRIB_WPOS][0];
+   win[1] = v->attrib[FRAG_ATTRIB_WPOS][1];
+   win[2] = v->attrib[FRAG_ATTRIB_WPOS][2] / ctx->DrawBuffer->_DepthMaxF;
+   win[3] = 1.0F / v->attrib[FRAG_ATTRIB_WPOS][3];
 
    color[0] = CHAN_TO_FLOAT(pv->color[0]);
    color[1] = CHAN_TO_FLOAT(pv->color[1]);
    color[2] = CHAN_TO_FLOAT(pv->color[2]);
    color[3] = CHAN_TO_FLOAT(pv->color[3]);
 
-   _mesa_feedback_vertex(ctx, win, color, (GLfloat) v->index, vtc);
+   _mesa_feedback_vertex(ctx, win, color, v->attrib[FRAG_ATTRIB_CI][0], vtc);
 }
 
 
@@ -120,9 +120,10 @@ _swrast_select_triangle(GLcontext *ctx, const SWvertex *v0,
 {
    if (_swrast_culltriangle(ctx, v0, v1, v2)) {
       const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF;
-      _mesa_update_hitflag(ctx, v0->win[2] * zs);
-      _mesa_update_hitflag(ctx, v1->win[2] * zs);
-      _mesa_update_hitflag(ctx, v2->win[2] * zs);
+
+      _mesa_update_hitflag( ctx, v0->attrib[FRAG_ATTRIB_WPOS][2] * zs );
+      _mesa_update_hitflag( ctx, v1->attrib[FRAG_ATTRIB_WPOS][2] * zs );
+      _mesa_update_hitflag( ctx, v2->attrib[FRAG_ATTRIB_WPOS][2] * zs );
    }
 }
 
@@ -131,8 +132,8 @@ void
 _swrast_select_line(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
 {
    const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF;
-   _mesa_update_hitflag(ctx, v0->win[2] * zs);
-   _mesa_update_hitflag(ctx, v1->win[2] * zs);
+   _mesa_update_hitflag( ctx, v0->attrib[FRAG_ATTRIB_WPOS][2] * zs );
+   _mesa_update_hitflag( ctx, v1->attrib[FRAG_ATTRIB_WPOS][2] * zs );
 }
 
 
@@ -140,5 +141,5 @@ void
 _swrast_select_point(GLcontext *ctx, const SWvertex *v)
 {
    const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF;
-   _mesa_update_hitflag(ctx, v->win[2] * zs);
+   _mesa_update_hitflag( ctx, v->attrib[FRAG_ATTRIB_WPOS][2] * zs );
 }
index 433fc4a..ed47964 100644 (file)
@@ -65,30 +65,92 @@ _swrast_z_to_fogfactor(GLcontext *ctx, GLfloat z)
 }
 
 
+#define LINEAR_FOG(f, coord)  f = (fogEnd - coord) * fogScale
+
+#define EXP_FOG(f, coord)  f = EXPF(density * coord)
+
+#define EXP2_FOG(f, coord)                             \
+do {                                                   \
+   GLfloat tmp = negDensitySquared * coord * coord;    \
+   if (tmp < FLT_MIN_10_EXP)                           \
+      tmp = FLT_MIN_10_EXP;                            \
+   f = EXPF(tmp);                                      \
+ } while(0)
+
+
+#define BLEND_FOG(f, coord)  f = coord
+
+
+
 /**
  * Template code for computing fog blend factor and applying it to colors.
  * \param TYPE  either GLubyte, GLushort or GLfloat.
  * \param COMPUTE_F  code to compute the fog blend factor, f.
  */
-#define FOG_LOOP(TYPE, COMPUTE_F)                                      \
-do {                                                                   \
-   const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];       \
-   GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];            \
-   const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;\
-   GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F;    \
-   GLuint i;                                                           \
-   for (i = 0; i < span->end; i++) {                                   \
-      GLfloat f, oneMinusF;                                            \
-      COMPUTE_F;                                                       \
-      f = CLAMP(f, 0.0F, 1.0F);                                                \
-      oneMinusF = 1.0F - f;                                            \
-      rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog); \
-      rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog); \
-      rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog); \
-      fogCoord += fogStep;                                             \
-      w += wStep;                                                      \
-   }                                                                   \
-} while (0)
+#define FOG_LOOP(TYPE, FOG_FUNC)                                               \
+if (span->arrayAttribs & FRAG_BIT_FOGC) {                                      \
+   GLuint i;                                                                   \
+   for (i = 0; i < span->end; i++) {                                           \
+      const GLfloat fogCoord = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];   \
+      const GLfloat c = FABSF(fogCoord);                                       \
+      GLfloat f, oneMinusF;                                                    \
+      FOG_FUNC(f, c);                                                          \
+      f = CLAMP(f, 0.0F, 1.0F);                                                        \
+      oneMinusF = 1.0F - f;                                                    \
+      rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog);         \
+      rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog);         \
+      rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog);         \
+   }                                                                           \
+}                                                                              \
+else {                                                                         \
+   const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];               \
+   GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];                    \
+   const GLfloat wStep = span->attrStepX[FRAG_ATTRIB_WPOS][3];                 \
+   GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];                           \
+   GLuint i;                                                                   \
+   for (i = 0; i < span->end; i++) {                                           \
+      const GLfloat c = FABSF(fogCoord) / w;                                   \
+      GLfloat f, oneMinusF;                                                    \
+      FOG_FUNC(f, c);                                                          \
+      f = CLAMP(f, 0.0F, 1.0F);                                                        \
+      oneMinusF = 1.0F - f;                                                    \
+      rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog);         \
+      rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog);         \
+      rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog);         \
+      fogCoord += fogStep;                                                     \
+      w += wStep;                                                              \
+   }                                                                           \
+}
+
+/* As above, but CI mode (XXX try to merge someday) */
+#define FOG_LOOP_CI(FOG_FUNC)                                                  \
+if (span->arrayAttribs & FRAG_BIT_FOGC) {                                      \
+   GLuint i;                                                                   \
+   for (i = 0; i < span->end; i++) {                                           \
+      const GLfloat fogCoord = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];   \
+      const GLfloat c = FABSF(fogCoord);                                       \
+      GLfloat f;                                                               \
+      FOG_FUNC(f, c);                                                          \
+      f = CLAMP(f, 0.0F, 1.0F);                                                        \
+      index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);                \
+   }                                                                           \
+}                                                                              \
+else {                                                                         \
+   const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];               \
+   GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];                    \
+   const GLfloat wStep = span->attrStepX[FRAG_ATTRIB_WPOS][3];                 \
+   GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];                           \
+   GLuint i;                                                                   \
+   for (i = 0; i < span->end; i++) {                                           \
+      const GLfloat c = FABSF(fogCoord) / w;                                   \
+      GLfloat f;                                                               \
+      FOG_FUNC(f, c);                                                          \
+      f = CLAMP(f, 0.0F, 1.0F);                                                        \
+      index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);                \
+      fogCoord += fogStep;                                                     \
+      w += wStep;                                                              \
+   }                                                                           \
+}
 
 
 
@@ -104,12 +166,12 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
 {
    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
    GLfloat rFog, gFog, bFog;
-   const GLuint haveW = (span->interpMask & SPAN_W);
 
    ASSERT(swrast->_FogEnabled);
-   ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG);
+   ASSERT(swrast->_ActiveAttribMask & FRAG_BIT_FOGC);
    ASSERT(span->arrayMask & SPAN_RGBA);
 
+   /* compute (scaled) fog color */
    if (span->array->ChanType == GL_UNSIGNED_BYTE) {
       rFog = ctx->Fog.Color[RCOMP] * 255.0;
       gFog = ctx->Fog.Color[GCOMP] * 255.0;
@@ -126,79 +188,68 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
       bFog = ctx->Fog.Color[BCOMP];
    }
 
-
-   /* NOTE: if haveW is true, that means the fog start/step values are
-    * perspective-corrected and we have to divide each fog coord by W.
-    */
-
-   /* we need to compute fog blend factors */
    if (swrast->_PreferPixelFog) {
       /* The span's fog values are fog coordinates, now compute blend factors
        * and blend the fragment colors with the fog color.
        */
-      const GLfloat fogEnd = ctx->Fog.End;
-      const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End)
-         ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start);
-      const GLfloat density = -ctx->Fog.Density;
-      const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
-
       switch (swrast->_FogMode) {
       case GL_LINEAR:
-#define COMPUTE_F  f = (fogEnd - FABSF(fogCoord) / w) * fogScale;
-         if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-            GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
-            FOG_LOOP(GLubyte, COMPUTE_F);
-         }
-         else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-            GLushort (*rgba)[4] = span->array->color.sz2.rgba;
-            FOG_LOOP(GLushort, COMPUTE_F);
-         }
-         else {
-            GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
-            ASSERT(span->array->ChanType == GL_FLOAT);
-            FOG_LOOP(GLfloat, COMPUTE_F);
+         {
+            const GLfloat fogEnd = ctx->Fog.End;
+            const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End)
+               ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start);
+            if (span->array->ChanType == GL_UNSIGNED_BYTE) {
+               GLubyte (*rgba)[4] = span->array->rgba8;
+               FOG_LOOP(GLubyte, LINEAR_FOG);
+            }
+            else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
+               GLushort (*rgba)[4] = span->array->rgba16;
+               FOG_LOOP(GLushort, LINEAR_FOG);
+            }
+            else {
+               GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
+               ASSERT(span->array->ChanType == GL_FLOAT);
+               FOG_LOOP(GLfloat, LINEAR_FOG);
+            }
          }
-#undef COMPUTE_F
          break;
 
       case GL_EXP:
-#define COMPUTE_F  f = EXPF(density * FABSF(fogCoord) / w);
-         if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-            GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
-            FOG_LOOP(GLubyte, COMPUTE_F);
-         }
-         else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-            GLushort (*rgba)[4] = span->array->color.sz2.rgba;
-            FOG_LOOP(GLushort, COMPUTE_F);
-         }
-         else {
-            GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
-            ASSERT(span->array->ChanType == GL_FLOAT);
-            FOG_LOOP(GLfloat, COMPUTE_F);
+         {
+            const GLfloat density = -ctx->Fog.Density;
+            if (span->array->ChanType == GL_UNSIGNED_BYTE) {
+               GLubyte (*rgba)[4] = span->array->rgba8;
+               FOG_LOOP(GLubyte, EXP_FOG);
+            }
+            else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
+               GLushort (*rgba)[4] = span->array->rgba16;
+               FOG_LOOP(GLushort, EXP_FOG);
+            }
+            else {
+               GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
+               ASSERT(span->array->ChanType == GL_FLOAT);
+               FOG_LOOP(GLfloat, EXP_FOG);
+            }
          }
-#undef COMPUTE_F
          break;
 
       case GL_EXP2:
-#define COMPUTE_F  const GLfloat coord = fogCoord / w; \
-                   GLfloat tmp = negDensitySquared * coord * coord; \
-                   if (tmp < FLT_MIN_10_EXP) \
-                      tmp = FLT_MIN_10_EXP; \
-                   f = EXPF(tmp);
-         if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-            GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
-            FOG_LOOP(GLubyte, COMPUTE_F);
-         }
-         else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-            GLushort (*rgba)[4] = span->array->color.sz2.rgba;
-            FOG_LOOP(GLushort, COMPUTE_F);
-         }
-         else {
-            GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
-            ASSERT(span->array->ChanType == GL_FLOAT);
-            FOG_LOOP(GLfloat, COMPUTE_F);
+         {
+            const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
+            if (span->array->ChanType == GL_UNSIGNED_BYTE) {
+               GLubyte (*rgba)[4] = span->array->rgba8;
+               FOG_LOOP(GLubyte, EXP2_FOG);
+            }
+            else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
+               GLushort (*rgba)[4] = span->array->rgba16;
+               FOG_LOOP(GLushort, EXP2_FOG);
+            }
+            else {
+               GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
+               ASSERT(span->array->ChanType == GL_FLOAT);
+               FOG_LOOP(GLfloat, EXP2_FOG);
+            }
          }
-#undef COMPUTE_F
          break;
 
       default:
@@ -206,63 +257,23 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
          return;
       }
    }
-   else if (span->arrayMask & SPAN_FOG) {
-      /* The span's fog array values are blend factors.
-       * They were previously computed per-vertex.
-       */
-      GLuint i;
-      if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-         GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
-         for (i = 0; i < span->end; i++) {
-            const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];
-            const GLfloat oneMinusF = 1.0F - f;
-            rgba[i][RCOMP] = (GLubyte) (f * rgba[i][RCOMP] + oneMinusF * rFog);
-            rgba[i][GCOMP] = (GLubyte) (f * rgba[i][GCOMP] + oneMinusF * gFog);
-            rgba[i][BCOMP] = (GLubyte) (f * rgba[i][BCOMP] + oneMinusF * bFog);
-         }
-      }
-      else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-         GLushort (*rgba)[4] = span->array->color.sz2.rgba;
-         for (i = 0; i < span->end; i++) {
-            const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];
-            const GLfloat oneMinusF = 1.0F - f;
-            rgba[i][RCOMP] = (GLushort) (f * rgba[i][RCOMP] + oneMinusF * rFog);
-            rgba[i][GCOMP] = (GLushort) (f * rgba[i][GCOMP] + oneMinusF * gFog);
-            rgba[i][BCOMP] = (GLushort) (f * rgba[i][BCOMP] + oneMinusF * bFog);
-         }
-      }
-      else {
-         GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
-         ASSERT(span->array->ChanType == GL_FLOAT);
-         for (i = 0; i < span->end; i++) {
-            const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];
-            const GLfloat oneMinusF = 1.0F - f;
-            rgba[i][RCOMP] = f * rgba[i][RCOMP] + oneMinusF * rFog;
-            rgba[i][GCOMP] = f * rgba[i][GCOMP] + oneMinusF * gFog;
-            rgba[i][BCOMP] = f * rgba[i][BCOMP] + oneMinusF * bFog;
-         }
-      }
-
-   }
    else {
-      /* The span's fog start/step values are blend factors.
+      /* The span's fog start/step/array values are blend factors in [0,1].
        * They were previously computed per-vertex.
        */
-#define COMPUTE_F f = fogCoord / w;
       if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-         GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
-         FOG_LOOP(GLubyte, COMPUTE_F);
+         GLubyte (*rgba)[4] = span->array->rgba8;
+         FOG_LOOP(GLubyte, BLEND_FOG);
       }
       else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-         GLushort (*rgba)[4] = span->array->color.sz2.rgba;
-         FOG_LOOP(GLushort, COMPUTE_F);
+         GLushort (*rgba)[4] = span->array->rgba16;
+         FOG_LOOP(GLushort, BLEND_FOG);
       }
       else {
          GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
          ASSERT(span->array->ChanType == GL_FLOAT);
-         FOG_LOOP(GLfloat, COMPUTE_F);
+         FOG_LOOP(GLfloat, BLEND_FOG);
       }
-#undef COMPUTE_F
    }
 }
 
@@ -274,13 +285,11 @@ void
 _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span )
 {
    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   const GLuint haveW = (span->interpMask & SPAN_W);
    const GLuint fogIndex = (GLuint) ctx->Fog.Index;
    GLuint *index = span->array->index;
 
    ASSERT(swrast->_FogEnabled);
    ASSERT(span->arrayMask & SPAN_INDEX);
-   ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG);
 
    /* we need to compute fog blend factors */
    if (swrast->_PreferPixelFog) {
@@ -293,60 +302,19 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span )
             const GLfloat fogEnd = ctx->Fog.End;
             const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End)
                ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start);
-            const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];
-            GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];
-            const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;
-            GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F;
-            GLuint i;
-            for (i = 0; i < span->end; i++) {
-               GLfloat f = (fogEnd - fogCoord / w) * fogScale;
-               f = CLAMP(f, 0.0F, 1.0F);
-               index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);
-               fogCoord += fogStep;
-               w += wStep;
-            }
+            FOG_LOOP_CI(LINEAR_FOG);
          }
          break;
       case GL_EXP:
          {
             const GLfloat density = -ctx->Fog.Density;
-            const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];
-            GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];
-            const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;
-            GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F;
-            GLuint i;
-            for (i = 0; i < span->end; i++) {
-               GLfloat f = EXPF(density * fogCoord / w);
-               f = CLAMP(f, 0.0F, 1.0F);
-               index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);
-               fogCoord += fogStep;
-               w += wStep;
-            }
+            FOG_LOOP_CI(EXP_FOG);
          }
          break;
       case GL_EXP2:
          {
             const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
-            const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];
-            GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];
-            const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;
-            GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F;
-            GLuint i;
-            for (i = 0; i < span->end; i++) {
-               const GLfloat coord = fogCoord / w;
-               GLfloat tmp = negDensitySquared * coord * coord;
-               GLfloat f;
-#if defined(__alpha__) || defined(__alpha)
-               /* XXX this underflow check may be needed for other systems*/
-               if (tmp < FLT_MIN_10_EXP)
-                  tmp = FLT_MIN_10_EXP;
-#endif
-               f = EXPF(tmp);
-               f = CLAMP(f, 0.0F, 1.0F);
-               index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);
-               fogCoord += fogStep;
-               w += wStep;
-            }
+            FOG_LOOP_CI(EXP2_FOG);
          }
          break;
       default:
@@ -354,31 +322,10 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span )
          return;
       }
    }
-   else if (span->arrayMask & SPAN_FOG) {
-      /* The span's fog array values are blend factors.
-       * They were previously computed per-vertex.
-       */
-      GLuint i;
-      for (i = 0; i < span->end; i++) {
-         const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];
-         index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);
-      }
-   }
    else {
-      /* The span's fog start/step values are blend factors.
+      /* The span's fog start/step/array values are blend factors in [0,1].
        * They were previously computed per-vertex.
        */
-      const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];
-      GLfloat fog = span->attrStart[FRAG_ATTRIB_FOGC][0];
-      const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;
-      GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F;
-      GLuint i;
-      ASSERT(span->interpMask & SPAN_FOG);
-      for (i = 0; i < span->end; i++) {
-         const GLfloat f = fog / w;
-         index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex);
-         fog += fogStep;
-         w += wStep;
-      }
+      FOG_LOOP_CI(BLEND_FOG);
    }
 }
index 80702e4..781146e 100644 (file)
@@ -121,29 +121,29 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor )
 /**********************************************************************/
 
 /* Simple color index line (no stipple, width=1, no Z, no fog, no tex)*/
-#define NAME simple_ci_line
+#define NAME simple_no_z_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 NAME ci_line
 #define INTERP_INDEX
 #define INTERP_Z
-#define INTERP_FOG
+#define INTERP_ATTRIBS /* for 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 {                                                      \
@@ -153,16 +153,15 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor )
 
 
 /* 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,19 +170,17 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor )
 #include "s_linetemp.h"
 
 
-/* General-purpose textured line (any/all features). */
-#define NAME textured_line
+/* General-purpose line (any/all features). */
+#define NAME general_line
 #define INTERP_RGBA
-#define INTERP_SPEC
 #define INTERP_Z
-#define INTERP_FOG
 #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) {                                       \
+   if (ctx->Line._Width > 1.0) {                               \
       draw_wide_line(ctx, &span, (GLboolean)(dx > dy));                \
    }                                                           \
    else {                                                      \
@@ -194,48 +191,39 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor )
 
 
 void
-_swrast_add_spec_terms_line( GLcontext *ctx,
-                             const SWvertex *v0,
-                             const SWvertex *v1 )
+_swrast_add_spec_terms_line(GLcontext *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
-      _mesa_printf("Driver func %p\n", (void *(*)()) swrast->Line);
-}
-#endif
-
-
 
 #ifdef DEBUG
 
@@ -257,7 +245,7 @@ do {                                    \
 
 
 
-/*
+/**
  * Determine which line drawing function to use given the current
  * rendering context.
  *
@@ -269,6 +257,9 @@ _swrast_choose_line( GLcontext *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) {
@@ -277,24 +268,27 @@ _swrast_choose_line( GLcontext *ctx )
          ASSERT(swrast->Line);
       }
       else if (ctx->Texture._EnabledCoordUnits
-             || ctx->FragmentProgram._Current) {
-         /* textured lines */
-         USE(textured_line);
+               || ctx->FragmentProgram._Current
+               || 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);
+            USE(rgba_line);
          else
-            USE(general_ci_line);
+            USE(ci_line);
       }
       else {
-         /* simplest lines */
+         ASSERT(!ctx->Depth.Test);
+         /* simple lines */
          if (rgbmode)
-            USE(simple_rgba_line);
+            USE(simple_no_z_rgba_line);
          else
-            USE(simple_ci_line);
+            USE(simple_no_z_ci_line);
       }
    }
    else if (ctx->RenderMode == GL_FEEDBACK) {
@@ -304,6 +298,4 @@ _swrast_choose_line( GLcontext *ctx )
       ASSERT(ctx->RenderMode == GL_SELECT);
       USE(_swrast_select_line);
    }
-
-   /*_mesa_print_line_function(ctx);*/
 }
index b6e8f28..55548f2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.3
+ * Version:  7.0
  *
  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  *
@@ -31,9 +31,7 @@
  * The following macros may be defined to indicate what auxillary information
  * must be interplated along the line:
  *    INTERP_Z        - if defined, interpolate Z values
- *    INTERP_FOG      - if defined, interpolate FOG values
  *    INTERP_RGBA     - if defined, interpolate RGBA values
- *    INTERP_SPEC     - if defined, interpolate specular RGB values
  *    INTERP_INDEX    - if defined, interpolate color index values
  *    INTERP_ATTRIBS  - if defined, interpolate attribs (texcoords, varying, etc)
  *
@@ -72,10 +70,10 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
    SWspan span;
    GLuint interpFlags = 0;
-   GLint x0 = (GLint) vert0->win[0];
-   GLint x1 = (GLint) vert1->win[0];
-   GLint y0 = (GLint) vert0->win[1];
-   GLint y1 = (GLint) vert1->win[1];
+   GLint x0 = (GLint) vert0->attrib[FRAG_ATTRIB_WPOS][0];
+   GLint x1 = (GLint) vert1->attrib[FRAG_ATTRIB_WPOS][0];
+   GLint y0 = (GLint) vert0->attrib[FRAG_ATTRIB_WPOS][1];
+   GLint y1 = (GLint) vert1->attrib[FRAG_ATTRIB_WPOS][1];
    GLint dx, dy;
    GLint numPixels;
    GLint xstep, ystep;
@@ -104,8 +102,8 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
    /* Cull primitives with malformed coordinates.
     */
    {
-      GLfloat tmp = vert0->win[0] + vert0->win[1]
-                  + vert1->win[0] + vert1->win[1];
+      GLfloat tmp = vert0->attrib[FRAG_ATTRIB_WPOS][0] + vert0->attrib[FRAG_ATTRIB_WPOS][1]
+                  + vert1->attrib[FRAG_ATTRIB_WPOS][0] + vert1->attrib[FRAG_ATTRIB_WPOS][1];
       if (IS_INF_OR_NAN(tmp))
         return;
    }
@@ -113,8 +111,12 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
    /*
    printf("%s():\n", __FUNCTION__);
    printf(" (%f, %f, %f) -> (%f, %f, %f)\n",
-          vert0->win[0], vert0->win[1], vert0->win[2],
-          vert1->win[0], vert1->win[1], vert1->win[2]);
+          vert0->attrib[FRAG_ATTRIB_WPOS][0],
+          vert0->attrib[FRAG_ATTRIB_WPOS][1],
+          vert0->attrib[FRAG_ATTRIB_WPOS][2],
+          vert1->attrib[FRAG_ATTRIB_WPOS][0],
+          vert1->attrib[FRAG_ATTRIB_WPOS][1],
+          vert1->attrib[FRAG_ATTRIB_WPOS][2]);
    printf(" (%d, %d, %d) -> (%d, %d, %d)\n",
           vert0->color[0], vert0->color[1], vert0->color[2], 
           vert1->color[0], vert1->color[1], vert1->color[2]);
@@ -154,6 +156,18 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
    if (dx == 0 && dy == 0)
       return;
 
+   /*
+   printf("%s %d,%d  %g %g %g %g  %g %g %g %g\n", __FUNCTION__, dx, dy,
+          vert0->attrib[FRAG_ATTRIB_COL1][0],
+          vert0->attrib[FRAG_ATTRIB_COL1][1],
+          vert0->attrib[FRAG_ATTRIB_COL1][2],
+          vert0->attrib[FRAG_ATTRIB_COL1][3],
+          vert1->attrib[FRAG_ATTRIB_COL1][0],
+          vert1->attrib[FRAG_ATTRIB_COL1][1],
+          vert1->attrib[FRAG_ATTRIB_COL1][2],
+          vert1->attrib[FRAG_ATTRIB_COL1][3]);
+   */
+
 #ifdef DEPTH_TYPE
    zPtr = (DEPTH_TYPE *) zrb->GetPointer(ctx, zrb, x0, y0);
 #endif
@@ -232,33 +246,15 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
       span.alphaStep = 0;
    }
 #endif
-#ifdef INTERP_SPEC
-   interpFlags |= SPAN_SPEC;
-   if (ctx->Light.ShadeModel == GL_SMOOTH) {
-      span.specRed       = ChanToFixed(vert0->specular[0]);
-      span.specGreen     = ChanToFixed(vert0->specular[1]);
-      span.specBlue      = ChanToFixed(vert0->specular[2]);
-      span.specRedStep   = (ChanToFixed(vert1->specular[0]) - span.specRed) / numPixels;
-      span.specGreenStep = (ChanToFixed(vert1->specular[1]) - span.specBlue) / numPixels;
-      span.specBlueStep  = (ChanToFixed(vert1->specular[2]) - span.specGreen) / numPixels;
-   }
-   else {
-      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;
-   }
-#endif
 #ifdef INTERP_INDEX
    interpFlags |= SPAN_INDEX;
    if (ctx->Light.ShadeModel == GL_SMOOTH) {
-      span.index = FloatToFixed(vert0->index);
-      span.indexStep = FloatToFixed(vert1->index - vert0->index) / numPixels;
+      span.index = FloatToFixed(vert0->attrib[FRAG_ATTRIB_CI][0]);
+      span.indexStep = FloatToFixed(  vert1->attrib[FRAG_ATTRIB_CI][0]
+                                    - vert0->attrib[FRAG_ATTRIB_CI][0]) / numPixels;
    }
    else {
-      span.index = FloatToFixed(vert1->index);
+      span.index = FloatToFixed(vert1->attrib[FRAG_ATTRIB_CI][0]);
       span.indexStep = 0;
    }
 #endif
@@ -266,57 +262,49 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
    interpFlags |= SPAN_Z;
    {
       if (depthBits <= 16) {
-         span.z = FloatToFixed(vert0->win[2]) + FIXED_HALF;
-         span.zStep = FloatToFixed(vert1->win[2] - vert0->win[2]) / numPixels;
+         span.z = FloatToFixed(vert0->attrib[FRAG_ATTRIB_WPOS][2]) + FIXED_HALF;
+         span.zStep = FloatToFixed(  vert1->attrib[FRAG_ATTRIB_WPOS][2]
+                                   - vert0->attrib[FRAG_ATTRIB_WPOS][2]) / numPixels;
       }
       else {
          /* don't use fixed point */
-         span.z = (GLuint) vert0->win[2];
-         span.zStep = (GLint) ((vert1->win[2] - vert0->win[2]) / numPixels);
+         span.z = (GLuint) vert0->attrib[FRAG_ATTRIB_WPOS][2];
+         span.zStep = (GLint) ((  vert1->attrib[FRAG_ATTRIB_WPOS][2]
+                                - vert0->attrib[FRAG_ATTRIB_WPOS][2]) / numPixels);
       }
    }
 #endif
-#ifdef INTERP_FOG
-   interpFlags |= SPAN_FOG;
-   span.attrStart[FRAG_ATTRIB_FOGC][0] = vert0->attrib[FRAG_ATTRIB_FOGC][0];
-   span.attrStepX[FRAG_ATTRIB_FOGC][0] = (vert1->attrib[FRAG_ATTRIB_FOGC][0]
-                                          - vert0->attrib[FRAG_ATTRIB_FOGC][0]) / numPixels;
-#endif
 #if defined(INTERP_ATTRIBS)
-   interpFlags |= (SPAN_TEXTURE | SPAN_VARYING);
    {
       const GLfloat invLen = 1.0F / numPixels;
-      const GLfloat invw0 = vert0->win[3];
-      const GLfloat invw1 = vert1->win[3];
+      const GLfloat invw0 = vert0->attrib[FRAG_ATTRIB_WPOS][3];
+      const GLfloat invw1 = vert1->attrib[FRAG_ATTRIB_WPOS][3];
+
+      span.attrStart[FRAG_ATTRIB_WPOS][3] = invw0;
+      span.attrStepX[FRAG_ATTRIB_WPOS][3] = (invw1 - invw0) * invLen;
+      span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0;
+
       ATTRIB_LOOP_BEGIN
-         GLfloat ds, dt, dr, dq;
-         span.attrStart[attr][0] = invw0 * vert0->attrib[attr][0];
-         span.attrStart[attr][1] = invw0 * vert0->attrib[attr][1];
-         span.attrStart[attr][2] = invw0 * vert0->attrib[attr][2];
-         span.attrStart[attr][3] = invw0 * vert0->attrib[attr][3];
-         ds = (invw1 * vert1->attrib[attr][0]) - span.attrStart[attr][0];
-         dt = (invw1 * vert1->attrib[attr][1]) - span.attrStart[attr][1];
-         dr = (invw1 * vert1->attrib[attr][2]) - span.attrStart[attr][2];
-         dq = (invw1 * vert1->attrib[attr][3]) - span.attrStart[attr][3];
-         span.attrStepX[attr][0] = ds * invLen;
-         span.attrStepX[attr][1] = dt * invLen;
-         span.attrStepX[attr][2] = dr * invLen;
-         span.attrStepX[attr][3] = dq * invLen;
-         span.attrStepY[attr][0] = 0.0F;
-         span.attrStepY[attr][1] = 0.0F;
-         span.attrStepY[attr][2] = 0.0F;
-         span.attrStepY[attr][3] = 0.0F;
+         if (swrast->_InterpMode[attr] == GL_FLAT) {
+            COPY_4V(span.attrStart[attr], vert1->attrib[attr]);
+            ASSIGN_4V(span.attrStepX[attr], 0.0, 0.0, 0.0, 0.0);
+         }
+         else {
+            GLuint c;
+            for (c = 0; c < 4; c++) {
+               float da;
+               span.attrStart[attr][c] = invw0 * vert0->attrib[attr][c];
+               da = (invw1 * vert1->attrib[attr][c]) - span.attrStart[attr][c];
+               span.attrStepX[attr][c] = da * invLen;
+            }
+         }
+         ASSIGN_4V(span.attrStepY[attr], 0.0, 0.0, 0.0, 0.0);
       ATTRIB_LOOP_END
    }
 #endif
 
    INIT_SPAN(span, GL_LINE, numPixels, interpFlags, SPAN_XY);
 
-   /* Need these for fragment prog texcoord interpolation */
-   span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F;
-   span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F;
-   span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F;
-
    /*
     * Draw
     */
@@ -346,7 +334,7 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
 #ifdef PIXEL_ADDRESS
          pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep);
 #endif
-         if (error<0) {
+         if (error < 0) {
             error += errorInc;
          }
          else {
@@ -413,9 +401,7 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
 
 #undef NAME
 #undef INTERP_Z
-#undef INTERP_FOG
 #undef INTERP_RGBA
-#undef INTERP_SPEC
 #undef INTERP_ATTRIBS
 #undef INTERP_INDEX
 #undef PIXEL_ADDRESS
index e680732..0af9063 100644 (file)
@@ -229,13 +229,13 @@ _swrast_logicop_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb,
    if (span->array->ChanType == GL_UNSIGNED_BYTE) {
       /* treat 4*GLubyte as GLuint */
       logicop_uint1(ctx, span->end,
-                    (GLuint *) span->array->color.sz1.rgba,
+                    (GLuint *) span->array->rgba8,
                     (const GLuint *) rbPixels, span->array->mask);
    }
    else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
       /* treat 2*GLushort as GLuint */
       logicop_uint2(ctx, 2 * span->end,
-                    (GLuint *) span->array->color.sz2.rgba,
+                    (GLuint *) span->array->rgba16,
                     (const GLuint *) rbPixels, span->array->mask);
    }
    else {
index 8800f7d..a69720e 100644 (file)
@@ -61,7 +61,7 @@ _swrast_mask_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb,
       const GLuint srcMask = *((GLuint *) ctx->Color.ColorMask);
       const GLuint dstMask = ~srcMask;
       const GLuint *dst = (const GLuint *) rbPixels;
-      GLuint *src = (GLuint *) span->array->color.sz1.rgba;
+      GLuint *src = (GLuint *) span->array->rgba8;
       GLuint i;
       for (i = 0; i < n; i++) {
          src[i] = (src[i] & srcMask) | (dst[i] & dstMask);
@@ -75,7 +75,7 @@ _swrast_mask_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb,
       const GLushort bMask = ctx->Color.ColorMask[BCOMP] ? 0xffff : 0x0;
       const GLushort aMask = ctx->Color.ColorMask[ACOMP] ? 0xffff : 0x0;
       const GLushort (*dst)[4] = (const GLushort (*)[4]) rbPixels;
-      GLushort (*src)[4] = span->array->color.sz2.rgba;
+      GLushort (*src)[4] = span->array->rgba16;
       GLuint i;
       for (i = 0; i < n; i++) {
          src[i][RCOMP] = (src[i][RCOMP] & rMask) | (dst[i][RCOMP] & ~rMask);
index 1401b77..02c9d9b 100644 (file)
@@ -34,7 +34,6 @@
 #include "s_span.h"
 
 
-
 #define RGBA       0x1
 #define INDEX      0x2
 #define SMOOTH     0x4
 #include "s_pointtemp.h"
 
 
-
-void _swrast_add_spec_terms_point( GLcontext *ctx,
-                                  const SWvertex *v0 )
+void
+_swrast_add_spec_terms_point(GLcontext *ctx, const SWvertex *v0)
 {
-   SWvertex *ncv0 = (SWvertex *)v0;
-   GLchan c[1][4];
-   COPY_CHAN4( c[0], ncv0->color );
-   ACC_3V( ncv0->color, ncv0->specular );
-   SWRAST_CONTEXT(ctx)->SpecPoint( ctx, ncv0 );
-   COPY_CHAN4( ncv0->color, c[0] );
+   SWvertex *ncv0 = (SWvertex *) v0;
+   GLfloat rSum, gSum, bSum;
+   GLchan cSave[4];
+
+   /* save */
+   COPY_CHAN4( cSave, ncv0->color );
+   /* sum */
+   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);
+   /* draw */
+   SWRAST_CONTEXT(ctx)->SpecPoint(ctx, ncv0);
+   /* restore */
+   COPY_CHAN4(ncv0->color, cSave);
 }
 
 
@@ -196,6 +205,9 @@ _swrast_choose_point( GLcontext *ctx )
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    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->Point.PointSprite) {
@@ -242,8 +254,10 @@ _swrast_choose_point( GLcontext *ctx )
             USE(atten_general_ci_point);
          }
       }
-      else if (ctx->Texture._EnabledCoordUnits && rgbMode) {
-         /* textured */
+      else if ((ctx->Texture._EnabledCoordUnits
+                || specular
+                || swrast->_FogEnabled) && rgbMode) {
+         /* textured, fogged */
          USE(textured_rgba_point);
       }
       else if (ctx->Point._Size != 1.0) {
@@ -258,6 +272,7 @@ _swrast_choose_point( GLcontext *ctx )
       else {
          /* single pixel points */
          if (rgbMode) {
+            assert((swrast->_ActiveAttribMask & FRAG_BIT_COL1) == 0);
             USE(size1_rgba_point);
          }
          else {
index dddc2f7..206085b 100644 (file)
@@ -40,7 +40,6 @@
  *   RGBA = do rgba instead of color index
  *   SMOOTH = do antialiasing
  *   ATTRIBS = general attributes (texcoords, etc)
- *   SPECULAR = do separate specular color
  *   LARGE = do points with diameter > 1 pixel
  *   ATTENUATE = compute point size attenuation
  *   SPRITE = GL_ARB_point_sprite / GL_NV_point_sprite
@@ -78,13 +77,8 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
    const GLchan blue  = vert->color[2];
    const GLchan alpha = vert->color[3];
 #endif
-#if FLAGS & SPECULAR
-   const GLchan specRed   = vert->specular[0];
-   const GLchan specGreen = vert->specular[1];
-   const GLchan specBlue  = vert->specular[2];
-#endif
 #if FLAGS & INDEX
-   const GLuint colorIndex = (GLuint) vert->index; /* XXX round? */
+   const GLuint colorIndex = (GLuint) vert->attrib[FRAG_ATTRIB_CI][0]; /* XXX round? */
 #endif
 #if FLAGS & ATTRIBS
    GLfloat attrib[FRAG_ATTRIB_MAX][4]; /* texture & varying */
@@ -92,10 +86,22 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    SWspan *span = &(swrast->PointSpan);
 
+   /*
+   printf("%s  %g %g %g %g\n", __FUNCTION__,
+          vert->attrib[FRAG_ATTRIB_COL1][0],
+          vert->attrib[FRAG_ATTRIB_COL1][1],
+          vert->attrib[FRAG_ATTRIB_COL1][2],
+          vert->attrib[FRAG_ATTRIB_COL1][3]);
+   if ( vert->attrib[FRAG_ATTRIB_COL1][0] == 0.0 &&
+        vert->attrib[FRAG_ATTRIB_COL1][1] == 1.0 &&
+        vert->attrib[FRAG_ATTRIB_COL1][2] == 0.0)
+      foo();
+   */
+
    /* Cull primitives with malformed coordinates.
     */
    {
-      float tmp = vert->win[0] + vert->win[1];
+      float tmp = vert->attrib[FRAG_ATTRIB_WPOS][0] + vert->attrib[FRAG_ATTRIB_WPOS][1];
       if (IS_INF_OR_NAN(tmp))
         return;
    }
@@ -103,49 +109,37 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
    /*
     * Span init
     */
-   span->interpMask = SPAN_FOG;
+   span->interpMask = 0;
    span->arrayMask = SPAN_XY | SPAN_Z;
-   span->attrStart[FRAG_ATTRIB_FOGC][0] = vert->attrib[FRAG_ATTRIB_FOGC][0];
-   span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0;
-   span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0;
 #if FLAGS & RGBA
    span->arrayMask |= SPAN_RGBA;
 #endif
-#if FLAGS & SPECULAR
-   span->arrayMask |= SPAN_SPEC;
-#endif
 #if FLAGS & INDEX
    span->arrayMask |= SPAN_INDEX;
 #endif
 #if FLAGS & ATTRIBS
-   span->arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
-   if (ctx->FragmentProgram._Active) {
-      /* Don't divide texture s,t,r by q (use TXP to do that) */
-      ATTRIB_LOOP_BEGIN
-         COPY_4V(attrib[attr], vert->attrib[attr]);
-      ATTRIB_LOOP_END
-   }
-   else {
-      /* Divide texture s,t,r by q here */
-      ATTRIB_LOOP_BEGIN
-         const GLfloat q = vert->attrib[attr][3];
-         const GLfloat invQ = (q == 0.0F || q == 1.0F) ? 1.0F : (1.0F / q);
-         attrib[attr][0] = vert->attrib[attr][0] * invQ;
-         attrib[attr][1] = vert->attrib[attr][1] * invQ;
-         attrib[attr][2] = vert->attrib[attr][2] * invQ;
-         attrib[attr][3] = q;
-      ATTRIB_LOOP_END
-   }
+   span->arrayMask |= SPAN_LAMBDA;
+
+   /* we're filling in the attrib arrays: */
+   span->arrayAttribs = swrast->_ActiveAttribMask;
+
+   ATTRIB_LOOP_BEGIN
+      COPY_4V(attrib[attr], vert->attrib[attr]);
+   ATTRIB_LOOP_END
+
    /* need these for fragment programs */
    span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F;
    span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F;
    span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F;
+#else
+   assert((swrast->_ActiveAttribMask & FRAG_BIT_COL1) == 0);
 #endif
+
 #if FLAGS & SMOOTH
    span->arrayMask |= SPAN_COVERAGE;
 #endif
 #if FLAGS & SPRITE
-   span->arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
+   span->arrayMask |= SPAN_LAMBDA;
 #endif
 
    /* Compute point size if not known to be one */
@@ -189,7 +183,7 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
    {{
       GLint x, y;
       const GLfloat radius = 0.5F * size;
-      const GLuint z = (GLuint) (vert->win[2] + 0.5F);
+      const GLuint z = (GLuint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F);
       GLuint count;
 #if FLAGS & SMOOTH
       const GLfloat rmin = radius - 0.7071F;  /* 0.7071 = sqrt(2)/2 */
@@ -197,10 +191,10 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
       const GLfloat rmin2 = MAX2(0.0F, rmin * rmin);
       const GLfloat rmax2 = rmax * rmax;
       const GLfloat cscale = 1.0F / (rmax2 - rmin2);
-      const GLint xmin = (GLint) (vert->win[0] - radius);
-      const GLint xmax = (GLint) (vert->win[0] + radius);
-      const GLint ymin = (GLint) (vert->win[1] - radius);
-      const GLint ymax = (GLint) (vert->win[1] + radius);
+      const GLint xmin = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][0] - radius);
+      const GLint xmax = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][0] + radius);
+      const GLint ymin = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][1] - radius);
+      const GLint ymax = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][1] + radius);
 #else
       /* non-smooth */
       GLint xmin, xmax, ymin, ymax;
@@ -210,16 +204,16 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
       iRadius = iSize / 2;
       if (iSize & 1) {
          /* odd size */
-         xmin = (GLint) (vert->win[0] - iRadius);
-         xmax = (GLint) (vert->win[0] + iRadius);
-         ymin = (GLint) (vert->win[1] - iRadius);
-         ymax = (GLint) (vert->win[1] + iRadius);
+         xmin = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][0] - iRadius);
+         xmax = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][0] + iRadius);
+         ymin = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][1] - iRadius);
+         ymax = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][1] + iRadius);
       }
       else {
          /* even size */
-         xmin = (GLint) vert->win[0] - iRadius + 1;
+         xmin = (GLint) vert->attrib[FRAG_ATTRIB_WPOS][0] - iRadius + 1;
          xmax = xmin + iSize - 1;
-         ymin = (GLint) vert->win[1] - iRadius + 1;
+         ymin = (GLint) vert->attrib[FRAG_ATTRIB_WPOS][1] - iRadius + 1;
          ymax = ymin + iSize - 1;
       }
 #endif /*SMOOTH*/
@@ -264,29 +258,26 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
             span->array->rgba[count][BCOMP] = blue;
             span->array->rgba[count][ACOMP] = alpha;
 #endif
-#if FLAGS & SPECULAR
-            span->array->spec[count][RCOMP] = specRed;
-            span->array->spec[count][GCOMP] = specGreen;
-            span->array->spec[count][BCOMP] = specBlue;
-#endif
 #if FLAGS & INDEX
             span->array->index[count] = colorIndex;
 #endif
 #if FLAGS & ATTRIBS
             ATTRIB_LOOP_BEGIN
                COPY_4V(span->array->attribs[attr][count], attrib[attr]);
-               if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) {
+            /**
+               if (attr < FRAG_ATTRIB_VAR0) {
                   const GLuint u = attr - FRAG_ATTRIB_TEX0;
                   span->array->lambda[u][count] = 0.0;
                }
+            **/
             ATTRIB_LOOP_END
 #endif
 
 #if FLAGS & SMOOTH
             /* compute coverage */
             {
-               const GLfloat dx = x - vert->win[0] + 0.5F;
-               const GLfloat dy = y - vert->win[1] + 0.5F;
+               const GLfloat dx = x - vert->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F;
+               const GLfloat dy = y - vert->attrib[FRAG_ATTRIB_WPOS][1] + 0.5F;
                const GLfloat dist2 = dx * dx + dy * dy;
                if (dist2 < rmax2) {
                   if (dist2 >= rmin2) {
@@ -327,12 +318,12 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
                GLuint attr = FRAG_ATTRIB_TEX0 + u;
                if (ctx->Texture.Unit[u]._ReallyEnabled) {
                   if (ctx->Point.CoordReplace[u]) {
-                     GLfloat s = 0.5F + (x + 0.5F - vert->win[0]) / size;
+                     GLfloat s = 0.5F + (x + 0.5F - vert->attrib[FRAG_ATTRIB_WPOS][0]) / size;
                      GLfloat t, r;
                      if (ctx->Point.SpriteOrigin == GL_LOWER_LEFT)
-                        t = 0.5F + (y + 0.5F - vert->win[1]) / size;
+                        t = 0.5F + (y + 0.5F - vert->attrib[FRAG_ATTRIB_WPOS][1]) / size;
                      else /* GL_UPPER_LEFT */
-                        t = 0.5F - (y + 0.5F - vert->win[1]) / size;
+                        t = 0.5F - (y + 0.5F - vert->attrib[FRAG_ATTRIB_WPOS][1]) / size;
                      if (ctx->Point.SpriteRMode == GL_ZERO)
                         r = 0.0F;
                      else if (ctx->Point.SpriteRMode == GL_S)
@@ -389,11 +380,6 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
       span->array->rgba[count][BCOMP] = blue;
       span->array->rgba[count][ACOMP] = alpha;
 #endif
-#if FLAGS & SPECULAR
-      span->array->spec[count][RCOMP] = specRed;
-      span->array->spec[count][GCOMP] = specGreen;
-      span->array->spec[count][BCOMP] = specBlue;
-#endif
 #if FLAGS & INDEX
       span->array->index[count] = colorIndex;
 #endif
@@ -403,9 +389,10 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
       ATTRIB_LOOP_END
 #endif
 
-      span->array->x[count] = (GLint) vert->win[0];
-      span->array->y[count] = (GLint) vert->win[1];
-      span->array->z[count] = (GLint) (vert->win[2] + 0.5F);
+      span->array->x[count] = (GLint) vert->attrib[FRAG_ATTRIB_WPOS][0];
+      span->array->y[count] = (GLint) vert->attrib[FRAG_ATTRIB_WPOS][1];
+      span->array->z[count] = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F);
+
       span->end = count + 1;
    }}
 
index 097d2c7..90a3d55 100644 (file)
 
 
 /**
- * Init span's Z interpolation values to the RasterPos Z.
- * Used during setup for glDraw/CopyPixels.
+ * Set default fragment attributes for the span using the
+ * current raster values.  Used prior to glDraw/CopyPixels
+ * and glBitmap.
  */
 void
-_swrast_span_default_z( GLcontext *ctx, SWspan *span )
+_swrast_span_default_attribs(GLcontext *ctx, SWspan *span)
 {
-   const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
-   if (ctx->DrawBuffer->Visual.depthBits <= 16)
-      span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F);
-   else
-      span->z = (GLint) (ctx->Current.RasterPos[2] * depthMax + 0.5F);
-   span->zStep = 0;
-   span->interpMask |= SPAN_Z;
-}
-
-
-/**
- * Init span's fogcoord interpolation values to the RasterPos fog.
- * Used during setup for glDraw/CopyPixels.
- */
-void
-_swrast_span_default_fog( GLcontext *ctx, SWspan *span )
-{
-   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   GLfloat fogVal; /* a coord or a blend factor */
-   if (swrast->_PreferPixelFog) {
-      /* fog blend factors will be computed from fog coordinates per pixel */
-      fogVal = ctx->Current.RasterDistance;
-   }
-   else {
-      /* fog blend factor should be computed from fogcoord now */
-      fogVal = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
+   /* Z*/
+   {
+      const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
+      if (ctx->DrawBuffer->Visual.depthBits <= 16)
+         span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F);
+      else
+         span->z = (GLint) (ctx->Current.RasterPos[2] * depthMax + 0.5F);
+      span->zStep = 0;
+      span->interpMask |= SPAN_Z;
    }
-   span->attrStart[FRAG_ATTRIB_FOGC][0] = fogVal;
-   span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0;
-   span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0;
-   span->interpMask |= SPAN_FOG;
-}
 
+   /* W (for perspective correction) */
+   span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0;
+   span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0;
+   span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0;
 
-/**
- * Init span's rgba or index interpolation values to the RasterPos color.
- * Used during setup for glDraw/CopyPixels.
- */
-void
-_swrast_span_default_color( GLcontext *ctx, SWspan *span )
-{
+   /* primary color, or color index */
    if (ctx->Visual.rgbMode) {
       GLchan r, g, b, a;
       UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]);
@@ -121,97 +98,129 @@ _swrast_span_default_color( GLcontext *ctx, SWspan *span )
       span->blueStep = 0;
       span->alphaStep = 0;
       span->interpMask |= SPAN_RGBA;
+
+      COPY_4V(span->attrStart[FRAG_ATTRIB_COL0], ctx->Current.RasterColor);
+      ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL0], 0.0, 0.0, 0.0, 0.0);
+      ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL0], 0.0, 0.0, 0.0, 0.0);
    }
    else {
       span->index = FloatToFixed(ctx->Current.RasterIndex);
       span->indexStep = 0;
       span->interpMask |= SPAN_INDEX;
    }
-}
-
 
-/**
- * Set the span's secondary color info to the current raster position's
- * secondary color, when needed (lighting enabled or colorsum enabled).
- */
-void
-_swrast_span_default_secondary_color(GLcontext *ctx, SWspan *span)
-{
+   /* Secondary color */
    if (ctx->Visual.rgbMode && (ctx->Light.Enabled || ctx->Fog.ColorSumEnabled))
    {
-      GLchan r, g, b, a;
-      UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterSecondaryColor[0]);
-      UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterSecondaryColor[1]);
-      UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterSecondaryColor[2]);
-      UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterSecondaryColor[3]);
-#if CHAN_TYPE == GL_FLOAT
-      span->specRed = r;
-      span->specGreen = g;
-      span->specBlue = b;
-      /*span->specAlpha = a;*/
-#else
-      span->specRed   = IntToFixed(r);
-      span->specGreen = IntToFixed(g);
-      span->specBlue  = IntToFixed(b);
-      /*span->specAlpha = IntToFixed(a);*/
-#endif
-      span->specRedStep = 0;
-      span->specGreenStep = 0;
-      span->specBlueStep = 0;
-      /*span->specAlphaStep = 0;*/
-      span->interpMask |= SPAN_SPEC;
+      COPY_4V(span->attrStart[FRAG_ATTRIB_COL1], ctx->Current.RasterSecondaryColor);
+      ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL1], 0.0, 0.0, 0.0, 0.0);
+      ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL1], 0.0, 0.0, 0.0, 0.0);
+   }
+
+   /* fog */
+   {
+      const SWcontext *swrast = SWRAST_CONTEXT(ctx);
+      GLfloat fogVal; /* a coord or a blend factor */
+      if (swrast->_PreferPixelFog) {
+         /* fog blend factors will be computed from fog coordinates per pixel */
+         fogVal = ctx->Current.RasterDistance;
+      }
+      else {
+         /* fog blend factor should be computed from fogcoord now */
+         fogVal = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
+      }
+      span->attrStart[FRAG_ATTRIB_FOGC][0] = fogVal;
+      span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0;
+      span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0;
+   }
+
+   /* texcoords */
+   {
+      GLuint i;
+      for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
+         const GLuint attr = FRAG_ATTRIB_TEX0 + i;
+         const GLfloat *tc = ctx->Current.RasterTexCoords[i];
+         if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) {
+            COPY_4V(span->attrStart[attr], tc);
+         }
+         else if (tc[3] > 0.0F) {
+            /* use (s/q, t/q, r/q, 1) */
+            span->attrStart[attr][0] = tc[0] / tc[3];
+            span->attrStart[attr][1] = tc[1] / tc[3];
+            span->attrStart[attr][2] = tc[2] / tc[3];
+            span->attrStart[attr][3] = 1.0;
+         }
+         else {
+            ASSIGN_4V(span->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.0F);
+         }
+         ASSIGN_4V(span->attrStepX[attr], 0.0F, 0.0F, 0.0F, 0.0F);
+         ASSIGN_4V(span->attrStepY[attr], 0.0F, 0.0F, 0.0F, 0.0F);
+      }
    }
 }
 
 
 /**
- * Init span's texcoord interpolation values to the RasterPos texcoords.
- * Used during setup for glDraw/CopyPixels.
+ * Interpolate the active attributes (and'd with attrMask) to
+ * fill in span->array->attribs[].
+ * Perspective correction will be done.  The point/line/triangle function
+ * should have computed attrStart/Step values for FRAG_ATTRIB_WPOS[3]!
  */
-void
-_swrast_span_default_texcoords( GLcontext *ctx, SWspan *span )
+static INLINE void
+interpolate_active_attribs(GLcontext *ctx, SWspan *span, GLbitfield attrMask)
 {
-   GLuint i;
-   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
-      const GLuint attr = FRAG_ATTRIB_TEX0 + i;
-      const GLfloat *tc = ctx->Current.RasterTexCoords[i];
-      if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) {
-         COPY_4V(span->attrStart[attr], tc);
-      }
-      else if (tc[3] > 0.0F) {
-         /* use (s/q, t/q, r/q, 1) */
-         span->attrStart[attr][0] = tc[0] / tc[3];
-         span->attrStart[attr][1] = tc[1] / tc[3];
-         span->attrStart[attr][2] = tc[2] / tc[3];
-         span->attrStart[attr][3] = 1.0;
-      }
-      else {
-         ASSIGN_4V(span->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.0F);
+   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+   ATTRIB_LOOP_BEGIN
+      if (attrMask & (1 << attr)) {
+         const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
+         GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];
+         const GLfloat dv0dx = span->attrStepX[attr][0];
+         const GLfloat dv1dx = span->attrStepX[attr][1];
+         const GLfloat dv2dx = span->attrStepX[attr][2];
+         const GLfloat dv3dx = span->attrStepX[attr][3];
+         GLfloat v0 = span->attrStart[attr][0];
+         GLfloat v1 = span->attrStart[attr][1];
+         GLfloat v2 = span->attrStart[attr][2];
+         GLfloat v3 = span->attrStart[attr][3];
+         GLuint k;
+         for (k = 0; k < span->end; k++) {
+            const GLfloat invW = 1.0f / w;
+            span->array->attribs[attr][k][0] = v0 * invW;
+            span->array->attribs[attr][k][1] = v1 * invW;
+            span->array->attribs[attr][k][2] = v2 * invW;
+            span->array->attribs[attr][k][3] = v3 * invW;
+            v0 += dv0dx;
+            v1 += dv1dx;
+            v2 += dv2dx;
+            v3 += dv3dx;
+            w += dwdx;
+         }
+         span->arrayAttribs |= (1 << attr);
       }
-      ASSIGN_4V(span->attrStepX[attr], 0.0F, 0.0F, 0.0F, 0.0F);
-      ASSIGN_4V(span->attrStepY[attr], 0.0F, 0.0F, 0.0F, 0.0F);
-   }
-   span->interpMask |= SPAN_TEXTURE;
+   ATTRIB_LOOP_END
 }
 
 
 /**
- * Interpolate primary colors to fill in the span->array->color array.
+ * Interpolate primary colors to fill in the span->array->rgba8 (or rgb16)
+ * color array.
  */
 static INLINE void
-interpolate_colors(SWspan *span)
+interpolate_int_colors(GLcontext *ctx, SWspan *span)
 {
    const GLuint n = span->end;
    GLuint i;
 
-   ASSERT((span->interpMask & SPAN_RGBA)  &&
-          !(span->arrayMask & SPAN_RGBA));
+#if CHAN_BITS != 32
+   ASSERT(!(span->arrayMask & SPAN_RGBA));
+#endif
 
    switch (span->array->ChanType) {
 #if CHAN_BITS != 32
    case GL_UNSIGNED_BYTE:
       {
-         GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
+         GLubyte (*rgba)[4] = span->array->rgba8;
          if (span->interpMask & SPAN_FLAT) {
             GLubyte color[4];
             color[RCOMP] = FixedToInt(span->red);
@@ -246,7 +255,7 @@ interpolate_colors(SWspan *span)
       break;
    case GL_UNSIGNED_SHORT:
       {
-         GLushort (*rgba)[4] = span->array->color.sz2.rgba;
+         GLushort (*rgba)[4] = span->array->rgba16;
          if (span->interpMask & SPAN_FLAT) {
             GLushort color[4];
             color[RCOMP] = FixedToInt(span->red);
@@ -258,7 +267,7 @@ interpolate_colors(SWspan *span)
             }
          }
          else {
-            GLushort (*rgba)[4] = span->array->color.sz2.rgba;
+            GLushort (*rgba)[4] = span->array->rgba16;
             GLfixed r, g, b, a;
             GLint dr, dg, db, da;
             r = span->red;
@@ -284,162 +293,76 @@ interpolate_colors(SWspan *span)
       break;
 #endif
    case GL_FLOAT:
-      {
-         GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
-         GLfloat r, g, b, a, dr, dg, db, da;
-         r = span->red;
-         g = span->green;
-         b = span->blue;
-         a = span->alpha;
-         if (span->interpMask & SPAN_FLAT) {
-            dr = dg = db = da = 0.0;
-         }
-         else {
-            dr = span->redStep;
-            dg = span->greenStep;
-            db = span->blueStep;
-            da = span->alphaStep;
-         }
-         for (i = 0; i < n; i++) {
-            rgba[i][RCOMP] = r;
-            rgba[i][GCOMP] = g;
-            rgba[i][BCOMP] = b;
-            rgba[i][ACOMP] = a;
-            r += dr;
-            g += dg;
-            b += db;
-            a += da;
-         }
-      }
+      interpolate_active_attribs(ctx, span, FRAG_BIT_COL0);
       break;
    default:
-      _mesa_problem(NULL, "bad datatype in interpolate_colors");
+      _mesa_problem(NULL, "bad datatype in interpolate_int_colors");
    }
    span->arrayMask |= SPAN_RGBA;
 }
 
 
 /**
- * Interpolate specular/secondary colors.
+ * Populate the FRAG_ATTRIB_COL0 array.
  */
 static INLINE void
-interpolate_specular(SWspan *span)
+interpolate_float_colors(SWspan *span)
 {
+   GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
    const GLuint n = span->end;
    GLuint i;
 
-   switch (span->array->ChanType) {
-#if CHAN_BITS != 32
-   case GL_UNSIGNED_BYTE:
-      {
-         GLubyte (*spec)[4] = span->array->color.sz1.spec;
-         if (span->interpMask & SPAN_FLAT) {
-            GLubyte color[4];
-            color[RCOMP] = FixedToInt(span->specRed);
-            color[GCOMP] = FixedToInt(span->specGreen);
-            color[BCOMP] = FixedToInt(span->specBlue);
-            color[ACOMP] = 0;
-            for (i = 0; i < n; i++) {
-               COPY_4UBV(spec[i], color);
-            }
-         }
-         else {
-            GLfixed r = span->specRed;
-            GLfixed g = span->specGreen;
-            GLfixed b = span->specBlue;
-            GLint dr = span->specRedStep;
-            GLint dg = span->specGreenStep;
-            GLint db = span->specBlueStep;
-            for (i = 0; i < n; i++) {
-               spec[i][RCOMP] = CLAMP(FixedToChan(r), 0, 255);
-               spec[i][GCOMP] = CLAMP(FixedToChan(g), 0, 255);
-               spec[i][BCOMP] = CLAMP(FixedToChan(b), 0, 255);
-               spec[i][ACOMP] = 0;
-               r += dr;
-               g += dg;
-               b += db;
-            }
-         }
+   assert(!(span->arrayAttribs & FRAG_BIT_COL0));
+
+   if (span->arrayMask & SPAN_RGBA) {
+      /* convert array of int colors */
+      for (i = 0; i < n; i++) {
+         col0[i][0] = UBYTE_TO_FLOAT(span->array->rgba8[i][0]);
+         col0[i][1] = UBYTE_TO_FLOAT(span->array->rgba8[i][1]);
+         col0[i][2] = UBYTE_TO_FLOAT(span->array->rgba8[i][2]);
+         col0[i][3] = UBYTE_TO_FLOAT(span->array->rgba8[i][3]);
       }
-      break;
-   case GL_UNSIGNED_SHORT:
-      {
-         GLushort (*spec)[4] = span->array->color.sz2.spec;
-         if (span->interpMask & SPAN_FLAT) {
-            GLushort color[4];
-            color[RCOMP] = FixedToInt(span->specRed);
-            color[GCOMP] = FixedToInt(span->specGreen);
-            color[BCOMP] = FixedToInt(span->specBlue);
-            color[ACOMP] = 0;
-            for (i = 0; i < n; i++) {
-               COPY_4V(spec[i], color);
-            }
-         }
-         else {
-            GLfixed r = FloatToFixed(span->specRed);
-            GLfixed g = FloatToFixed(span->specGreen);
-            GLfixed b = FloatToFixed(span->specBlue);
-            GLint dr = FloatToFixed(span->specRedStep);
-            GLint dg = FloatToFixed(span->specGreenStep);
-            GLint db = FloatToFixed(span->specBlueStep);
-            for (i = 0; i < n; i++) {
-               spec[i][RCOMP] = FixedToInt(r);
-               spec[i][GCOMP] = FixedToInt(g);
-               spec[i][BCOMP] = FixedToInt(b);
-               spec[i][ACOMP] = 0;
-               r += dr;
-               g += dg;
-               b += db;
-            }
+   }
+   else {
+      /* interpolate red/green/blue/alpha to get float colors */
+      ASSERT(span->interpMask & SPAN_RGBA);
+      if (span->interpMask & SPAN_FLAT) {
+         GLfloat r = FixedToFloat(span->red);
+         GLfloat g = FixedToFloat(span->green);
+         GLfloat b = FixedToFloat(span->blue);
+         GLfloat a = FixedToFloat(span->alpha);
+         for (i = 0; i < n; i++) {
+            ASSIGN_4V(col0[i], r, g, b, a);
          }
       }
-      break;
-#endif
-   case GL_FLOAT:
-      {
-         GLfloat (*spec)[4] = span->array->attribs[FRAG_ATTRIB_COL1];
-#if CHAN_BITS <= 16
-         GLfloat r = CHAN_TO_FLOAT(FixedToChan(span->specRed));
-         GLfloat g = CHAN_TO_FLOAT(FixedToChan(span->specGreen));
-         GLfloat b = CHAN_TO_FLOAT(FixedToChan(span->specBlue));
-#else
-         GLfloat r = span->specRed;
-         GLfloat g = span->specGreen;
-         GLfloat b = span->specBlue;
-#endif
-         GLfloat dr, dg, db;
-         if (span->interpMask & SPAN_FLAT) {
-            dr = dg = db = 0.0;
-         }
-         else {
-#if CHAN_BITS <= 16
-            dr = CHAN_TO_FLOAT(FixedToChan(span->specRedStep));
-            dg = CHAN_TO_FLOAT(FixedToChan(span->specGreenStep));
-            db = CHAN_TO_FLOAT(FixedToChan(span->specBlueStep));
-#else
-            dr = span->specRedStep;
-            dg = span->specGreenStep;
-            db = span->specBlueStep;
-#endif
-         }
+      else {
+         GLfloat r = FixedToFloat(span->red);
+         GLfloat g = FixedToFloat(span->green);
+         GLfloat b = FixedToFloat(span->blue);
+         GLfloat a = FixedToFloat(span->alpha);
+         GLfloat dr = FixedToFloat(span->redStep);
+         GLfloat dg = FixedToFloat(span->greenStep);
+         GLfloat db = FixedToFloat(span->blueStep);
+         GLfloat da = FixedToFloat(span->alphaStep);
          for (i = 0; i < n; i++) {
-            spec[i][RCOMP] = r;
-            spec[i][GCOMP] = g;
-            spec[i][BCOMP] = b;
-            spec[i][ACOMP] = 0.0F;
+            col0[i][0] = r;
+            col0[i][1] = g;
+            col0[i][2] = b;
+            col0[i][3] = a;
             r += dr;
             g += dg;
             b += db;
+            a += da;
          }
       }
-      break;
-   default:
-      _mesa_problem(NULL, "bad datatype in interpolate_specular");
    }
-   span->arrayMask |= SPAN_SPEC;
+
+   span->arrayAttribs |= FRAG_BIT_COL0;
+   span->array->ChanType = GL_FLOAT;
 }
 
 
+
 /* Fill in the span.color.index array from the interpolation values */
 static INLINE void
 interpolate_indexes(GLcontext *ctx, SWspan *span)
@@ -450,8 +373,8 @@ interpolate_indexes(GLcontext *ctx, SWspan *span)
    GLuint *indexes = span->array->index;
    GLuint i;
    (void) ctx;
-   ASSERT((span->interpMask & SPAN_INDEX)  &&
-         !(span->arrayMask & SPAN_INDEX));
+
+   ASSERT(!(span->arrayMask & SPAN_INDEX));
 
    if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) {
       /* constant color */
@@ -472,35 +395,16 @@ interpolate_indexes(GLcontext *ctx, SWspan *span)
 }
 
 
-/* Fill in the span.array.fog values from the interpolation values */
-static INLINE void
-interpolate_fog(const GLcontext *ctx, SWspan *span)
-{
-   GLfloat (*fog)[4] = span->array->attribs[FRAG_ATTRIB_FOGC];
-   const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0];
-   GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0];
-   const GLuint haveW = (span->interpMask & SPAN_W);
-   const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;
-   GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F;
-   GLuint i;
-   for (i = 0; i < span->end; i++) {
-      fog[i][0] = fogCoord / w;
-      fogCoord += fogStep;
-      w += wStep;
-   }
-   span->arrayMask |= SPAN_FOG;
-}
-
-
-/* Fill in the span.zArray array from the interpolation values */
+/**
+ * Fill in the span.zArray array from the span->z, zStep values.
+ */
 void
 _swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span )
 {
    const GLuint n = span->end;
    GLuint i;
 
-   ASSERT((span->interpMask & SPAN_Z)  &&
-         !(span->arrayMask & SPAN_Z));
+   ASSERT(!(span->arrayMask & SPAN_Z));
 
    if (ctx->DrawBuffer->Visual.depthBits <= 16) {
       GLfixed zval = span->z;
@@ -524,7 +428,8 @@ _swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span )
 }
 
 
-/*
+/**
+ * Compute mipmap LOD from partial derivatives.
  * This the ideal solution, as given in the OpenGL spec.
  */
 #if 0
@@ -546,8 +451,9 @@ compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
 #endif
 
 
-/*
- * This is a faster approximation
+/**
+ * Compute mipmap LOD from partial derivatives.
+ * This is a faster approximation than above function.
  */
 GLfloat
 _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
@@ -572,14 +478,15 @@ _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
 
 
 /**
- * Fill in the span.texcoords array from the interpolation values.
+ * Fill in the span.array->attrib[FRAG_ATTRIB_TEXn] arrays from the
+ * using the attrStart/Step values.
+ *
+ * This function only used during fixed-function fragment processing.
+ *
  * Note: in the places where we divide by Q (or mult by invQ) we're
  * really doing two things: perspective correction and texcoord
  * projection.  Remember, for texcoord (s,t,r,q) we need to index
  * texels with (s/q, t/q, r/q).
- * If we're using a fragment program, we never do the division
- * for texcoord projection.  That's done by the TXP instruction
- * or user-written code.
  */
 static void
 interpolate_texcoords(GLcontext *ctx, SWspan *span)
@@ -588,11 +495,6 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span)
       = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1;
    GLuint u;
 
-   ASSERT(span->interpMask & SPAN_TEXTURE);
-   ASSERT(!(span->arrayMask & SPAN_TEXTURE));
-
-   span->arrayMask |= SPAN_TEXTURE;
-
    /* XXX CoordUnits vs. ImageUnits */
    for (u = 0; u < maxUnit; u++) {
       if (ctx->Texture._EnabledCoordUnits & (1 << u)) {
@@ -724,55 +626,6 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span)
 }
 
 
-
-/**
- * Fill in the arrays->attribs[FRAG_ATTRIB_VARx] arrays from the
- * interpolation values.
- * XXX since interpolants/arrays are getting uniformed, we might merge
- * this with interpolate_texcoords(), interpolate_Fog(), etc. someday.
- */
-static INLINE void
-interpolate_varying(GLcontext *ctx, SWspan *span)
-{
-   GLuint var;
-   const GLbitfield inputsUsed = ctx->FragmentProgram._Current->Base.InputsRead;
-
-   ASSERT(span->interpMask & SPAN_VARYING);
-   ASSERT(!(span->arrayMask & SPAN_VARYING));
-
-   span->arrayMask |= SPAN_VARYING;
-
-   for (var = 0; var < MAX_VARYING; var++) {
-      if (inputsUsed & FRAG_BIT_VAR(var)) {
-         const GLuint attr = FRAG_ATTRIB_VAR0 + var;
-         const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
-         GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];
-         const GLfloat dv0dx = span->attrStepX[attr][0];
-         const GLfloat dv1dx = span->attrStepX[attr][1];
-         const GLfloat dv2dx = span->attrStepX[attr][2];
-         const GLfloat dv3dx = span->attrStepX[attr][3];
-         GLfloat v0 = span->attrStart[attr][0];
-         GLfloat v1 = span->attrStart[attr][1];
-         GLfloat v2 = span->attrStart[attr][2];
-         GLfloat v3 = span->attrStart[attr][3];
-         GLuint k;
-         for (k = 0; k < span->end; k++) {
-            GLfloat invW = 1.0f / w;
-            span->array->attribs[attr][k][0] = v0 * invW;
-            span->array->attribs[attr][k][1] = v1 * invW;
-            span->array->attribs[attr][k][2] = v2 * invW;
-            span->array->attribs[attr][k][3] = v3 * invW;
-            v0 += dv0dx;
-            v1 += dv1dx;
-            v2 += dv2dx;
-            v3 += dv3dx;
-            w += dwdx;
-         }
-      }
-   }
-}
-
-
 /**
  * Fill in the arrays->attribs[FRAG_ATTRIB_WPOS] array.
  */
@@ -934,7 +787,9 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
    ASSERT(span->primitive == GL_POINT  ||  span->primitive == GL_LINE ||
          span->primitive == GL_POLYGON  ||  span->primitive == GL_BITMAP);
    ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX);
+   /*
    ASSERT((span->interpMask & span->arrayMask) == 0);
+   */
 
    if (span->arrayMask & SPAN_MASK) {
       /* mask was initialized by caller, probably glBitmap */
@@ -981,7 +836,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
 
    /* Stencil and Z testing */
    if (ctx->Depth.Test || ctx->Stencil.Enabled) {
-      if (span->interpMask & SPAN_Z)
+      if (!(span->arrayMask & SPAN_Z))
          _swrast_span_interpolate_z(ctx, span);
 
       if (ctx->Stencil.Enabled) {
@@ -1022,7 +877,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
        ctx->Color.IndexLogicOpEnabled ||
        ctx->Color.IndexMask != 0xffffffff ||
        (span->arrayMask & SPAN_COVERAGE)) {
-      if (span->interpMask & SPAN_INDEX) {
+      if (!(span->arrayMask & SPAN_INDEX) /*span->interpMask & SPAN_INDEX*/) {
          interpolate_indexes(ctx, span);
       }
    }
@@ -1071,7 +926,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
             _swrast_mask_ci_span(ctx, rb, span);
          }
 
-         if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) {
+         if (!(span->arrayMask & SPAN_INDEX) && span->indexStep == 0) {
             /* all fragments have same color index */
             GLubyte index8;
             GLushort index16;
@@ -1151,63 +1006,52 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
 
 
 /**
- * Add specular color to base color.  This is used only when
- * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR.
+ * Add specular colors to primary colors.
+ * Only called during fixed-function operation.
+ * Result is float color array (FRAG_ATTRIB_COL0).
  */
 static INLINE void
 add_specular(GLcontext *ctx, SWspan *span)
 {
-   switch (span->array->ChanType) {
-   case GL_UNSIGNED_BYTE:
-      {
-         GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
-         GLubyte (*spec)[4] = span->array->color.sz1.spec;
-         GLuint i;
-         for (i = 0; i < span->end; i++) {
-            GLint r = rgba[i][RCOMP] + spec[i][RCOMP];
-            GLint g = rgba[i][GCOMP] + spec[i][GCOMP];
-            GLint b = rgba[i][BCOMP] + spec[i][BCOMP];
-            GLint a = rgba[i][ACOMP] + spec[i][ACOMP];
-            rgba[i][RCOMP] = MIN2(r, 255);
-            rgba[i][GCOMP] = MIN2(g, 255);
-            rgba[i][BCOMP] = MIN2(b, 255);
-            rgba[i][ACOMP] = MIN2(a, 255);
-         }
+   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
+   const GLubyte *mask = span->array->mask;
+   GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
+   GLfloat (*col1)[4] = span->array->attribs[FRAG_ATTRIB_COL1];
+   GLuint i;
+
+   ASSERT(!ctx->FragmentProgram._Current);
+   ASSERT(span->arrayMask & SPAN_RGBA);
+   ASSERT(swrast->_ActiveAttribMask & FRAG_BIT_COL1);
+
+   if (span->array->ChanType == GL_FLOAT) {
+      if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {
+         interpolate_active_attribs(ctx, span, FRAG_BIT_COL0);
       }
-      break;
-   case GL_UNSIGNED_SHORT:
-      {
-         GLushort (*rgba)[4] = span->array->color.sz2.rgba;
-         GLushort (*spec)[4] = span->array->color.sz2.spec;
-         GLuint i;
-         for (i = 0; i < span->end; i++) {
-            GLint r = rgba[i][RCOMP] + spec[i][RCOMP];
-            GLint g = rgba[i][GCOMP] + spec[i][GCOMP];
-            GLint b = rgba[i][BCOMP] + spec[i][BCOMP];
-            GLint a = rgba[i][ACOMP] + spec[i][ACOMP];
-            rgba[i][RCOMP] = MIN2(r, 65535);
-            rgba[i][GCOMP] = MIN2(g, 65535);
-            rgba[i][BCOMP] = MIN2(b, 65535);
-            rgba[i][ACOMP] = MIN2(a, 65535);
-         }
+   }
+   else {
+      /* need float colors */
+      if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {
+         interpolate_float_colors(span);
       }
-      break;
-   case GL_FLOAT:
-      {
-         GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
-         GLfloat (*spec)[4] = span->array->attribs[FRAG_ATTRIB_COL1];
-         GLuint i;
-         for (i = 0; i < span->end; i++) {
-            rgba[i][RCOMP] += spec[i][RCOMP];
-            rgba[i][GCOMP] += spec[i][GCOMP];
-            rgba[i][BCOMP] += spec[i][BCOMP];
-            rgba[i][ACOMP] += spec[i][ACOMP];
-         }
+   }
+
+   if ((span->arrayAttribs & FRAG_BIT_COL1) == 0) {
+      /* XXX could avoid this and interpolate COL1 in the loop below */
+      interpolate_active_attribs(ctx, span, FRAG_BIT_COL1);
+   }
+
+   ASSERT(span->arrayAttribs & FRAG_BIT_COL0);
+   ASSERT(span->arrayAttribs & FRAG_BIT_COL1);
+
+   for (i = 0; i < span->end; i++) {
+      if (mask[i]) {
+         col0[i][0] += col1[i][0];
+         col0[i][1] += col1[i][1];
+         col0[i][2] += col1[i][2];
       }
-      break;
-   default:
-      _mesa_problem(ctx, "Invalid datatype in add_specular");
    }
+
+   span->array->ChanType = GL_FLOAT;
 }
 
 
@@ -1220,7 +1064,7 @@ apply_aa_coverage(SWspan *span)
    const GLfloat *coverage = span->array->coverage;
    GLuint i;
    if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-      GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
+      GLubyte (*rgba)[4] = span->array->rgba8;
       for (i = 0; i < span->end; i++) {
          const GLfloat a = rgba[i][ACOMP] * coverage[i];
          rgba[i][ACOMP] = (GLubyte) CLAMP(a, 0.0, 255.0);
@@ -1229,7 +1073,7 @@ apply_aa_coverage(SWspan *span)
       }
    }
    else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-      GLushort (*rgba)[4] = span->array->color.sz2.rgba;
+      GLushort (*rgba)[4] = span->array->rgba16;
       for (i = 0; i < span->end; i++) {
          const GLfloat a = rgba[i][ACOMP] * coverage[i];
          rgba[i][ACOMP] = (GLushort) CLAMP(a, 0.0, 65535.0);
@@ -1239,6 +1083,7 @@ apply_aa_coverage(SWspan *span)
       GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
       for (i = 0; i < span->end; i++) {
          rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i];
+         /* clamp later */
       }
    }
 }
@@ -1278,18 +1123,18 @@ convert_color_type(SWspan *span, GLenum newType, GLuint output)
       span->array->ChanType = GL_FLOAT;
    }
    else if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-      src = span->array->color.sz1.rgba;
+      src = span->array->rgba8;
    }
    else {
       ASSERT(span->array->ChanType == GL_UNSIGNED_SHORT);
-      src = span->array->color.sz2.rgba;
+      src = span->array->rgba16;
    }
 
    if (newType == GL_UNSIGNED_BYTE) {
-      dst = span->array->color.sz1.rgba;
+      dst = span->array->rgba8;
    }
    else if (newType == GL_UNSIGNED_SHORT) {
-      dst = span->array->color.sz2.rgba;
+      dst = span->array->rgba16;
    }
    else {
       dst = span->array->attribs[FRAG_ATTRIB_COL0];
@@ -1321,42 +1166,16 @@ shade_texture_span(GLcontext *ctx, SWspan *span)
       inputsRead = ~0;
    }
 
-   if ((inputsRead & FRAG_BIT_COL0) && (span->interpMask & SPAN_RGBA))
-      interpolate_colors(span);
-
-   if (ctx->Texture._EnabledCoordUnits && (span->interpMask & SPAN_TEXTURE))
-      interpolate_texcoords(ctx, span);
-
    if (ctx->FragmentProgram._Current ||
        ctx->ATIFragmentShader._Enabled) {
-      /* use float colors if running a fragment program or shader */
-      const GLenum oldType = span->array->ChanType;
-      const GLenum newType = GL_FLOAT;
-
-      if ((inputsRead & FRAG_BIT_COL0) && (oldType != newType)) {
-         GLvoid *src = (oldType == GL_UNSIGNED_BYTE)
-            ? (GLvoid *) span->array->color.sz1.rgba
-            : (GLvoid *) span->array->color.sz2.rgba;
-         assert(span->arrayMask & SPAN_RGBA);
-         _mesa_convert_colors(oldType, src,
-                              newType, span->array->attribs[FRAG_ATTRIB_COL0],
-                              span->end, span->array->mask);
-      }
-      span->array->ChanType = newType;
-
-      /* fragment programs/shaders may need specular, fog and Z coords */
-      if ((inputsRead & FRAG_BIT_COL1) && (span->interpMask & SPAN_SPEC))
-         interpolate_specular(span);
+      /* programmable shading */
+      span->array->ChanType = GL_FLOAT;
 
-      if ((inputsRead & FRAG_BIT_FOGC) && (span->interpMask & SPAN_FOG))
-         interpolate_fog(ctx, span);
+      interpolate_active_attribs(ctx, span, ~0);
 
-      if (span->interpMask & SPAN_Z)
+      if (!(span->arrayMask & SPAN_Z))
          _swrast_span_interpolate_z (ctx, span);
 
-      if ((inputsRead >= FRAG_BIT_VAR0) && (span->interpMask & SPAN_VARYING))
-         interpolate_varying(ctx, span);
-
 #if 0
       if (inputsRead & FRAG_BIT_WPOS)
 #else
@@ -1373,8 +1192,20 @@ shade_texture_span(GLcontext *ctx, SWspan *span)
          _swrast_exec_fragment_shader(ctx, span);
       }
    }
-   else if (ctx->Texture._EnabledUnits && (span->arrayMask & SPAN_TEXTURE)) {
+   else if (ctx->Texture._EnabledUnits) {
       /* conventional texturing */
+
+#if CHAN_BITS == 32
+      if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {
+         interpolate_int_colors(ctx, span);
+      }
+#else
+      if (!(span->arrayMask & SPAN_RGBA))
+         interpolate_int_colors(ctx, span);
+#endif
+      if ((span->arrayAttribs & FRAG_BITS_TEX_ANY) == 0x0)
+         interpolate_texcoords(ctx, span);
+
       _swrast_texture_span(ctx, span);
    }
 }
@@ -1395,13 +1226,13 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
    const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
    const GLbitfield origInterpMask = span->interpMask;
    const GLbitfield origArrayMask = span->arrayMask;
+   const GLbitfield origArrayAttribs = span->arrayAttribs;
    const GLenum chanType = span->array->ChanType;
    const GLboolean shader = (ctx->FragmentProgram._Current
                              || ctx->ATIFragmentShader._Enabled);
    const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits;
    struct gl_framebuffer *fb = ctx->DrawBuffer;
    GLuint output;
-   GLboolean deferredTexture;
 
    /*
    printf("%s()  interp 0x%x  array 0x%x\n", __FUNCTION__,
@@ -1413,41 +1244,6 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
          span->primitive == GL_POLYGON ||
           span->primitive == GL_BITMAP);
    ASSERT(span->end <= MAX_WIDTH);
-   ASSERT((span->interpMask & span->arrayMask) == 0);
-   ASSERT((span->interpMask & SPAN_RGBA) ^ (span->arrayMask & SPAN_RGBA));
-
-   /* check for conditions that prevent deferred shading (doing shading
-    * after stencil/ztest).
-    * XXX move this code into state validation.
-    */
-   if (ctx->Color.AlphaEnabled) {
-      /* alpha test depends on post-texture/shader colors */
-      deferredTexture = GL_FALSE;
-   }
-   else if (shaderOrTexture) {
-      if (ctx->FragmentProgram._Current) {
-         if (ctx->FragmentProgram._Current->Base.OutputsWritten
-             & (1 << FRAG_RESULT_DEPR)) {
-            /* Z comes from fragment program/shader */
-            deferredTexture = GL_FALSE;
-         }
-         else if (ctx->Query.CurrentOcclusionObject) {
-            /* occlusion query depends on shader discard/kill results */
-            deferredTexture = GL_FALSE;
-         }
-         else {
-            deferredTexture = GL_TRUE;
-         }
-      }
-      else {
-         /* ATI frag shader or conventional texturing */
-         deferredTexture = GL_TRUE;
-      }
-   }
-   else {
-      /* no texturing or shadering */
-      deferredTexture = GL_FALSE;
-   }
 
    /* Fragment write masks */
    if (span->arrayMask & SPAN_MASK) {
@@ -1486,12 +1282,10 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
       stipple_polygon_span(ctx, span);
    }
 
-   /* This is the normal place to compute the resulting fragment color/Z.
-    * As an optimization, we try to defer this until after Z/stencil
-    * testing in order to try to avoid computing colors that we won't
-    * actually need.
+   /* This is the normal place to compute the fragment color/Z
+    * from texturing or shading.
     */
-   if (shaderOrTexture && !deferredTexture) {
+   if (shaderOrTexture && !swrast->_DeferredTexture) {
       shade_texture_span(ctx, span);
    }
 
@@ -1504,7 +1298,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
 
    /* Stencil and Z testing */
    if (ctx->Stencil.Enabled || ctx->Depth.Test) {
-      if (span->interpMask & SPAN_Z)
+      if (!(span->arrayMask & SPAN_Z))
          _swrast_span_interpolate_z(ctx, span);
 
       if (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0) {
@@ -1544,14 +1338,19 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
     * a good chance that many fragments will have already been killed by
     * Z/stencil testing.
     */
-   if (deferredTexture) {
-      ASSERT(shaderOrTexture);
+   if (shaderOrTexture && swrast->_DeferredTexture) {
       shade_texture_span(ctx, span);
    }
 
+#if CHAN_BITS == 32
+   if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) {
+      interpolate_int_colors(ctx, span);
+   }
+#else
    if ((span->arrayMask & SPAN_RGBA) == 0) {
-      interpolate_colors(span);
+      interpolate_int_colors(ctx, span);
    }
+#endif
 
    ASSERT(span->arrayMask & SPAN_RGBA);
 
@@ -1560,17 +1359,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
       if (ctx->Fog.ColorSumEnabled ||
           (ctx->Light.Enabled &&
            ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
-         if (span->interpMask & SPAN_SPEC) {
-            interpolate_specular(span);
-         }
-         if (span->arrayMask & SPAN_SPEC) {
-            add_specular(ctx, span);
-         }
-         else {
-            /* We probably added the base/specular colors during the
-             * vertex stage!
-             */
-         }
+         add_specular(ctx, span);
       }
    }
 
@@ -1659,6 +1448,7 @@ end:
    /* restore these values before returning */
    span->interpMask = origInterpMask;
    span->arrayMask = origArrayMask;
+   span->arrayAttribs = origArrayAttribs;
    span->array->ChanType = chanType;
 }
 
@@ -1921,18 +1711,9 @@ _swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb,
    void *rbPixels;
 
    /*
-    * Determine pixel size (in bytes).
     * Point rbPixels to a temporary space (use specular color arrays).
     */
-   if (span->array->ChanType == GL_UNSIGNED_BYTE) {
-      rbPixels = span->array->color.sz1.spec;
-   }
-   else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
-      rbPixels = span->array->color.sz2.spec;
-   }
-   else {
-      rbPixels = span->array->attribs[FRAG_ATTRIB_COL1];
-   }
+   rbPixels = span->array->attribs[FRAG_ATTRIB_COL1];
 
    /* Get destination values from renderbuffer */
    if (span->arrayMask & SPAN_XY) {
index f650a27..585cce9 100644 (file)
 
 /**
  * \defgroup SpanFlags
- * Bitflags used for interpMask and arrayMask fields below to indicate
- * which interpolant values and fragment arrays are in use, respectively.
+ * Special bitflags to describe span data.
  *
- * XXX We should replace these flags with the FRAG_BIT_ values someday...
+ * In general, the point/line/triangle functions interpolate/emit the
+ * attributes specified by swrast->_ActiveAttribs (i.e. FRAT_BIT_* values).
+ * Some things don't fit into that, though, so we have these flags.
  */
 /*@{*/
-#define SPAN_RGBA         0x001
-#define SPAN_SPEC         0x002
-#define SPAN_INDEX        0x004
-#define SPAN_Z            0x008
-#define SPAN_W            0x010
-#define SPAN_FOG          0x020
-#define SPAN_TEXTURE      0x040
-#define SPAN_INT_TEXTURE  0x080
-#define SPAN_LAMBDA       0x100
-#define SPAN_COVERAGE     0x200
-#define SPAN_FLAT         0x400  /**< flat shading? */
-#define SPAN_XY           0x800
-#define SPAN_MASK        0x1000
-#define SPAN_VARYING     0x2000
+#define SPAN_RGBA       0x01  /**< interpMask and arrayMask */
+#define SPAN_INDEX      0x02  /**< interpMask and arrayMask */
+#define SPAN_Z          0x04  /**< interpMask and arrayMask */
+#define SPAN_FLAT       0x08  /**< interpMask: flat shading? */
+#define SPAN_XY         0x10  /**< array.x[], y[] valid? */
+#define SPAN_MASK       0x20  /**< was array.mask[] filled in by caller? */
+#define SPAN_LAMBDA     0x40  /**< array.lambda[] valid? */
+#define SPAN_COVERAGE   0x80  /**< array.coverage[] valid? */
 /*@}*/
 
 
-#if 0
-/* alternate arrangement for code below */
-struct arrays2 {
-   union {
-      GLubyte  sz1[MAX_WIDTH][4]; /* primary color */
-      GLushort sz2[MAX_WIDTH][4];
-   } rgba;
-   union {
-      GLubyte  sz1[MAX_WIDTH][4]; /* specular color and temp storage */
-      GLushort sz2[MAX_WIDTH][4];
-   } spec;
-};
-#endif
-
-
-
 /**
  * \sw_span_arrays 
  * \brief Arrays of fragment values.
@@ -92,26 +71,19 @@ typedef struct sw_span_arrays
    GLubyte mask[MAX_WIDTH];
 
    GLenum ChanType; /**< Color channel type, GL_UNSIGNED_BYTE, GL_FLOAT */
-   union {
-      struct {
-         GLubyte rgba[MAX_WIDTH][4]; /**< primary color */
-         GLubyte spec[MAX_WIDTH][4]; /**< specular color and temp storage */
-      } sz1;
-      struct {
-         GLushort rgba[MAX_WIDTH][4];
-         GLushort spec[MAX_WIDTH][4];
-      } sz2;
-   } color;
-   /** XXX these are temporary fields, pointing into above color arrays */
-   GLchan (*rgba)[4];
-   GLchan (*spec)[4];
 
+   /** Attribute arrays that don't fit into attribs[] array above */
+   /*@{*/
+   GLubyte rgba8[MAX_WIDTH][4];
+   GLushort rgba16[MAX_WIDTH][4];
+   GLchan (*rgba)[4];  /** either == rgba8 or rgba16 */
    GLint   x[MAX_WIDTH];  /**< fragment X coords */
    GLint   y[MAX_WIDTH];  /**< fragment Y coords */
    GLuint  z[MAX_WIDTH];  /**< fragment Z coords */
    GLuint  index[MAX_WIDTH];  /**< Color indexes */
    GLfloat lambda[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH]; /**< Texture LOD */
    GLfloat coverage[MAX_WIDTH];  /**< Fragment coverage for AA/smoothing */
+   /*@}*/
 } SWspanarrays;
 
 
@@ -160,26 +132,13 @@ typedef struct sw_span
    /* For horizontal spans, step is the partial derivative wrt X.
     * For lines, step is the delta from one fragment to the next.
     */
-#if CHAN_TYPE == GL_FLOAT
-   GLfloat red, redStep;
-   GLfloat green, greenStep;
-   GLfloat blue, blueStep;
-   GLfloat alpha, alphaStep;
-   GLfloat specRed, specRedStep;
-   GLfloat specGreen, specGreenStep;
-   GLfloat specBlue, specBlueStep;
-#else /* CHAN_TYPE == GL_UNSIGNED_BYTE or GL_UNSIGNED_SHORT */
    GLfixed red, redStep;
    GLfixed green, greenStep;
    GLfixed blue, blueStep;
    GLfixed alpha, alphaStep;
-   GLfixed specRed, specRedStep;
-   GLfixed specGreen, specGreenStep;
-   GLfixed specBlue, specBlueStep;
-#endif
    GLfixed index, indexStep;
-   GLfixed z, zStep;    /* XXX z should probably be GLuint */
-   GLfixed intTex[2], intTexStep[2];  /* s, t only */
+   GLfixed z, zStep;    /**< XXX z should probably be GLuint */
+   GLfixed intTex[2], intTexStep[2];  /**< (s,t) for unit[0] only */
 
    /**
     * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates
@@ -187,6 +146,8 @@ typedef struct sw_span
     */
    GLbitfield arrayMask;
 
+   GLbitfield arrayAttribs;
+
    /**
     * We store the arrays of fragment values in a separate struct so
     * that we can allocate sw_span structs on the stack without using
@@ -203,6 +164,7 @@ do {                                                                \
    (S).primitive = (PRIMITIVE);                                        \
    (S).interpMask = (INTERP_MASK);                             \
    (S).arrayMask = (ARRAY_MASK);                               \
+   (S).arrayAttribs = 0x0;                                     \
    (S).end = (END);                                            \
    (S).facing = 0;                                             \
    (S).array = SWRAST_CONTEXT(ctx)->SpanArrays;                        \
@@ -211,23 +173,11 @@ do {                                                              \
 
 
 extern void
-_swrast_span_default_z( GLcontext *ctx, SWspan *span );
+_swrast_span_default_attribs(GLcontext *ctx, SWspan *span);
 
 extern void
 _swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span );
 
-extern void
-_swrast_span_default_fog( GLcontext *ctx, SWspan *span );
-
-extern void
-_swrast_span_default_color( GLcontext *ctx, SWspan *span );
-
-extern void
-_swrast_span_default_secondary_color(GLcontext *ctx, SWspan *span);
-
-extern void
-_swrast_span_default_texcoords( GLcontext *ctx, SWspan *span );
-
 extern GLfloat
 _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
                        GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
index ebb4c0d..4ac7222 100644 (file)
@@ -1080,7 +1080,6 @@ _swrast_texture_span( GLcontext *ctx, SWspan *span )
    GLuint unit;
 
    ASSERT(span->end < MAX_WIDTH);
-   ASSERT(span->arrayMask & SPAN_TEXTURE);
 
    /*
     * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR)
index fc9d29b..c255545 100644 (file)
@@ -52,10 +52,10 @@ _swrast_culltriangle( GLcontext *ctx,
                       const SWvertex *v1,
                       const SWvertex *v2 )
 {
-   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 ex = v1->attrib[FRAG_ATTRIB_WPOS][0] - v0->attrib[FRAG_ATTRIB_WPOS][0];
+   GLfloat ey = v1->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1];
+   GLfloat fx = v2->attrib[FRAG_ATTRIB_WPOS][0] - v0->attrib[FRAG_ATTRIB_WPOS][0];
+   GLfloat fy = v2->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1];
    GLfloat c = ex*fy-ey*fx;
 
    if (c * SWRAST_CONTEXT(ctx)->_BackfaceSign > 0)
@@ -71,7 +71,7 @@ _swrast_culltriangle( GLcontext *ctx,
  */
 #define NAME ci_triangle
 #define INTERP_Z 1
-#define INTERP_FOG 1
+#define INTERP_ATTRIBS 1  /* just for fog */
 #define INTERP_INDEX 1
 #define RENDER_SPAN( span )  _swrast_write_index_span(ctx, &span);
 #include "s_tritemp.h"
@@ -83,7 +83,6 @@ _swrast_culltriangle( GLcontext *ctx,
  */
 #define NAME flat_rgba_triangle
 #define INTERP_Z 1
-#define INTERP_FOG 1
 #define SETUP_CODE                             \
    ASSERT(ctx->Texture._EnabledCoordUnits == 0);\
    ASSERT(ctx->Light.ShadeModel==GL_FLAT);     \
@@ -106,7 +105,6 @@ _swrast_culltriangle( GLcontext *ctx,
  */
 #define NAME smooth_rgba_triangle
 #define INTERP_Z 1
-#define INTERP_FOG 1
 #define INTERP_RGB 1
 #define INTERP_ALPHA 1
 #define SETUP_CODE                             \
@@ -228,7 +226,6 @@ _swrast_culltriangle( GLcontext *ctx,
 #include "s_tritemp.h"
 
 
-
 #if CHAN_TYPE != GL_FLOAT
 
 struct affine_info
@@ -511,7 +508,6 @@ affine_span(GLcontext *ctx, SWspan *span,
  */
 #define NAME affine_textured_triangle
 #define INTERP_Z 1
-#define INTERP_FOG 1
 #define INTERP_RGB 1
 #define INTERP_ALPHA 1
 #define INTERP_INT_TEX 1
@@ -784,8 +780,6 @@ fast_persp_span(GLcontext *ctx, SWspan *span,
  */
 #define NAME persp_textured_triangle
 #define INTERP_Z 1
-#define INTERP_W 1
-#define INTERP_FOG 1
 #define INTERP_RGB 1
 #define INTERP_ALPHA 1
 #define INTERP_ATTRIBS 1
@@ -843,10 +837,8 @@ fast_persp_span(GLcontext *ctx, SWspan *span,
 
 #include "s_tritemp.h"
 
+#endif /*CHAN_TYPE != GL_FLOAT*/
 
-#endif /* CHAN_BITS != GL_FLOAT */
-
-                
 
 
 /*
@@ -854,10 +846,7 @@ fast_persp_span(GLcontext *ctx, SWspan *span,
  */
 #define NAME general_triangle
 #define INTERP_Z 1
-#define INTERP_W 1
-#define INTERP_FOG 1
 #define INTERP_RGB 1
-#define INTERP_SPEC 1
 #define INTERP_ALPHA 1
 #define INTERP_ATTRIBS 1
 #define RENDER_SPAN( span )   _swrast_write_rgba_span(ctx, &span);
@@ -924,51 +913,47 @@ nodraw_triangle( GLcontext *ctx,
  * draw the triangle, then restore the original primary color.
  * Inefficient, but seldom needed.
  */
-void _swrast_add_spec_terms_triangle( GLcontext *ctx,
-                                     const SWvertex *v0,
-                                     const SWvertex *v1,
-                                     const SWvertex *v2 )
+void
+_swrast_add_spec_terms_triangle(GLcontext *ctx, const SWvertex *v0,
+                                const SWvertex *v1, const SWvertex *v2)
 {
    SWvertex *ncv0 = (SWvertex *)v0; /* drop const qualifier */
    SWvertex *ncv1 = (SWvertex *)v1;
    SWvertex *ncv2 = (SWvertex *)v2;
-#if CHAN_TYPE == GL_FLOAT
    GLfloat rSum, gSum, bSum;
-#else
-   GLint rSum, gSum, bSum;
-#endif
-   GLchan c[3][4];
+   GLchan cSave[3][4];
+
    /* save original colors */
-   COPY_CHAN4( c[0], ncv0->color );
-   COPY_CHAN4( c[1], ncv1->color );
-   COPY_CHAN4( c[2], ncv2->color );
+   COPY_CHAN4( cSave[0], ncv0->color );
+   COPY_CHAN4( cSave[1], ncv1->color );
+   COPY_CHAN4( cSave[2], ncv2->color );
    /* sum v0 */
-   rSum = ncv0->color[0] + ncv0->specular[0];
-   gSum = ncv0->color[1] + ncv0->specular[1];
-   bSum = ncv0->color[2] + ncv0->specular[2];
-   ncv0->color[0] = MIN2(rSum, CHAN_MAX);
-   ncv0->color[1] = MIN2(gSum, CHAN_MAX);
-   ncv0->color[2] = MIN2(bSum, CHAN_MAX);
+   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 = ncv1->color[0] + ncv1->specular[0];
-   gSum = ncv1->color[1] + ncv1->specular[1];
-   bSum = ncv1->color[2] + ncv1->specular[2];
-   ncv1->color[0] = MIN2(rSum, CHAN_MAX);
-   ncv1->color[1] = MIN2(gSum, CHAN_MAX);
-   ncv1->color[2] = MIN2(bSum, CHAN_MAX);
+   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);
    /* sum v2 */
-   rSum = ncv2->color[0] + ncv2->specular[0];
-   gSum = ncv2->color[1] + ncv2->specular[1];
-   bSum = ncv2->color[2] + ncv2->specular[2];
-   ncv2->color[0] = MIN2(rSum, CHAN_MAX);
-   ncv2->color[1] = MIN2(gSum, CHAN_MAX);
-   ncv2->color[2] = MIN2(bSum, CHAN_MAX);
+   rSum = CHAN_TO_FLOAT(ncv2->color[0]) + ncv2->attrib[FRAG_ATTRIB_COL1][0];
+   gSum = CHAN_TO_FLOAT(ncv2->color[1]) + ncv2->attrib[FRAG_ATTRIB_COL1][1];
+   bSum = CHAN_TO_FLOAT(ncv2->color[2]) + ncv2->attrib[FRAG_ATTRIB_COL1][2];
+   UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[0], rSum);
+   UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[1], gSum);
+   UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[2], bSum);
    /* draw */
    SWRAST_CONTEXT(ctx)->SpecTriangle( ctx, ncv0, ncv1, ncv2 );
    /* restore original colors */
-   COPY_CHAN4( ncv0->color, c[0] );
-   COPY_CHAN4( ncv1->color, c[1] );
-   COPY_CHAN4( ncv2->color, c[2] );
+   COPY_CHAN4( ncv0->color, cSave[0] );
+   COPY_CHAN4( ncv1->color, cSave[1] );
+   COPY_CHAN4( ncv2->color, cSave[2] );
 }
 
 
@@ -1044,9 +1029,15 @@ _swrast_choose_triangle( GLcontext *ctx )
          return;
       }
 
+      /*
+       * XXX should examine swrast->_ActiveAttribMask to determine what
+       * needs to be interpolated.
+       */
       if (ctx->Texture._EnabledCoordUnits ||
           ctx->FragmentProgram._Current ||
-          ctx->ATIFragmentShader._Enabled) {
+          ctx->ATIFragmentShader._Enabled ||
+          NEED_SECONDARY_COLOR(ctx) ||
+          swrast->_FogEnabled) {
          /* 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;
@@ -1072,6 +1063,7 @@ _swrast_choose_triangle( GLcontext *ctx )
              && (format == MESA_FORMAT_RGB || format == MESA_FORMAT_RGBA)
              && minFilter == magFilter
              && ctx->Light.Model.ColorControl == GL_SINGLE_COLOR
+             && !swrast->_FogEnabled
              && ctx->Texture.Unit[0].EnvMode != GL_COMBINE_EXT) {
            if (ctx->Hint.PerspectiveCorrection==GL_FASTEST) {
               if (minFilter == GL_NEAREST
@@ -1091,7 +1083,7 @@ _swrast_choose_triangle( GLcontext *ctx )
                  }
               }
               else {
-#if (CHAN_BITS == 16 || CHAN_BITS == 32)
+#if CHAN_BITS != 8
                   USE(general_triangle);
 #else
                   USE(affine_textured_triangle);
@@ -1099,7 +1091,7 @@ _swrast_choose_triangle( GLcontext *ctx )
               }
            }
            else {
-#if (CHAN_BITS == 16 || CHAN_BITS == 32)
+#if CHAN_BITS != 8
                USE(general_triangle);
 #else
                USE(persp_textured_triangle);
@@ -1112,14 +1104,23 @@ _swrast_choose_triangle( GLcontext *ctx )
          }
       }
       else {
-         ASSERT(!ctx->Texture._EnabledCoordUnits);
+         ASSERT(!swrast->_FogEnabled);
+         ASSERT(!NEED_SECONDARY_COLOR(ctx));
         if (ctx->Light.ShadeModel==GL_SMOOTH) {
            /* smooth shaded, no texturing, stippled or some raster ops */
-            USE(smooth_rgba_triangle);
+#if CHAN_BITS != 8
+               USE(general_triangle);
+#else
+               USE(smooth_rgba_triangle);
+#endif
         }
         else {
            /* flat shaded, no texturing, stippled or some raster ops */
+#if CHAN_BITS != 8
+            USE(general_triangle);
+#else
             USE(flat_rgba_triangle);
+#endif
         }
       }
    }
index dcc3e95..2a90ffd 100644 (file)
  *
  * The following macros may be defined to indicate what auxillary information
  * must be interpolated across the triangle:
- *    INTERP_Z        - if defined, interpolate vertex Z values
- *    INTERP_W        - if defined, interpolate vertex W values
- *    INTERP_FOG      - if defined, interpolate fog values
- *    INTERP_RGB      - if defined, interpolate RGB values
- *    INTERP_ALPHA    - if defined, interpolate Alpha values (req's INTERP_RGB)
- *    INTERP_SPEC     - if defined, interpolate specular RGB values
+ *    INTERP_Z        - if defined, interpolate integer Z values
+ *    INTERP_RGB      - if defined, interpolate integer RGB values
+ *    INTERP_ALPHA    - if defined, interpolate integer Alpha values
  *    INTERP_INDEX    - if defined, interpolate color index values
  *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
- *                         (fast, simple 2-D texture mapping)
+ *                         (fast, simple 2-D texture mapping, without
+ *                         perspective correction)
  *    INTERP_ATTRIBS  - if defined, interpolate arbitrary attribs (texcoords,
- *                         varying vars, etc)
- *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
+ *                         varying vars, etc)  This also causes W to be
+ *                         computed for perspective correction).
  *
  * When one can directly address pixels in the color buffer the following
  * macros can be defined and used to compute pixel addresses during
  *                          Y==0 at bottom of screen and increases upward.
  *
  * Similarly, for direct depth buffer access, this type is used for depth
- * buffer addressing:
+ * buffer addressing (see zRow):
  *    DEPTH_TYPE          - either GLushort or GLuint
  *
  * Optionally, one may provide one-time setup code per triangle:
  *    SETUP_CODE    - code which is to be executed once per triangle
- *    CLEANUP_CODE    - code to execute at end of triangle
  *
  * The following macro MUST be defined:
  *    RENDER_SPAN(span) - code to write a span of pixels.
  * SUB_PIXEL_BITS.
  */
 
-/*
- * ColorTemp is used for intermediate color values.
- */
-#if CHAN_TYPE == GL_FLOAT
-#define ColorTemp GLfloat
-#else
-#define ColorTemp GLint  /* same as GLfixed */
-#endif
-
-
-/*
- * Walk triangle edges with GLfixed or GLdouble
- */
-#if TRIANGLE_WALK_DOUBLE
-#define GLinterp        GLdouble
-#define InterpToInt(X)  ((GLint) (X))
-#define INTERP_ONE      1.0
-#else
-#define GLinterp        GLfixed
-#define InterpToInt(X)  FixedToInt(X)
-#define INTERP_ONE      FIXED_ONE
-#endif
-
 
 /*
  * Some code we unfortunately need to prevent negative interpolated colors.
@@ -141,15 +115,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 {
    typedef struct {
       const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
-#if TRIANGLE_WALK_DOUBLE
-      GLdouble dx;     /* X(v1) - X(v0) */
-      GLdouble dy;     /* Y(v1) - Y(v0) */
-      GLdouble dxdy;   /* dx/dy */
-      GLdouble adjy;   /* adjust from v[0]->fy to fsy, scaled */
-      GLdouble fsx;    /* first sample point x coord */
-      GLdouble fsy;
-      GLdouble fx0;    /*X of lower endpoint */
-#else
       GLfloat dx;      /* X(v1) - X(v0) */
       GLfloat dy;      /* Y(v1) - Y(v0) */
       GLfloat dxdy;    /* dx/dy */
@@ -158,7 +123,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
       GLfixed fsx;     /* first sample point x coord */
       GLfixed fsy;
       GLfixed fx0;     /* fixed pt X of lower endpoint */
-#endif
       GLint lines;     /* number of lines to be sampled on this edge */
    } EdgeT;
 
@@ -173,10 +137,8 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
    GLfloat oneOverArea;
    const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
    GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign;
-#if !TRIANGLE_WALK_DOUBLE
    const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */
-#endif
-   GLinterp vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
+   GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
 
    SWspan span;
 
@@ -191,28 +153,27 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
    /*
    printf("%s()\n", __FUNCTION__);
-   printf("  %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
-   printf("  %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
-   printf("  %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
-   */
-   /*
-   ASSERT(v0->win[2] >= 0.0);
-   ASSERT(v1->win[2] >= 0.0);
-   ASSERT(v2->win[2] >= 0.0);
+   printf("  %g, %g, %g\n",
+          v0->attrib[FRAG_ATTRIB_WPOS][0],
+          v0->attrib[FRAG_ATTRIB_WPOS][1],
+          v0->attrib[FRAG_ATTRIB_WPOS][2]);
+   printf("  %g, %g, %g\n",
+          v1->attrib[FRAG_ATTRIB_WPOS][0],
+          v1->attrib[FRAG_ATTRIB_WPOS][1],
+          v1->attrib[FRAG_ATTRIB_WPOS][2]);
+   printf("  %g, %g, %g\n",
+          v2->attrib[FRAG_ATTRIB_WPOS][0],
+          v2->attrib[FRAG_ATTRIB_WPOS][1],
+          v2->attrib[FRAG_ATTRIB_WPOS][2]);
    */
+
    /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
     * And find the order of the 3 vertices along the Y axis.
     */
    {
-#if TRIANGLE_WALK_DOUBLE
-      const GLdouble fy0 = v0->win[1] - 0.5;
-      const GLdouble fy1 = v1->win[1] - 0.5;
-      const GLdouble fy2 = v2->win[1] - 0.5;
-#else
-      const GLfixed fy0 = FloatToFixed(v0->win[1] - 0.5F) & snapMask;
-      const GLfixed fy1 = FloatToFixed(v1->win[1] - 0.5F) & snapMask;
-      const GLfixed fy2 = FloatToFixed(v2->win[1] - 0.5F) & snapMask;
-#endif
+      const GLfixed fy0 = FloatToFixed(v0->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask;
+      const GLfixed fy1 = FloatToFixed(v1->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask;
+      const GLfixed fy2 = FloatToFixed(v2->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask;
       if (fy0 <= fy1) {
          if (fy1 <= fy2) {
             /* y0 <= y1 <= y2 */
@@ -252,15 +213,9 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
       }
 
       /* fixed point X coords */
-#if TRIANGLE_WALK_DOUBLE
-      vMin_fx = vMin->win[0] + 0.5;
-      vMid_fx = vMid->win[0] + 0.5;
-      vMax_fx = vMax->win[0] + 0.5;
-#else
-      vMin_fx = FloatToFixed(vMin->win[0] + 0.5F) & snapMask;
-      vMid_fx = FloatToFixed(vMid->win[0] + 0.5F) & snapMask;
-      vMax_fx = FloatToFixed(vMax->win[0] + 0.5F) & snapMask;
-#endif
+      vMin_fx = FloatToFixed(vMin->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask;
+      vMid_fx = FloatToFixed(vMid->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask;
+      vMax_fx = FloatToFixed(vMax->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask;
    }
 
    /* vertex/edge relationship */
@@ -269,29 +224,16 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
    eBot.v0 = vMin;   eBot.v1 = vMid;
 
    /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
-#if TRIANGLE_WALK_DOUBLE
-   eMaj.dx = vMax_fx - vMin_fx;
-   eMaj.dy = vMax_fy - vMin_fy;
-   eTop.dx = vMax_fx - vMid_fx;
-   eTop.dy = vMax_fy - vMid_fy;
-   eBot.dx = vMid_fx - vMin_fx;
-   eBot.dy = vMid_fy - vMin_fy;
-#else
    eMaj.dx = FixedToFloat(vMax_fx - vMin_fx);
    eMaj.dy = FixedToFloat(vMax_fy - vMin_fy);
    eTop.dx = FixedToFloat(vMax_fx - vMid_fx);
    eTop.dy = FixedToFloat(vMax_fy - vMid_fy);
    eBot.dx = FixedToFloat(vMid_fx - vMin_fx);
    eBot.dy = FixedToFloat(vMid_fy - vMin_fy);
-#endif
 
    /* compute area, oneOverArea and perform backface culling */
    {
-#if TRIANGLE_WALK_DOUBLE
-      const GLdouble area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
-#else
       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
-#endif
       /* Do backface culling */
       if (area * bf < 0.0)
          return;
@@ -307,70 +249,37 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
    /* Edge setup.  For a triangle strip these could be reused... */
    {
-#if TRIANGLE_WALK_DOUBLE
-      eMaj.fsy = CEILF(vMin_fy);
-      eMaj.lines = (GLint) CEILF(vMax_fy - eMaj.fsy);
-#else
       eMaj.fsy = FixedCeil(vMin_fy);
       eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy));
-#endif
       if (eMaj.lines > 0) {
          eMaj.dxdy = eMaj.dx / eMaj.dy;
-#if TRIANGLE_WALK_DOUBLE
-         eMaj.adjy = (eMaj.fsy - vMin_fy) * FIXED_SCALE;  /* SCALED! */
-         eMaj.fx0 = vMin_fx;
-         eMaj.fsx = eMaj.fx0 + (eMaj.adjy * eMaj.dxdy) / (GLdouble) FIXED_SCALE;
-#else
          eMaj.fdxdy = SignedFloatToFixed(eMaj.dxdy);
          eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
          eMaj.fx0 = vMin_fx;
          eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * eMaj.dxdy);
-#endif
       }
       else {
          return;  /*CULLED*/
       }
 
-#if TRIANGLE_WALK_DOUBLE
-      eTop.fsy = CEILF(vMid_fy);
-      eTop.lines = (GLint) CEILF(vMax_fy - eTop.fsy);
-#else
       eTop.fsy = FixedCeil(vMid_fy);
       eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy));
-#endif
       if (eTop.lines > 0) {
          eTop.dxdy = eTop.dx / eTop.dy;
-#if TRIANGLE_WALK_DOUBLE
-         eTop.adjy = (eTop.fsy - vMid_fy) * FIXED_SCALE; /* SCALED! */
-         eTop.fx0 = vMid_fx;
-         eTop.fsx = eTop.fx0 + (eTop.adjy * eTop.dxdy) / (GLdouble) FIXED_SCALE;
-#else
          eTop.fdxdy = SignedFloatToFixed(eTop.dxdy);
          eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
          eTop.fx0 = vMid_fx;
          eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * eTop.dxdy);
-#endif
       }
 
-#if TRIANGLE_WALK_DOUBLE
-      eBot.fsy = CEILF(vMin_fy);
-      eBot.lines = (GLint) CEILF(vMid_fy - eBot.fsy);
-#else
       eBot.fsy = FixedCeil(vMin_fy);
       eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy));
-#endif
       if (eBot.lines > 0) {
          eBot.dxdy = eBot.dx / eBot.dy;
-#if TRIANGLE_WALK_DOUBLE
-         eBot.adjy = (eBot.fsy - vMin_fy) * FIXED_SCALE;  /* SCALED! */
-         eBot.fx0 = vMin_fx;
-         eBot.fsx = eBot.fx0 + (eBot.adjy * eBot.dxdy) / (GLdouble) FIXED_SCALE;
-#else
          eBot.fdxdy = SignedFloatToFixed(eBot.dxdy);
          eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
          eBot.fx0 = vMin_fx;
          eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * eBot.dxdy);
-#endif
       }
    }
 
@@ -428,10 +337,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_Z
       span.interpMask |= SPAN_Z;
       {
-         GLfloat eMaj_dz = vMax->win[2] - vMin->win[2];
-         GLfloat eBot_dz = vMid->win[2] - vMin->win[2];
+         GLfloat eMaj_dz = vMax->attrib[FRAG_ATTRIB_WPOS][2] - vMin->attrib[FRAG_ATTRIB_WPOS][2];
+         GLfloat eBot_dz = vMid->attrib[FRAG_ATTRIB_WPOS][2] - vMin->attrib[FRAG_ATTRIB_WPOS][2];
          span.attrStepX[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
-         if (span.attrStepX[FRAG_ATTRIB_WPOS][2] > maxDepth || span.attrStepX[FRAG_ATTRIB_WPOS][2] < -maxDepth) {
+         if (span.attrStepX[FRAG_ATTRIB_WPOS][2] > maxDepth ||
+             span.attrStepX[FRAG_ATTRIB_WPOS][2] < -maxDepth) {
             /* probably a sliver triangle */
             span.attrStepX[FRAG_ATTRIB_WPOS][2] = 0.0;
             span.attrStepY[FRAG_ATTRIB_WPOS][2] = 0.0;
@@ -445,42 +355,18 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
             span.zStep = (GLint) span.attrStepX[FRAG_ATTRIB_WPOS][2];
       }
 #endif
-#ifdef INTERP_W
-      span.interpMask |= SPAN_W;
-      {
-         const GLfloat eMaj_dw = vMax->win[3] - vMin->win[3];
-         const GLfloat eBot_dw = vMid->win[3] - vMin->win[3];
-         span.attrStepX[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw);
-         span.attrStepY[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx);
-      }
-#endif
-#ifdef INTERP_FOG
-      span.interpMask |= SPAN_FOG;
-      {
-#  ifdef INTERP_W
-         const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3];
-         const GLfloat eMaj_dfog = vMax->attrib[FRAG_ATTRIB_FOGC][0] * wMax - vMin->attrib[FRAG_ATTRIB_FOGC][0] * wMin;
-         const GLfloat eBot_dfog = vMid->attrib[FRAG_ATTRIB_FOGC][0] * wMid - vMin->attrib[FRAG_ATTRIB_FOGC][0] * wMin;
-#  else
-         const GLfloat eMaj_dfog = vMax->attrib[FRAG_ATTRIB_FOGC][0] - vMin->attrib[FRAG_ATTRIB_FOGC][0];
-         const GLfloat eBot_dfog = vMid->attrib[FRAG_ATTRIB_FOGC][0] - vMin->attrib[FRAG_ATTRIB_FOGC][0];
-#  endif
-         span.attrStepX[FRAG_ATTRIB_FOGC][0] = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
-         span.attrStepY[FRAG_ATTRIB_FOGC][0] = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
-      }
-#endif
 #ifdef INTERP_RGB
       span.interpMask |= SPAN_RGBA;
       if (ctx->Light.ShadeModel == GL_SMOOTH) {
-         GLfloat eMaj_dr = (GLfloat) ((ColorTemp) vMax->color[RCOMP] - (ColorTemp) vMin->color[RCOMP]);
-         GLfloat eBot_dr = (GLfloat) ((ColorTemp) vMid->color[RCOMP] - (ColorTemp) vMin->color[RCOMP]);
-         GLfloat eMaj_dg = (GLfloat) ((ColorTemp) vMax->color[GCOMP] - (ColorTemp) vMin->color[GCOMP]);
-         GLfloat eBot_dg = (GLfloat) ((ColorTemp) vMid->color[GCOMP] - (ColorTemp) vMin->color[GCOMP]);
-         GLfloat eMaj_db = (GLfloat) ((ColorTemp) vMax->color[BCOMP] - (ColorTemp) vMin->color[BCOMP]);
-         GLfloat eBot_db = (GLfloat) ((ColorTemp) vMid->color[BCOMP] - (ColorTemp) vMin->color[BCOMP]);
+         GLfloat eMaj_dr = (GLfloat) (vMax->color[RCOMP] - vMin->color[RCOMP]);
+         GLfloat eBot_dr = (GLfloat) (vMid->color[RCOMP] - vMin->color[RCOMP]);
+         GLfloat eMaj_dg = (GLfloat) (vMax->color[GCOMP] - vMin->color[GCOMP]);
+         GLfloat eBot_dg = (GLfloat) (vMid->color[GCOMP] - vMin->color[GCOMP]);
+         GLfloat eMaj_db = (GLfloat) (vMax->color[BCOMP] - vMin->color[BCOMP]);
+         GLfloat eBot_db = (GLfloat) (vMid->color[BCOMP] - vMin->color[BCOMP]);
 #  ifdef INTERP_ALPHA
-         GLfloat eMaj_da = (GLfloat) ((ColorTemp) vMax->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]);
-         GLfloat eBot_da = (GLfloat) ((ColorTemp) vMid->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]);
+         GLfloat eMaj_da = (GLfloat) (vMax->color[ACOMP] - vMin->color[ACOMP]);
+         GLfloat eBot_da = (GLfloat) (vMid->color[ACOMP] - vMin->color[ACOMP]);
 #  endif
          span.attrStepX[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
          span.attrStepY[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
@@ -488,23 +374,13 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
          span.attrStepY[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
          span.attrStepX[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
          span.attrStepY[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
-#  if CHAN_TYPE == GL_FLOAT
-         span.redStep   = span.attrStepX[FRAG_ATTRIB_COL0][0];
-         span.greenStep = span.attrStepX[FRAG_ATTRIB_COL0][1];
-         span.blueStep  = span.attrStepX[FRAG_ATTRIB_COL0][2];
-#  else
          span.redStep   = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][0]);
          span.greenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][1]);
          span.blueStep  = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][2]);
-#  endif /* GL_FLOAT */
 #  ifdef INTERP_ALPHA
          span.attrStepX[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
          span.attrStepY[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
-#    if CHAN_TYPE == GL_FLOAT
-         span.alphaStep = span.attrStepX[FRAG_ATTRIB_COL0][3];
-#    else
          span.alphaStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3]);
-#    endif /* GL_FLOAT */
 #  endif /* INTERP_ALPHA */
       }
       else {
@@ -513,70 +389,20 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
          span.attrStepX[FRAG_ATTRIB_COL0][0] = span.attrStepY[FRAG_ATTRIB_COL0][0] = 0.0F;
          span.attrStepX[FRAG_ATTRIB_COL0][1] = span.attrStepY[FRAG_ATTRIB_COL0][1] = 0.0F;
          span.attrStepX[FRAG_ATTRIB_COL0][2] = span.attrStepY[FRAG_ATTRIB_COL0][2] = 0.0F;
-#    if CHAN_TYPE == GL_FLOAT
-        span.redStep   = 0.0F;
-        span.greenStep = 0.0F;
-        span.blueStep  = 0.0F;
-#    else
         span.redStep   = 0;
         span.greenStep = 0;
         span.blueStep  = 0;
-#    endif /* GL_FLOAT */
 #  ifdef INTERP_ALPHA
-         span.attrStepX[FRAG_ATTRIB_COL0][3] = span.attrStepY[FRAG_ATTRIB_COL0][3] = 0.0F;
-#    if CHAN_TYPE == GL_FLOAT
-        span.alphaStep = 0.0F;
-#    else
+         span.attrStepX[FRAG_ATTRIB_COL0][3] = span.attrStepX[FRAG_ATTRIB_COL0][3] = 0.0F;
         span.alphaStep = 0;
-#    endif /* GL_FLOAT */
 #  endif
       }
 #endif /* INTERP_RGB */
-#ifdef INTERP_SPEC
-      span.interpMask |= SPAN_SPEC;
-      if (ctx->Light.ShadeModel == GL_SMOOTH) {
-         GLfloat eMaj_dsr = (GLfloat) ((ColorTemp) vMax->specular[RCOMP] - (ColorTemp) vMin->specular[RCOMP]);
-         GLfloat eBot_dsr = (GLfloat) ((ColorTemp) vMid->specular[RCOMP] - (ColorTemp) vMin->specular[RCOMP]);
-         GLfloat eMaj_dsg = (GLfloat) ((ColorTemp) vMax->specular[GCOMP] - (ColorTemp) vMin->specular[GCOMP]);
-         GLfloat eBot_dsg = (GLfloat) ((ColorTemp) vMid->specular[GCOMP] - (ColorTemp) vMin->specular[GCOMP]);
-         GLfloat eMaj_dsb = (GLfloat) ((ColorTemp) vMax->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]);
-         GLfloat eBot_dsb = (GLfloat) ((ColorTemp) vMid->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]);
-         span.attrStepX[FRAG_ATTRIB_COL1][0] = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr);
-         span.attrStepY[FRAG_ATTRIB_COL1][0] = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx);
-         span.attrStepX[FRAG_ATTRIB_COL1][1] = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg);
-         span.attrStepY[FRAG_ATTRIB_COL1][1] = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx);
-         span.attrStepX[FRAG_ATTRIB_COL1][2] = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb);
-         span.attrStepY[FRAG_ATTRIB_COL1][2] = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx);
-#  if CHAN_TYPE == GL_FLOAT
-         span.specRedStep   = span.attrStepX[FRAG_ATTRIB_COL1][0];
-         span.specGreenStep = span.attrStepX[FRAG_ATTRIB_COL1][1];
-         span.specBlueStep  = span.attrStepX[FRAG_ATTRIB_COL1][2];
-#  else
-         span.specRedStep   = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][0]);
-         span.specGreenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][1]);
-         span.specBlueStep  = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][2]);
-#  endif
-      }
-      else {
-         span.attrStepX[FRAG_ATTRIB_COL1][0] = span.attrStepY[FRAG_ATTRIB_COL1][0] = 0.0F;
-         span.attrStepX[FRAG_ATTRIB_COL1][1] = span.attrStepY[FRAG_ATTRIB_COL1][1] = 0.0F;
-         span.attrStepX[FRAG_ATTRIB_COL1][2] = span.attrStepY[FRAG_ATTRIB_COL1][2] = 0.0F;
-#  if CHAN_TYPE == GL_FLOAT
-        span.specRedStep   = 0.0F;
-        span.specGreenStep = 0.0F;
-        span.specBlueStep  = 0.0F;
-#  else
-        span.specRedStep   = 0;
-        span.specGreenStep = 0;
-        span.specBlueStep  = 0;
-#  endif
-      }
-#endif /* INTERP_SPEC */
 #ifdef INTERP_INDEX
       span.interpMask |= SPAN_INDEX;
       if (ctx->Light.ShadeModel == GL_SMOOTH) {
-         GLfloat eMaj_di = vMax->index - vMin->index;
-         GLfloat eBot_di = vMid->index - vMin->index;
+         GLfloat eMaj_di = vMax->attrib[FRAG_ATTRIB_CI][0] - vMin->attrib[FRAG_ATTRIB_CI][0];
+         GLfloat eBot_di = vMid->attrib[FRAG_ATTRIB_CI][0] - vMin->attrib[FRAG_ATTRIB_CI][0];
          didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di);
          didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx);
          span.indexStep = SignedFloatToFixed(didx);
@@ -588,7 +414,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
       }
 #endif
 #ifdef INTERP_INT_TEX
-      span.interpMask |= SPAN_INT_TEXTURE;
       {
          GLfloat eMaj_ds = (vMax->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE;
          GLfloat eBot_ds = (vMid->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE;
@@ -603,27 +428,31 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
       }
 #endif
 #ifdef INTERP_ATTRIBS
-      span.interpMask |= (SPAN_TEXTURE | SPAN_VARYING);
       {
-         /* win[3] is 1/W */
-         const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3];
+         /* attrib[FRAG_ATTRIB_WPOS][3] is 1/W */
+         const GLfloat wMax = vMax->attrib[FRAG_ATTRIB_WPOS][3];
+         const GLfloat wMin = vMin->attrib[FRAG_ATTRIB_WPOS][3];
+         const GLfloat wMid = vMid->attrib[FRAG_ATTRIB_WPOS][3];
+         {
+            const GLfloat eMaj_dw = wMax - wMin;
+            const GLfloat eBot_dw = wMid - wMin;
+            span.attrStepX[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw);
+            span.attrStepY[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx);
+         }
          ATTRIB_LOOP_BEGIN
-            GLfloat eMaj_ds = vMax->attrib[attr][0] * wMax - vMin->attrib[attr][0] * wMin;
-            GLfloat eBot_ds = vMid->attrib[attr][0] * wMid - vMin->attrib[attr][0] * wMin;
-            GLfloat eMaj_dt = vMax->attrib[attr][1] * wMax - vMin->attrib[attr][1] * wMin;
-            GLfloat eBot_dt = vMid->attrib[attr][1] * wMid - vMin->attrib[attr][1] * wMin;
-            GLfloat eMaj_du = vMax->attrib[attr][2] * wMax - vMin->attrib[attr][2] * wMin;
-            GLfloat eBot_du = vMid->attrib[attr][2] * wMid - vMin->attrib[attr][2] * wMin;
-            GLfloat eMaj_dv = vMax->attrib[attr][3] * wMax - vMin->attrib[attr][3] * wMin;
-            GLfloat eBot_dv = vMid->attrib[attr][3] * wMid - vMin->attrib[attr][3] * wMin;
-            span.attrStepX[attr][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
-            span.attrStepY[attr][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
-            span.attrStepX[attr][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
-            span.attrStepY[attr][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
-            span.attrStepX[attr][2] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
-            span.attrStepY[attr][2] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
-            span.attrStepX[attr][3] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
-            span.attrStepY[attr][3] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
+            if (swrast->_InterpMode[attr] == GL_FLAT) {
+               ASSIGN_4V(span.attrStepX[attr], 0.0, 0.0, 0.0, 0.0);
+               ASSIGN_4V(span.attrStepY[attr], 0.0, 0.0, 0.0, 0.0);
+            }
+            else {
+               GLuint c;
+               for (c = 0; c < 4; c++) {
+                  GLfloat eMaj_da = vMax->attrib[attr][c] * wMax - vMin->attrib[attr][c] * wMin;
+                  GLfloat eBot_da = vMid->attrib[attr][c] * wMid - vMin->attrib[attr][c] * wMin;
+                  span.attrStepX[attr][c] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
+                  span.attrStepY[attr][c] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
+               }
+            }
          ATTRIB_LOOP_END
       }
 #endif
@@ -677,9 +506,9 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
       {
          GLint subTriangle;
-         GLinterp fxLeftEdge = 0, fxRightEdge = 0;
-         GLinterp fdxLeftEdge = 0, fdxRightEdge = 0;
-         GLinterp fError = 0, fdError = 0;
+         GLfixed fxLeftEdge = 0, fxRightEdge = 0;
+         GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
+         GLfixed fError = 0, fdError = 0;
 #ifdef PIXEL_ADDRESS
          PIXEL_TYPE *pRow = NULL;
          GLint dPRowOuter = 0, dPRowInner;  /* offset in bytes */
@@ -694,24 +523,13 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
          GLuint zLeft = 0;
          GLfixed fdzOuter = 0, fdzInner;
 #endif
-#ifdef INTERP_W
-         GLfloat wLeft = 0, dwOuter = 0, dwInner;
-#endif
-#ifdef INTERP_FOG
-         GLfloat fogLeft = 0, dfogOuter = 0, dfogInner;
-#endif
 #ifdef INTERP_RGB
-         ColorTemp rLeft = 0, fdrOuter = 0, fdrInner;
-         ColorTemp gLeft = 0, fdgOuter = 0, fdgInner;
-         ColorTemp bLeft = 0, fdbOuter = 0, fdbInner;
+         GLint rLeft = 0, fdrOuter = 0, fdrInner;
+         GLint gLeft = 0, fdgOuter = 0, fdgInner;
+         GLint bLeft = 0, fdbOuter = 0, fdbInner;
 #endif
 #ifdef INTERP_ALPHA
-         ColorTemp aLeft = 0, fdaOuter = 0, fdaInner;
-#endif
-#ifdef INTERP_SPEC
-         ColorTemp srLeft=0, dsrOuter=0, dsrInner;
-         ColorTemp sgLeft=0, dsgOuter=0, dsgInner;
-         ColorTemp sbLeft=0, dsbOuter=0, dsbInner;
+         GLint aLeft = 0, fdaOuter = 0, fdaInner;
 #endif
 #ifdef INTERP_INDEX
          GLfixed iLeft=0, diOuter=0, diInner;
@@ -721,14 +539,9 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
          GLfixed tLeft=0, dtOuter=0, dtInner;
 #endif
 #ifdef INTERP_ATTRIBS
-         GLfloat sLeft[FRAG_ATTRIB_MAX];
-         GLfloat tLeft[FRAG_ATTRIB_MAX];
-         GLfloat uLeft[FRAG_ATTRIB_MAX];
-         GLfloat vLeft[FRAG_ATTRIB_MAX];
-         GLfloat dsOuter[FRAG_ATTRIB_MAX], dsInner[FRAG_ATTRIB_MAX];
-         GLfloat dtOuter[FRAG_ATTRIB_MAX], dtInner[FRAG_ATTRIB_MAX];
-         GLfloat duOuter[FRAG_ATTRIB_MAX], duInner[FRAG_ATTRIB_MAX];
-         GLfloat dvOuter[FRAG_ATTRIB_MAX], dvInner[FRAG_ATTRIB_MAX];
+         GLfloat wLeft = 0, dwOuter = 0, dwInner;
+         GLfloat attrLeft[FRAG_ATTRIB_MAX][4];
+         GLfloat daOuter[FRAG_ATTRIB_MAX][4], daInner[FRAG_ATTRIB_MAX][4];
 #endif
 
          for (subTriangle=0; subTriangle<=1; subTriangle++) {
@@ -775,30 +588,12 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
             if (setupLeft && eLeft->lines > 0) {
                const SWvertex *vLower = eLeft->v0;
-#if TRIANGLE_WALK_DOUBLE
-               const GLdouble fsy = eLeft->fsy;
-               const GLdouble fsx = eLeft->fsx;
-               const GLdouble fx = CEILF(fsx);
-               const GLdouble adjx = (fx - eLeft->fx0) * FIXED_SCALE;  /* SCALED! */
-#else
                const GLfixed fsy = eLeft->fsy;
                const GLfixed fsx = eLeft->fsx;  /* no fractional part */
                const GLfixed fx = FixedCeil(fsx);  /* no fractional part */
-               const GLfixed adjx = (GLinterp) (fx - eLeft->fx0); /* SCALED! */
-#endif
-               const GLinterp adjy = (GLinterp) eLeft->adjy;      /* SCALED! */
+               const GLfixed adjx = (GLfixed) (fx - eLeft->fx0); /* SCALED! */
+               const GLfixed adjy = (GLfixed) eLeft->adjy;      /* SCALED! */
                GLint idxOuter;
-#if TRIANGLE_WALK_DOUBLE
-               GLdouble dxOuter;
-
-               fError = fx - fsx - 1.0;
-               fxLeftEdge = fsx;
-               fdxLeftEdge = eLeft->dxdy;
-               dxOuter = FLOORF(fdxLeftEdge);
-               fdError = dxOuter - fdxLeftEdge + 1.0;
-               idxOuter = (GLint) dxOuter;
-               span.y = (GLint) fsy;
-#else
                GLfloat dxOuter;
                GLfixed fdxOuter;
 
@@ -810,7 +605,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
                idxOuter = FixedToInt(fdxOuter);
                dxOuter = (GLfloat) idxOuter;
                span.y = FixedToInt(fsy);
-#endif
 
                /* silence warnings on some compilers */
                (void) dxOuter;
@@ -820,7 +614,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
 #ifdef PIXEL_ADDRESS
                {
-                  pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(InterpToInt(fxLeftEdge), span.y);
+                  pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(FixedToInt(fxLeftEdge), span.y);
                   dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE);
                   /* negative because Y=0 at bottom and increases upward */
                }
@@ -837,7 +631,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
 #ifdef INTERP_Z
                {
-                  GLfloat z0 = vLower->win[2];
+                  GLfloat z0 = vLower->attrib[FRAG_ATTRIB_WPOS][2];
                   if (depthBits <= 16) {
                      /* interpolate fixed-pt values */
                      GLfloat tmp = (z0 * FIXED_SCALE
@@ -847,129 +641,71 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
                         zLeft = (GLfixed) tmp;
                      else
                         zLeft = MAX_GLUINT / 2;
-                     fdzOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
+                     fdzOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_WPOS][2] +
+                                                   dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
                   }
                   else {
                      /* interpolate depth values w/out scaling */
                      zLeft = (GLuint) (z0 + span.attrStepX[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjx)
                                           + span.attrStepY[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjy));
-                     fdzOuter = (GLint) (span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
+                     fdzOuter = (GLint) (span.attrStepY[FRAG_ATTRIB_WPOS][2] +
+                                         dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
                   }
 #  ifdef DEPTH_TYPE
                   zRow = (DEPTH_TYPE *)
-                    zrb->GetPointer(ctx, zrb, InterpToInt(fxLeftEdge), span.y);
+                    zrb->GetPointer(ctx, zrb, FixedToInt(fxLeftEdge), span.y);
                   dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE);
 #  endif
                }
 #endif
-#ifdef INTERP_W
-               wLeft = vLower->win[3] + (span.attrStepX[FRAG_ATTRIB_WPOS][3] * adjx + span.attrStepY[FRAG_ATTRIB_WPOS][3] * adjy) * (1.0F/FIXED_SCALE);
-               dwOuter = span.attrStepY[FRAG_ATTRIB_WPOS][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][3];
-#endif
-#ifdef INTERP_FOG
-#  ifdef INTERP_W
-               fogLeft = vLower->attrib[FRAG_ATTRIB_FOGC][0] * vLower->win[3] + (span.attrStepX[FRAG_ATTRIB_FOGC][0] * adjx + span.attrStepY[FRAG_ATTRIB_FOGC][0] * adjy) * (1.0F/FIXED_SCALE);
-#  else
-               fogLeft = vLower->attrib[FRAG_ATTRIB_FOGC][0] + (span.attrStepX[FRAG_ATTRIB_FOGC][0] * adjx + span.attrStepY[FRAG_ATTRIB_FOGC][0] * adjy) * (1.0F/FIXED_SCALE);
-#  endif
-               dfogOuter = span.attrStepY[FRAG_ATTRIB_FOGC][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_FOGC][0];
-#endif
 #ifdef INTERP_RGB
                if (ctx->Light.ShadeModel == GL_SMOOTH) {
-#  if CHAN_TYPE == GL_FLOAT
-                  rLeft = vLower->color[RCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) * (1.0F / FIXED_SCALE);
-                  gLeft = vLower->color[GCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) * (1.0F / FIXED_SCALE);
-                  bLeft = vLower->color[BCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) * (1.0F / FIXED_SCALE);
-                  fdrOuter = span.attrStepY[FRAG_ATTRIB_COL0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0];
-                  fdgOuter = span.attrStepY[FRAG_ATTRIB_COL0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1];
-                  fdbOuter = span.attrStepY[FRAG_ATTRIB_COL0][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2];
-#  else
-                  rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) + FIXED_HALF;
-                  gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) + FIXED_HALF;
-                  bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) + FIXED_HALF;
-                  fdrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0]);
-                  fdgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1]);
-                  fdbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2]);
-#  endif
+                  rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP])
+                                  + span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx
+                                  + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) + FIXED_HALF;
+                  gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP])
+                                  + span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx
+                                  + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) + FIXED_HALF;
+                  bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP])
+                                  + span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx
+                                  + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) + FIXED_HALF;
+                  fdrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][0]
+                                                + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0]);
+                  fdgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][1]
+                                                + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1]);
+                  fdbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][2]
+                                                + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2]);
 #  ifdef INTERP_ALPHA
-#    if CHAN_TYPE == GL_FLOAT
-                  aLeft = vLower->color[ACOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][3] * adjy) * (1.0F / FIXED_SCALE);
-                  fdaOuter = span.attrStepY[FRAG_ATTRIB_COL0][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3];
-#    else
-                  aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjy) + FIXED_HALF;
-                  fdaOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]);
-#    endif
+                  aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP])
+                                  + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx
+                                  + span.attrStepY[FRAG_ATTRIB_COL0][3] * adjy) + FIXED_HALF;
+                  fdaOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][3]
+                                                + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]);
 #  endif
                }
                else {
                   ASSERT(ctx->Light.ShadeModel == GL_FLAT);
-#  if CHAN_TYPE == GL_FLOAT
-                  rLeft = v2->color[RCOMP];
-                  gLeft = v2->color[GCOMP];
-                  bLeft = v2->color[BCOMP];
-                  fdrOuter = fdgOuter = fdbOuter = 0.0F;
-#  else
                   rLeft = ChanToFixed(v2->color[RCOMP]);
                   gLeft = ChanToFixed(v2->color[GCOMP]);
                   bLeft = ChanToFixed(v2->color[BCOMP]);
                   fdrOuter = fdgOuter = fdbOuter = 0;
-#  endif
 #  ifdef INTERP_ALPHA
-#    if CHAN_TYPE == GL_FLOAT
-                  aLeft = v2->color[ACOMP];
-                  fdaOuter = 0.0F;
-#    else
                   aLeft = ChanToFixed(v2->color[ACOMP]);
                   fdaOuter = 0;
-#    endif
 #  endif
                }
 #endif /* INTERP_RGB */
 
 
-#ifdef INTERP_SPEC
-               if (ctx->Light.ShadeModel == GL_SMOOTH) {
-#  if CHAN_TYPE == GL_FLOAT
-                  srLeft = vLower->specular[RCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][0] * adjy) * (1.0F / FIXED_SCALE);
-                  sgLeft = vLower->specular[GCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][1] * adjy) * (1.0F / FIXED_SCALE);
-                  sbLeft = vLower->specular[BCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][2] * adjy) * (1.0F / FIXED_SCALE);
-                  dsrOuter = span.attrStepY[FRAG_ATTRIB_COL1][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][0];
-                  dsgOuter = span.attrStepY[FRAG_ATTRIB_COL1][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][1];
-                  dsbOuter = span.attrStepY[FRAG_ATTRIB_COL1][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][2];
-#  else
-                  srLeft = (GLfixed) (ChanToFixed(vLower->specular[RCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][0] * adjy) + FIXED_HALF;
-                  sgLeft = (GLfixed) (ChanToFixed(vLower->specular[GCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][1] * adjy) + FIXED_HALF;
-                  sbLeft = (GLfixed) (ChanToFixed(vLower->specular[BCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][2] * adjy) + FIXED_HALF;
-                  dsrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][0]);
-                  dsgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][1]);
-                  dsbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][2]);
-#  endif
-               }
-               else {
-                  ASSERT(ctx->Light.ShadeModel == GL_FLAT);
-#if  CHAN_TYPE == GL_FLOAT
-                  srLeft = v2->specular[RCOMP];
-                  sgLeft = v2->specular[GCOMP];
-                  sbLeft = v2->specular[BCOMP];
-                  dsrOuter = dsgOuter = dsbOuter = 0.0F;
-#  else
-                  srLeft = ChanToFixed(v2->specular[RCOMP]);
-                  sgLeft = ChanToFixed(v2->specular[GCOMP]);
-                  sbLeft = ChanToFixed(v2->specular[BCOMP]);
-                  dsrOuter = dsgOuter = dsbOuter = 0;
-#  endif
-               }
-#endif
-
 #ifdef INTERP_INDEX
                if (ctx->Light.ShadeModel == GL_SMOOTH) {
-                  iLeft = (GLfixed)(vLower->index * FIXED_SCALE
+                  iLeft = (GLfixed)(vLower->attrib[FRAG_ATTRIB_CI][0] * FIXED_SCALE
                                  + didx * adjx + didy * adjy) + FIXED_HALF;
                   diOuter = SignedFloatToFixed(didy + dxOuter * didx);
                }
                else {
                   ASSERT(ctx->Light.ShadeModel == GL_FLAT);
-                  iLeft = FloatToFixed(v2->index);
+                  iLeft = FloatToFixed(v2->attrib[FRAG_ATTRIB_CI][0]);
                   diOuter = 0;
                }
 #endif
@@ -979,42 +715,50 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
                   s0 = vLower->attrib[FRAG_ATTRIB_TEX0][0] * S_SCALE;
                   sLeft = (GLfixed)(s0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][0] * adjx
                                  + span.attrStepY[FRAG_ATTRIB_TEX0][0] * adjy) + FIXED_HALF;
-                  dsOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][0]);
+                  dsOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][0]
+                                               + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][0]);
 
                   t0 = vLower->attrib[FRAG_ATTRIB_TEX0][1] * T_SCALE;
                   tLeft = (GLfixed)(t0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][1] * adjx
                                  + span.attrStepY[FRAG_ATTRIB_TEX0][1] * adjy) + FIXED_HALF;
-                  dtOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][1]);
+                  dtOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][1]
+                                               + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][1]);
                }
 #endif
 #ifdef INTERP_ATTRIBS
+               {
+                  const GLuint attr = FRAG_ATTRIB_WPOS;
+                  wLeft = vLower->attrib[FRAG_ATTRIB_WPOS][3]
+                        + (span.attrStepX[attr][3] * adjx
+                           + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE);
+                  dwOuter = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3];
+               }
                ATTRIB_LOOP_BEGIN
-                  const GLfloat invW = vLower->win[3];
-                  const GLfloat s0 = vLower->attrib[attr][0] * invW;
-                  const GLfloat t0 = vLower->attrib[attr][1] * invW;
-                  const GLfloat u0 = vLower->attrib[attr][2] * invW;
-                  const GLfloat v0 = vLower->attrib[attr][3] * invW;
-                  sLeft[attr] = s0 + (span.attrStepX[attr][0] * adjx + span.attrStepY[attr][0] * adjy) * (1.0F/FIXED_SCALE);
-                  tLeft[attr] = t0 + (span.attrStepX[attr][1] * adjx + span.attrStepY[attr][1] * adjy) * (1.0F/FIXED_SCALE);
-                  uLeft[attr] = u0 + (span.attrStepX[attr][2] * adjx + span.attrStepY[attr][2] * adjy) * (1.0F/FIXED_SCALE);
-                  vLeft[attr] = v0 + (span.attrStepX[attr][3] * adjx + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE);
-                  dsOuter[attr] = span.attrStepY[attr][0] + dxOuter * span.attrStepX[attr][0];
-                  dtOuter[attr] = span.attrStepY[attr][1] + dxOuter * span.attrStepX[attr][1];
-                  duOuter[attr] = span.attrStepY[attr][2] + dxOuter * span.attrStepX[attr][2];
-                  dvOuter[attr] = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3];
+                  const GLfloat invW = vLower->attrib[FRAG_ATTRIB_WPOS][3];
+                  if (swrast->_InterpMode[attr] == GL_FLAT) {
+                     GLuint c;
+                     for (c = 0; c < 4; c++) {
+                        attrLeft[attr][c] = v2->attrib[attr][c] * invW;
+                        daOuter[attr][c] = 0.0;
+                     }
+                  }
+                  else {
+                     GLuint c;
+                     for (c = 0; c < 4; c++) {
+                        const GLfloat a = vLower->attrib[attr][c] * invW;
+                        attrLeft[attr][c] = a + (  span.attrStepX[attr][c] * adjx
+                                                 + span.attrStepY[attr][c] * adjy) * (1.0F/FIXED_SCALE);
+                        daOuter[attr][c] = span.attrStepY[attr][c] + dxOuter * span.attrStepX[attr][c];
+                     }
+                  }
                ATTRIB_LOOP_END
 #endif
             } /*if setupLeft*/
 
 
             if (setupRight && eRight->lines>0) {
-#if TRIANGLE_WALK_DOUBLE
-               fxRightEdge = eRight->fsx;
-               fdxRightEdge = eRight->dxdy;
-#else
                fxRightEdge = eRight->fsx - FIXED_EPSILON;
                fdxRightEdge = eRight->fdxdy;
-#endif
             }
 
             if (lines==0) {
@@ -1032,12 +776,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #  endif
             fdzInner = fdzOuter + span.zStep;
 #endif
-#ifdef INTERP_W
-            dwInner = dwOuter + span.attrStepX[FRAG_ATTRIB_WPOS][3];
-#endif
-#ifdef INTERP_FOG
-            dfogInner = dfogOuter + span.attrStepX[FRAG_ATTRIB_FOGC][0];
-#endif
 #ifdef INTERP_RGB
             fdrInner = fdrOuter + span.redStep;
             fdgInner = fdgOuter + span.greenStep;
@@ -1046,11 +784,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_ALPHA
             fdaInner = fdaOuter + span.alphaStep;
 #endif
-#ifdef INTERP_SPEC
-            dsrInner = dsrOuter + span.specRedStep;
-            dsgInner = dsgOuter + span.specGreenStep;
-            dsbInner = dsbOuter + span.specBlueStep;
-#endif
 #ifdef INTERP_INDEX
             diInner = diOuter + span.indexStep;
 #endif
@@ -1059,19 +792,20 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
             dtInner = dtOuter + span.intTexStep[1];
 #endif
 #ifdef INTERP_ATTRIBS
+            dwInner = dwOuter + span.attrStepX[FRAG_ATTRIB_WPOS][3];
             ATTRIB_LOOP_BEGIN
-               dsInner[attr] = dsOuter[attr] + span.attrStepX[attr][0];
-               dtInner[attr] = dtOuter[attr] + span.attrStepX[attr][1];
-               duInner[attr] = duOuter[attr] + span.attrStepX[attr][2];
-               dvInner[attr] = dvOuter[attr] + span.attrStepX[attr][3];
+               GLuint c;
+               for (c = 0; c < 4; c++) {
+                  daInner[attr][c] = daOuter[attr][c] + span.attrStepX[attr][c];
+               }
             ATTRIB_LOOP_END
 #endif
 
             while (lines > 0) {
                /* initialize the span interpolants to the leftmost value */
                /* ff = fixed-pt fragment */
-               const GLint right = InterpToInt(fxRightEdge);
-               span.x = InterpToInt(fxLeftEdge);
+               const GLint right = FixedToInt(fxRightEdge);
+               span.x = FixedToInt(fxLeftEdge);
                if (right <= span.x)
                   span.end = 0;
                else
@@ -1080,12 +814,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_Z
                span.z = zLeft;
 #endif
-#ifdef INTERP_W
-               span.attrStart[FRAG_ATTRIB_WPOS][3] = wLeft;
-#endif
-#ifdef INTERP_FOG
-               span.attrStart[FRAG_ATTRIB_FOGC][0] = fogLeft;
-#endif
 #ifdef INTERP_RGB
                span.red = rLeft;
                span.green = gLeft;
@@ -1094,11 +822,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_ALPHA
                span.alpha = aLeft;
 #endif
-#ifdef INTERP_SPEC
-               span.specRed = srLeft;
-               span.specGreen = sgLeft;
-               span.specBlue = sbLeft;
-#endif
 #ifdef INTERP_INDEX
                span.index = iLeft;
 #endif
@@ -1108,11 +831,12 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #endif
 
 #ifdef INTERP_ATTRIBS
+               span.attrStart[FRAG_ATTRIB_WPOS][3] = wLeft;
                ATTRIB_LOOP_BEGIN
-                  span.attrStart[attr][0] = sLeft[attr];
-                  span.attrStart[attr][1] = tLeft[attr];
-                  span.attrStart[attr][2] = uLeft[attr];
-                  span.attrStart[attr][3] = vLeft[attr];
+                  GLuint c;
+                  for (c = 0; c < 4; c++) {
+                     span.attrStart[attr][c] = attrLeft[attr][c];
+                  }
                ATTRIB_LOOP_END
 #endif
 
@@ -1131,11 +855,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_ALPHA
                   CLAMP_INTERPOLANT(alpha, alphaStep, len);
 #endif
-#ifdef INTERP_SPEC
-                  CLAMP_INTERPOLANT(specRed, specRedStep, len);
-                  CLAMP_INTERPOLANT(specGreen, specGreenStep, len);
-                  CLAMP_INTERPOLANT(specBlue, specBlueStep, len);
-#endif
 #ifdef INTERP_INDEX
                   CLAMP_INTERPOLANT(index, indexStep, len);
 #endif
@@ -1158,7 +877,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 
                fError += fdError;
                if (fError >= 0) {
-                  fError -= INTERP_ONE;
+                  fError -= FIXED_ONE;
 
 #ifdef PIXEL_ADDRESS
                   pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter);
@@ -1169,12 +888,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #  endif
                   zLeft += fdzOuter;
 #endif
-#ifdef INTERP_W
-                  wLeft += dwOuter;
-#endif
-#ifdef INTERP_FOG
-                  fogLeft += dfogOuter;
-#endif
 #ifdef INTERP_RGB
                   rLeft += fdrOuter;
                   gLeft += fdgOuter;
@@ -1183,11 +896,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_ALPHA
                   aLeft += fdaOuter;
 #endif
-#ifdef INTERP_SPEC
-                  srLeft += dsrOuter;
-                  sgLeft += dsgOuter;
-                  sbLeft += dsbOuter;
-#endif
 #ifdef INTERP_INDEX
                   iLeft += diOuter;
 #endif
@@ -1196,11 +904,12 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
                   tLeft += dtOuter;
 #endif
 #ifdef INTERP_ATTRIBS
+                  wLeft += dwOuter;
                   ATTRIB_LOOP_BEGIN
-                     sLeft[attr] += dsOuter[attr];
-                     tLeft[attr] += dtOuter[attr];
-                     uLeft[attr] += duOuter[attr];
-                     vLeft[attr] += dvOuter[attr];
+                     GLuint c;
+                     for (c = 0; c < 4; c++) {
+                        attrLeft[attr][c] += daOuter[attr][c];
+                     }
                   ATTRIB_LOOP_END
 #endif
                }
@@ -1214,12 +923,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #  endif
                   zLeft += fdzInner;
 #endif
-#ifdef INTERP_W
-                  wLeft += dwInner;
-#endif
-#ifdef INTERP_FOG
-                  fogLeft += dfogInner;
-#endif
 #ifdef INTERP_RGB
                   rLeft += fdrInner;
                   gLeft += fdgInner;
@@ -1228,11 +931,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #ifdef INTERP_ALPHA
                   aLeft += fdaInner;
 #endif
-#ifdef INTERP_SPEC
-                  srLeft += dsrInner;
-                  sgLeft += dsgInner;
-                  sbLeft += dsbInner;
-#endif
 #ifdef INTERP_INDEX
                   iLeft += diInner;
 #endif
@@ -1241,11 +939,12 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
                   tLeft += dtInner;
 #endif
 #ifdef INTERP_ATTRIBS
+                  wLeft += dwInner;
                   ATTRIB_LOOP_BEGIN
-                     sLeft[attr] += dsInner[attr];
-                     tLeft[attr] += dtInner[attr];
-                     uLeft[attr] += duInner[attr];
-                     vLeft[attr] += dvInner[attr];
+                     GLuint c;
+                     for (c = 0; c < 4; c++) {
+                        attrLeft[attr][c] += daInner[attr][c];
+                     }
                   ATTRIB_LOOP_END
 #endif
                }
@@ -1254,14 +953,10 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
          } /* for subTriangle */
 
       }
-#ifdef CLEANUP_CODE
-      CLEANUP_CODE
-#endif
    }
 }
 
 #undef SETUP_CODE
-#undef CLEANUP_CODE
 #undef RENDER_SPAN
 
 #undef PIXEL_TYPE
@@ -1270,24 +965,15 @@ static void NAME(GLcontext *ctx, const SWvertex *v0,
 #undef DEPTH_TYPE
 
 #undef INTERP_Z
-#undef INTERP_W
-#undef INTERP_FOG
 #undef INTERP_RGB
 #undef INTERP_ALPHA
-#undef INTERP_SPEC
 #undef INTERP_INDEX
 #undef INTERP_INT_TEX
 #undef INTERP_ATTRIBS
-#undef TEX_UNIT_LOOP
-#undef VARYING_LOOP
 
 #undef S_SCALE
 #undef T_SCALE
 
 #undef FixedToDepth
-#undef ColorTemp
-#undef GLinterp
-#undef InterpToInt
-#undef INTERP_ONE
 
 #undef NAME
index 0908265..78fa137 100644 (file)
@@ -155,14 +155,11 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
    zoomed_arrays.ChanType = span->array->ChanType;
    /* XXX temporary */
 #if CHAN_TYPE == GL_UNSIGNED_BYTE
-   zoomed_arrays.rgba = zoomed_arrays.color.sz1.rgba;
-   zoomed_arrays.spec = zoomed_arrays.color.sz1.spec;
+   zoomed_arrays.rgba = zoomed_arrays.rgba8;
 #elif CHAN_TYPE == GL_UNSIGNED_SHORT
-   zoomed_arrays.rgba = zoomed_arrays.color.sz2.rgba;
-   zoomed_arrays.spec = zoomed_arrays.color.sz2.spec;
+   zoomed_arrays.rgba = zoomed_arrays.rgba16;
 #else
    zoomed_arrays.rgba = zoomed_arrays.attribs[FRAG_ATTRIB_COL0];
-   zoomed_arrays.spec = zoomed_arrays.attribs[FRAG_ATTRIB_COL1];
 #endif
 
 
@@ -219,7 +216,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
             GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
             ASSERT(j >= 0);
             ASSERT(j < (GLint) span->end);
-            COPY_4UBV(zoomed.array->color.sz1.rgba[i], rgba[j]);
+            COPY_4UBV(zoomed.array->rgba8[i], rgba[j]);
          }
       }
       else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) {
@@ -229,7 +226,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
             GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
             ASSERT(j >= 0);
             ASSERT(j < (GLint) span->end);
-            COPY_4V(zoomed.array->color.sz2.rgba[i], rgba[j]);
+            COPY_4V(zoomed.array->rgba16[i], rgba[j]);
          }
       }
       else {
@@ -251,10 +248,10 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
             GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
             ASSERT(j >= 0);
             ASSERT(j < (GLint) span->end);
-            zoomed.array->color.sz1.rgba[i][0] = rgb[j][0];
-            zoomed.array->color.sz1.rgba[i][1] = rgb[j][1];
-            zoomed.array->color.sz1.rgba[i][2] = rgb[j][2];
-            zoomed.array->color.sz1.rgba[i][3] = 0xff;
+            zoomed.array->rgba8[i][0] = rgb[j][0];
+            zoomed.array->rgba8[i][1] = rgb[j][1];
+            zoomed.array->rgba8[i][2] = rgb[j][2];
+            zoomed.array->rgba8[i][3] = 0xff;
          }
       }
       else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) {
@@ -264,10 +261,10 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
             GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
             ASSERT(j >= 0);
             ASSERT(j < (GLint) span->end);
-            zoomed.array->color.sz2.rgba[i][0] = rgb[j][0];
-            zoomed.array->color.sz2.rgba[i][1] = rgb[j][1];
-            zoomed.array->color.sz2.rgba[i][2] = rgb[j][2];
-            zoomed.array->color.sz2.rgba[i][3] = 0xffff;
+            zoomed.array->rgba16[i][0] = rgb[j][0];
+            zoomed.array->rgba16[i][1] = rgb[j][1];
+            zoomed.array->rgba16[i][2] = rgb[j][2];
+            zoomed.array->rgba16[i][3] = 0xffff;
          }
       }
       else {
@@ -314,8 +311,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
        * Also, clipping may change the span end value, so store it as well.
        */
       const GLint end = zoomed.end; /* save */
-      /* use specular color array for temp storage */
-      void *rgbaSave = zoomed.array->spec;
+      GLuint rgbaSave[MAX_WIDTH][4];
       const GLint pixelSize =
          (zoomed.array->ChanType == GL_UNSIGNED_BYTE) ? 4 * sizeof(GLubyte) :
          ((zoomed.array->ChanType == GL_UNSIGNED_SHORT) ? 4 * sizeof(GLushort)
@@ -334,7 +330,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
    }
    else if (format == GL_COLOR_INDEX) {
       /* use specular color array for temp storage */
-      GLuint *indexSave = (GLuint *) zoomed.array->spec;
+      GLuint *indexSave = (GLuint *) zoomed.array->attribs[FRAG_ATTRIB_FOGC];
       const GLint end = zoomed.end; /* save */
       if (y1 - y0 > 1) {
          MEMCPY(indexSave, zoomed.array->index, zoomed.end * sizeof(GLuint));
index 12264a1..d101a9e 100644 (file)
  * improve its usefulness as a fallback mechanism for hardware
  * drivers.
  *
+ * wpos = attr[FRAG_ATTRIB_WPOS] and MUST BE THE FIRST values in the
+ * vertex because of the tnl clipping code.
+
+ * wpos[0] and [1] are the screen-coords of SWvertex.
+ * wpos[2] is the z-buffer coord (if 16-bit Z buffer, in range [0,65535]).
+ * wpos[3] is 1/w where w is the clip-space W coord.  This is the value
+ * that clip{XYZ} were multiplied by to get ndc{XYZ}.
+ *
  * Full software drivers:
  *   - Register the rastersetup and triangle functions from
  *     utils/software_helper.
  *     primitives unaccelerated), hook in swrast_setup instead.
  */
 typedef struct {
-   /** win[0], win[1] are the screen-coords of SWvertex.
-    * win[2] is the z-buffer coord (if 16-bit Z buffer, in range [0,65535]).
-    * win[3] is 1/w where w is the clip-space W coord.  This is the value
-    * that clip{XYZ} were multiplied by to get ndc{XYZ}.
-    */
-   GLfloat win[4];
-   GLchan color[4];
-   GLchan specular[4];
-   GLfloat index;
+   GLfloat attrib[FRAG_ATTRIB_MAX][4];
+   GLchan color[4];   /** integer color */
    GLfloat pointSize;
-   GLfloat attrib[FRAG_ATTRIB_MAX][4]; /**< texcoords & varying, more to come */
 } SWvertex;
 
 
+#define FRAG_ATTRIB_CI FRAG_ATTRIB_COL0
+
+
 struct swrast_device_driver;
 
 
index 3f6d294..9f83fde 100644 (file)
@@ -120,16 +120,25 @@ setup_vertex_format(GLcontext *ctx)
 
       RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
 
-      EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, win );
-
-      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR0 ))
-         EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4CHAN_4F_RGBA, color );
+      EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, attrib[FRAG_ATTRIB_WPOS] );
+
+      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR0 )) {
+         if (ctx->FragmentProgram._Current
+             || ctx->ATIFragmentShader._Enabled
+             || CHAN_TYPE == GL_FLOAT)
+            EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4F, attrib[FRAG_ATTRIB_COL0]);
+         else
+            EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4CHAN_4F_RGBA, color );
+      }
 
-      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ))
-         EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4CHAN_4F_RGBA, specular);
+      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
+         EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4F, attrib[FRAG_ATTRIB_COL1]);
+      }
 
-      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR_INDEX ))
-         EMIT_ATTR( _TNL_ATTRIB_COLOR_INDEX, EMIT_1F, index );
+      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR_INDEX )) {
+         EMIT_ATTR( _TNL_ATTRIB_COLOR_INDEX, EMIT_1F,
+                    attrib[FRAG_ATTRIB_CI][0] );
+      }
 
       if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
          const GLint emit = ctx->FragmentProgram._Current ? EMIT_4F : EMIT_1F;
@@ -184,6 +193,10 @@ _swsetup_RenderStart( GLcontext *ctx )
       _swsetup_choose_trifuncs(ctx);
    }
 
+   if (swsetup->NewState & _NEW_PROGRAM) {
+      RENDERINPUTS_ZERO( swsetup->last_index_bitset );
+   }
+
    swsetup->NewState = 0;
 
    _swrast_render_start(ctx);
@@ -258,10 +271,10 @@ _swsetup_Translate( GLcontext *ctx, const void *vertex, SWvertex *dest )
 
    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_POS, tmp );
 
-   dest->win[0] = m[0]  * tmp[0] + m[12];
-   dest->win[1] = m[5]  * tmp[1] + m[13];
-   dest->win[2] = m[10] * tmp[2] + m[14];
-   dest->win[3] =         tmp[3];
+   dest->attrib[FRAG_ATTRIB_WPOS][0] = m[0]  * tmp[0] + m[12];
+   dest->attrib[FRAG_ATTRIB_WPOS][1] = m[5]  * tmp[1] + m[13];
+   dest->attrib[FRAG_ATTRIB_WPOS][2] = m[10] * tmp[2] + m[14];
+   dest->attrib[FRAG_ATTRIB_WPOS][3] =         tmp[3];
 
    /** XXX try to limit these loops someday */
    for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
@@ -276,13 +289,16 @@ _swsetup_Translate( GLcontext *ctx, const void *vertex, SWvertex *dest )
    UNCLAMPED_FLOAT_TO_RGBA_CHAN( dest->color, tmp );
 
    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR1, tmp );
+   COPY_4V(dest->attrib[FRAG_ATTRIB_COL1], tmp);
+   /*
    UNCLAMPED_FLOAT_TO_RGBA_CHAN( dest->specular, tmp );
+   */
 
    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_FOG, tmp );
    dest->attrib[FRAG_ATTRIB_FOGC][0] = tmp[0];
 
    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR_INDEX, tmp );
-   dest->index = tmp[0];
+   dest->attrib[FRAG_ATTRIB_CI][0] = tmp[0];
 
    /* XXX See _tnl_get_attr about pointsize ... */
    _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_POINTSIZE, tmp );
index 628e928..b4207f2 100644 (file)
@@ -57,7 +57,7 @@ static void _swsetup_render_line_tri( GLcontext *ctx,
    SWvertex *v1 = &verts[e1];
    SWvertex *v2 = &verts[e2];
    GLchan c[2][4];
-   GLchan s[2][4];
+   GLfloat s[2][4];
    GLfloat i[2];
 
    /* cull testing */
@@ -71,17 +71,17 @@ static void _swsetup_render_line_tri( GLcontext *ctx,
    if (ctx->Light.ShadeModel == GL_FLAT) {
       COPY_CHAN4(c[0], v0->color);
       COPY_CHAN4(c[1], v1->color);
-      COPY_CHAN4(s[0], v0->specular);
-      COPY_CHAN4(s[1], v1->specular);
-      i[0] = v0->index;
-      i[1] = v1->index;
+      COPY_4V(s[0], v0->attrib[FRAG_ATTRIB_COL1]);
+      COPY_4V(s[1], v1->attrib[FRAG_ATTRIB_COL1]);
+      i[0] = v0->attrib[FRAG_ATTRIB_CI][0];
+      i[1] = v1->attrib[FRAG_ATTRIB_CI][0];
 
       COPY_CHAN4(v0->color, v2->color);
       COPY_CHAN4(v1->color, v2->color);
-      COPY_CHAN4(v0->specular, v2->specular);
-      COPY_CHAN4(v1->specular, v2->specular);
-      v0->index = v2->index;
-      v1->index = v2->index;
+      COPY_4V(v0->attrib[FRAG_ATTRIB_COL1], v2->attrib[FRAG_ATTRIB_COL1]);
+      COPY_4V(v1->attrib[FRAG_ATTRIB_COL1], v2->attrib[FRAG_ATTRIB_COL1]);
+      v0->attrib[FRAG_ATTRIB_CI][0] = v2->attrib[FRAG_ATTRIB_CI][0];
+      v1->attrib[FRAG_ATTRIB_CI][0] = v2->attrib[FRAG_ATTRIB_CI][0];
    }
 
    if (swsetup->render_prim == GL_POLYGON) {
@@ -97,10 +97,10 @@ static void _swsetup_render_line_tri( GLcontext *ctx,
    if (ctx->Light.ShadeModel == GL_FLAT) {
       COPY_CHAN4(v0->color, c[0]);
       COPY_CHAN4(v1->color, c[1]);
-      COPY_CHAN4(v0->specular, s[0]);
-      COPY_CHAN4(v1->specular, s[1]);
-      v0->index = i[0];
-      v1->index = i[1];
+      COPY_4V(v0->attrib[FRAG_ATTRIB_COL1], s[0]);
+      COPY_4V(v1->attrib[FRAG_ATTRIB_COL1], s[1]);
+      v0->attrib[FRAG_ATTRIB_CI][0] = i[0];
+      v1->attrib[FRAG_ATTRIB_CI][0] = i[1];
    }
 }
 
@@ -116,7 +116,7 @@ static void _swsetup_render_point_tri( GLcontext *ctx,
    SWvertex *v1 = &verts[e1];
    SWvertex *v2 = &verts[e2];
    GLchan c[2][4];
-   GLchan s[2][4];
+   GLfloat s[2][4];
    GLfloat i[2];
 
    /* cull testing */
@@ -131,18 +131,18 @@ static void _swsetup_render_point_tri( GLcontext *ctx,
       /* save colors/indexes for v0, v1 vertices */
       COPY_CHAN4(c[0], v0->color);
       COPY_CHAN4(c[1], v1->color);
-      COPY_CHAN4(s[0], v0->specular);
-      COPY_CHAN4(s[1], v1->specular);
-      i[0] = v0->index;
-      i[1] = v1->index;
+      COPY_4V(s[0], v0->attrib[FRAG_ATTRIB_COL1]);
+      COPY_4V(s[1], v1->attrib[FRAG_ATTRIB_COL1]);
+      i[0] = v0->attrib[FRAG_ATTRIB_CI][0];
+      i[1] = v1->attrib[FRAG_ATTRIB_CI][0];
 
       /* copy v2 color/indexes to v0, v1 indexes */
       COPY_CHAN4(v0->color, v2->color);
       COPY_CHAN4(v1->color, v2->color);
-      COPY_CHAN4(v0->specular, v2->specular);
-      COPY_CHAN4(v1->specular, v2->specular);
-      v0->index = v2->index;
-      v1->index = v2->index;
+      COPY_4V(v0->attrib[FRAG_ATTRIB_COL1], v2->attrib[FRAG_ATTRIB_COL1]);
+      COPY_4V(v1->attrib[FRAG_ATTRIB_COL1], v2->attrib[FRAG_ATTRIB_COL1]);
+      v0->attrib[FRAG_ATTRIB_CI][0] = v2->attrib[FRAG_ATTRIB_CI][0];
+      v1->attrib[FRAG_ATTRIB_CI][0] = v2->attrib[FRAG_ATTRIB_CI][0];
    }
 
    if (ef[e0]) _swrast_Point( ctx, v0 );
@@ -153,10 +153,10 @@ static void _swsetup_render_point_tri( GLcontext *ctx,
       /* restore v0, v1 colores/indexes */
       COPY_CHAN4(v0->color, c[0]);
       COPY_CHAN4(v1->color, c[1]);
-      COPY_CHAN4(v0->specular, s[0]);
-      COPY_CHAN4(v1->specular, s[1]);
-      v0->index = i[0];
-      v1->index = i[1];
+      COPY_4V(v0->attrib[FRAG_ATTRIB_COL1], s[0]);
+      COPY_4V(v1->attrib[FRAG_ATTRIB_COL1], s[1]);
+      v0->attrib[FRAG_ATTRIB_CI][0] = i[0];
+      v1->attrib[FRAG_ATTRIB_CI][0] = i[1];
    }
    _swrast_flush(ctx);
 }
index 1fdf0cb..9fcde31 100644 (file)
@@ -36,7 +36,7 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
    GLenum mode = GL_FILL;
    GLuint facing = 0;
    GLchan saved_color[3][4];
-   GLchan saved_spec[3][4];
+   GLfloat saved_spec[3][4];
    GLfloat saved_index[3];
 
    v[0] = &verts[e0];
@@ -46,10 +46,10 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
 
    if (IND & (SS_TWOSIDE_BIT | SS_OFFSET_BIT | SS_UNFILLED_BIT))
    {
-      GLfloat ex = v[0]->win[0] - v[2]->win[0];
-      GLfloat ey = v[0]->win[1] - v[2]->win[1];
-      GLfloat fx = v[1]->win[0] - v[2]->win[0];
-      GLfloat fy = v[1]->win[1] - v[2]->win[1];
+      GLfloat ex = v[0]->attrib[FRAG_ATTRIB_WPOS][0] - v[2]->attrib[FRAG_ATTRIB_WPOS][0];
+      GLfloat ey = v[0]->attrib[FRAG_ATTRIB_WPOS][1] - v[2]->attrib[FRAG_ATTRIB_WPOS][1];
+      GLfloat fx = v[1]->attrib[FRAG_ATTRIB_WPOS][0] - v[2]->attrib[FRAG_ATTRIB_WPOS][0];
+      GLfloat fy = v[1]->attrib[FRAG_ATTRIB_WPOS][1] - v[2]->attrib[FRAG_ATTRIB_WPOS][1];
       GLfloat cc  = ex*fy - ey*fx;
 
       if (IND & (SS_TWOSIDE_BIT | SS_UNFILLED_BIT))
@@ -85,30 +85,30 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
                  if (VB->SecondaryColorPtr[1]) {
                     GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
 
-                    COPY_CHAN4(saved_spec[0], v[0]->specular);
-                    COPY_CHAN4(saved_spec[1], v[1]->specular);
-                    COPY_CHAN4(saved_spec[2], v[2]->specular);
+                    COPY_4V(saved_spec[0], v[0]->attrib[FRAG_ATTRIB_COL1]);
+                    COPY_4V(saved_spec[1], v[1]->attrib[FRAG_ATTRIB_COL1]);
+                    COPY_4V(saved_spec[2], v[2]->attrib[FRAG_ATTRIB_COL1]);
 
                     if (VB->SecondaryColorPtr[1]->stride) {
-                       SS_SPEC(v[0]->specular, vbspec[e0]);
-                       SS_SPEC(v[1]->specular, vbspec[e1]);
-                       SS_SPEC(v[2]->specular, vbspec[e2]);
+                       SS_SPEC(v[0]->attrib[FRAG_ATTRIB_COL1], vbspec[e0]);
+                       SS_SPEC(v[1]->attrib[FRAG_ATTRIB_COL1], vbspec[e1]);
+                       SS_SPEC(v[2]->attrib[FRAG_ATTRIB_COL1], vbspec[e2]);
                     }
                     else {
-                       SS_SPEC(v[0]->specular, vbspec[0]);
-                       SS_SPEC(v[1]->specular, vbspec[0]);
-                       SS_SPEC(v[2]->specular, vbspec[0]);
+                       SS_SPEC(v[0]->attrib[FRAG_ATTRIB_COL1], vbspec[0]);
+                       SS_SPEC(v[1]->attrib[FRAG_ATTRIB_COL1], vbspec[0]);
+                       SS_SPEC(v[2]->attrib[FRAG_ATTRIB_COL1], vbspec[0]);
                     }
                  }
               } else {
                  GLfloat *vbindex = (GLfloat *)VB->IndexPtr[1]->data;
-                 saved_index[0] = v[0]->index;
-                 saved_index[1] = v[1]->index;
-                 saved_index[2] = v[2]->index;
+                 saved_index[0] = v[0]->attrib[FRAG_ATTRIB_CI][0];
+                 saved_index[1] = v[1]->attrib[FRAG_ATTRIB_CI][0];
+                 saved_index[2] = v[2]->attrib[FRAG_ATTRIB_CI][0];
                  
-                 SS_IND(v[0]->index, (GLuint) vbindex[e0]);
-                 SS_IND(v[1]->index, (GLuint) vbindex[e1]);
-                 SS_IND(v[2]->index, (GLuint) vbindex[e2]);
+                 SS_IND(v[0]->attrib[FRAG_ATTRIB_CI][0], (GLuint) vbindex[e0]);
+                 SS_IND(v[1]->attrib[FRAG_ATTRIB_CI][0], (GLuint) vbindex[e1]);
+                 SS_IND(v[2]->attrib[FRAG_ATTRIB_CI][0], (GLuint) vbindex[e2]);
               }
            }
         }
@@ -117,9 +117,9 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
       if (IND & SS_OFFSET_BIT)
       {
         offset = ctx->Polygon.OffsetUnits * ctx->DrawBuffer->_MRD;
-        z[0] = v[0]->win[2];
-        z[1] = v[1]->win[2];
-        z[2] = v[2]->win[2];
+        z[0] = v[0]->attrib[FRAG_ATTRIB_WPOS][2];
+        z[1] = v[1]->attrib[FRAG_ATTRIB_WPOS][2];
+        z[2] = v[2]->attrib[FRAG_ATTRIB_WPOS][2];
         if (cc * cc > 1e-16) {
            const GLfloat ez = z[0] - z[2];
            const GLfloat fz = z[1] - z[2];
@@ -130,40 +130,40 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
             /* Unfortunately, we need to clamp to prevent negative Zs below.
              * Technically, we should do the clamping per-fragment.
              */
-            offset = MAX2(offset, -v[0]->win[2]);
-            offset = MAX2(offset, -v[1]->win[2]);
-            offset = MAX2(offset, -v[2]->win[2]);
+            offset = MAX2(offset, -v[0]->attrib[FRAG_ATTRIB_WPOS][2]);
+            offset = MAX2(offset, -v[1]->attrib[FRAG_ATTRIB_WPOS][2]);
+            offset = MAX2(offset, -v[2]->attrib[FRAG_ATTRIB_WPOS][2]);
         }
       }
    }
 
    if (mode == GL_POINT) {
       if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetPoint) {
-        v[0]->win[2] += offset;
-        v[1]->win[2] += offset;
-        v[2]->win[2] += offset;
+        v[0]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
+        v[1]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
+        v[2]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
       }
       _swsetup_render_point_tri( ctx, e0, e1, e2, facing );
    } else if (mode == GL_LINE) {
       if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetLine) {
-        v[0]->win[2] += offset;
-        v[1]->win[2] += offset;
-        v[2]->win[2] += offset;
+        v[0]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
+        v[1]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
+        v[2]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
       }
       _swsetup_render_line_tri( ctx, e0, e1, e2, facing );
    } else {
       if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetFill) {
-        v[0]->win[2] += offset;
-        v[1]->win[2] += offset;
-        v[2]->win[2] += offset;
+        v[0]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
+        v[1]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
+        v[2]->attrib[FRAG_ATTRIB_WPOS][2] += offset;
       }
       _swrast_Triangle( ctx, v[0], v[1], v[2] );
    }
 
    if (IND & SS_OFFSET_BIT) {
-      v[0]->win[2] = z[0];
-      v[1]->win[2] = z[1];
-      v[2]->win[2] = z[2];
+      v[0]->attrib[FRAG_ATTRIB_WPOS][2] = z[0];
+      v[1]->attrib[FRAG_ATTRIB_WPOS][2] = z[1];
+      v[2]->attrib[FRAG_ATTRIB_WPOS][2] = z[2];
    }
 
    if (IND & SS_TWOSIDE_BIT) {
@@ -176,14 +176,14 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
             }
 
            if (VB->SecondaryColorPtr[1]) {
-              COPY_CHAN4(v[0]->specular, saved_spec[0]);
-              COPY_CHAN4(v[1]->specular, saved_spec[1]);
-              COPY_CHAN4(v[2]->specular, saved_spec[2]);
+              COPY_4V(v[0]->attrib[FRAG_ATTRIB_COL1], saved_spec[0]);
+              COPY_4V(v[1]->attrib[FRAG_ATTRIB_COL1], saved_spec[1]);
+              COPY_4V(v[2]->attrib[FRAG_ATTRIB_COL1], saved_spec[2]);
            }
         } else {
-           v[0]->index = saved_index[0];
-           v[1]->index = saved_index[1];
-           v[2]->index = saved_index[2];
+           v[0]->attrib[FRAG_ATTRIB_CI][0] = saved_index[0];
+           v[1]->attrib[FRAG_ATTRIB_CI][0] = saved_index[1];
+           v[2]->attrib[FRAG_ATTRIB_CI][0] = saved_index[2];
         }
       }
    }
index 6cdd1bc..ab3bb37 100644 (file)
@@ -89,15 +89,15 @@ void TAG(translate_vertex)(GLcontext *ctx,
 
    if (format == TINY_VERTEX_FORMAT) {
       if (HAVE_HW_VIEWPORT) {
-        dst->win[0] = s[0]  * src->v.x + s[12];
-        dst->win[1] = s[5]  * src->v.y + s[13];
-        dst->win[2] = s[10] * src->v.z + s[14];
-        dst->win[3] = 1.0;
+        dst->attrib[FRAG_ATTRIB_WPOS][0] = s[0]  * src->v.x + s[12];
+        dst->attrib[FRAG_ATTRIB_WPOS][1] = s[5]  * src->v.y + s[13];
+        dst->attrib[FRAG_ATTRIB_WPOS][2] = s[10] * src->v.z + s[14];
+        dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0;
       } else {
-        dst->win[0] = UNVIEWPORT_X( src->v.x );
-        dst->win[1] = UNVIEWPORT_Y( src->v.y );
-        dst->win[2] = UNVIEWPORT_Z( src->v.z );
-        dst->win[3] = 1.0;
+        dst->attrib[FRAG_ATTRIB_WPOS][0] = UNVIEWPORT_X( src->v.x );
+        dst->attrib[FRAG_ATTRIB_WPOS][1] = UNVIEWPORT_Y( src->v.y );
+        dst->attrib[FRAG_ATTRIB_WPOS][2] = UNVIEWPORT_Z( src->v.z );
+        dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0;
       }
 
       dst->color[0] = src->tv.color.red;
@@ -109,21 +109,21 @@ void TAG(translate_vertex)(GLcontext *ctx,
       if (HAVE_HW_VIEWPORT) {
         if (HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) {
            GLfloat oow = 1.0 / src->v.w;
-           dst->win[0] = s[0]  * src->v.x * oow + s[12];
-           dst->win[1] = s[5]  * src->v.y * oow + s[13];
-           dst->win[2] = s[10] * src->v.z * oow + s[14];
-           dst->win[3] = oow;
+           dst->attrib[FRAG_ATTRIB_WPOS][0] = s[0]  * src->v.x * oow + s[12];
+           dst->attrib[FRAG_ATTRIB_WPOS][1] = s[5]  * src->v.y * oow + s[13];
+           dst->attrib[FRAG_ATTRIB_WPOS][2] = s[10] * src->v.z * oow + s[14];
+           dst->attrib[FRAG_ATTRIB_WPOS][3] = oow;
         } else {
-           dst->win[0] = s[0]  * src->v.x + s[12];
-           dst->win[1] = s[5]  * src->v.y + s[13];
-           dst->win[2] = s[10] * src->v.z + s[14];
-           dst->win[3] = src->v.w;
+           dst->attrib[FRAG_ATTRIB_WPOS][0] = s[0]  * src->v.x + s[12];
+           dst->attrib[FRAG_ATTRIB_WPOS][1] = s[5]  * src->v.y + s[13];
+           dst->attrib[FRAG_ATTRIB_WPOS][2] = s[10] * src->v.z + s[14];
+           dst->attrib[FRAG_ATTRIB_WPOS][3] = src->v.w;
         }
       } else {
-        dst->win[0] = UNVIEWPORT_X( src->v.x );
-        dst->win[1] = UNVIEWPORT_Y( src->v.y );
-        dst->win[2] = UNVIEWPORT_Z( src->v.z );
-        dst->win[3] = src->v.w;
+        dst->attrib[FRAG_ATTRIB_WPOS][0] = UNVIEWPORT_X( src->v.x );
+        dst->attrib[FRAG_ATTRIB_WPOS][1] = UNVIEWPORT_Y( src->v.y );
+        dst->attrib[FRAG_ATTRIB_WPOS][2] = UNVIEWPORT_Z( src->v.z );
+        dst->attrib[FRAG_ATTRIB_WPOS][3] = src->v.w;
       }
 
       dst->color[0] = src->v.color.red;
@@ -131,11 +131,11 @@ void TAG(translate_vertex)(GLcontext *ctx,
       dst->color[2] = src->v.color.blue;
       dst->color[3] = src->v.color.alpha;
 
-      dst->specular[0] = src->v.specular.red;
-      dst->specular[1] = src->v.specular.green;
-      dst->specular[2] = src->v.specular.blue;
+      dst->attrib[FRAG_ATTRIB_COL1][0] = UBYTE_TO_FLOAT(src->v.specular.red);
+      dst->attrib[FRAG_ATTRIB_COL1][1] = UBYTE_TO_FLOAT(src->v.specular.green);
+      dst->attrib[FRAG_ATTRIB_COL1][2] = UBYTE_TO_FLOAT(src->v.specular.blue);
 
-      dst->attrib[FRAG_ATTRIB_FOGC][0] = src->v.specular.alpha/255.0;
+      dst->attrib[FRAG_ATTRIB_FOGC][0] = UBYTE_TO_FLOAT(src->v.specular.alpha);
 
       if (HAVE_PTEX_VERTICES &&
          ((HAVE_TEX2_VERTICES && format == PROJ_TEX3_VERTEX_FORMAT) ||