sw_span can now hold x/y arrays of fragment positions - getting ready to
authorBrian Paul <brian.paul@tungstengraphics.com>
Sat, 2 Feb 2002 17:24:11 +0000 (17:24 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Sat, 2 Feb 2002 17:24:11 +0000 (17:24 +0000)
ditch the pb (pixel buffer) code.
Converted point drawing, bitmaps and aa lines to use new span functions.

23 files changed:
src/mesa/swrast/s_aaline.c
src/mesa/swrast/s_aalinetemp.h
src/mesa/swrast/s_accum.c
src/mesa/swrast/s_bitmap.c
src/mesa/swrast/s_blend.c
src/mesa/swrast/s_blend.h
src/mesa/swrast/s_buffers.c
src/mesa/swrast/s_context.c
src/mesa/swrast/s_context.h
src/mesa/swrast/s_depth.c
src/mesa/swrast/s_drawpix.c
src/mesa/swrast/s_logic.c
src/mesa/swrast/s_logic.h
src/mesa/swrast/s_masking.c
src/mesa/swrast/s_masking.h
src/mesa/swrast/s_points.c
src/mesa/swrast/s_pointtemp.h
src/mesa/swrast/s_span.c
src/mesa/swrast/s_stencil.c
src/mesa/swrast/s_stencil.h
src/mesa/swrast/s_triangle.c
src/mesa/swrast/s_zoom.c
src/mesa/swrast/swrast.h

index 9e7ed8c..92103cb 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: s_aaline.c,v 1.12 2001/09/18 23:06:14 kschultz Exp $ */
+/* $Id: s_aaline.c,v 1.13 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -27,8 +27,8 @@
 
 #include "glheader.h"
 #include "swrast/s_aaline.h"
-#include "swrast/s_pb.h"
 #include "swrast/s_context.h"
+#include "swrast/s_span.h"
 #include "swrast/swrast.h"
 #include "mtypes.h"
 #include "mmath.h"
@@ -75,6 +75,8 @@ struct LineInfo
    GLfloat vPlane[MAX_TEXTURE_UNITS][4];
    GLfloat lambda[MAX_TEXTURE_UNITS];
    GLfloat texWidth[MAX_TEXTURE_UNITS], texHeight[MAX_TEXTURE_UNITS];
+
+   struct sw_span span;
 };
 
 
@@ -326,8 +328,9 @@ compute_coveragef(const struct LineInfo *info,
 
 
 
-typedef void (*plot_func)(GLcontext *ctx, const struct LineInfo *line,
-                          struct pixel_buffer *pb, int ix, int iy);
+typedef void (*plot_func)(GLcontext *ctx, struct LineInfo *line,
+                          int ix, int iy);
+                         
 
 
 /*
@@ -337,7 +340,6 @@ static void
 segment(GLcontext *ctx,
         struct LineInfo *line,
         plot_func plot,
-        struct pixel_buffer *pb,
         GLfloat t0, GLfloat t1)
 {
    const GLfloat absDx = (line->dx < 0.0F) ? -line->dx : line->dx;
@@ -407,7 +409,7 @@ segment(GLcontext *ctx,
          GLint iy;
          /* scan across the line, bottom-to-top */
          for (iy = iyBot; iy < iyTop; iy++) {
-            (*plot)(ctx, line, pb, ix, iy);
+            (*plot)(ctx, line, ix, iy);
          }
          yBot += dydx;
          yTop += dydx;
@@ -453,7 +455,7 @@ segment(GLcontext *ctx,
          GLint ix;
          /* scan across the line, left-to-right */
          for (ix = ixLeft; ix < ixRight; ix++) {
-            (*plot)(ctx, line, pb, ix, iy);
+            (*plot)(ctx, line, ix, iy);
          }
          xLeft += dxdy;
          xRight += dxdy;
@@ -486,6 +488,7 @@ segment(GLcontext *ctx,
 
 #define NAME(x)  aa_multitex_rgba_##x
 #define DO_Z
+#define DO_FOG
 #define DO_RGBA
 #define DO_MULTITEX
 #include "s_aalinetemp.h"
@@ -493,6 +496,7 @@ segment(GLcontext *ctx,
 
 #define NAME(x)  aa_multitex_spec_##x
 #define DO_Z
+#define DO_FOG
 #define DO_RGBA
 #define DO_MULTITEX
 #define DO_SPEC
index f645e55..a473250 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: s_aalinetemp.h,v 1.15 2001/12/05 10:24:31 keithw Exp $ */
+/* $Id: s_aalinetemp.h,v 1.16 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  * Function to render each fragment in the AA line.
  */
 static void
-NAME(plot)(GLcontext *ctx, const struct LineInfo *line,
-           struct pixel_buffer *pb, int ix, int iy)
+NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy)
 {
    const GLfloat fx = (GLfloat) ix;
    const GLfloat fy = (GLfloat) iy;
    const GLfloat coverage = compute_coveragef(line, ix, iy);
-   GLdepth z;
-   GLfloat fog;
-#ifdef DO_RGBA
-   GLchan red, green, blue, alpha;
-#else
-   GLint index;
-#endif
-   GLchan specRed, specGreen, specBlue;
-   GLfloat tex[MAX_TEXTURE_UNITS][4], lambda[MAX_TEXTURE_UNITS];
+   const GLuint i = line->span.end;
 
    if (coverage == 0.0)
       return;
 
+   line->span.end++;
+   line->span.coverage[i] = coverage;
+   line->span.xArray[i] = ix;
+   line->span.yArray[i] = iy;
+
    /*
     * Compute Z, color, texture coords, fog for the fragment by
     * solving the plane equations at (ix,iy).
     */
 #ifdef DO_Z
-   z = (GLdepth) solve_plane(fx, fy, line->zPlane);
-#else
-   z = 0.0;
+   line->span.zArray[i] = (GLdepth) solve_plane(fx, fy, line->zPlane);
 #endif
 #ifdef DO_FOG
-   fog = solve_plane(fx, fy, line->fPlane);
-#else
-   fog = 0.0;
+   line->span.fogArray[i] = solve_plane(fx, fy, line->fPlane);
 #endif
 #ifdef DO_RGBA
-   red   = solve_plane_chan(fx, fy, line->rPlane);
-   green = solve_plane_chan(fx, fy, line->gPlane);
-   blue  = solve_plane_chan(fx, fy, line->bPlane);
-   alpha = solve_plane_chan(fx, fy, line->aPlane);
+   line->span.color.rgba[i][RCOMP] = solve_plane_chan(fx, fy, line->rPlane);
+   line->span.color.rgba[i][GCOMP] = solve_plane_chan(fx, fy, line->gPlane);
+   line->span.color.rgba[i][BCOMP] = solve_plane_chan(fx, fy, line->bPlane);
+   line->span.color.rgba[i][ACOMP] = solve_plane_chan(fx, fy, line->aPlane);
 #endif
 #ifdef DO_INDEX
-   index = (GLint) solve_plane(fx, fy, line->iPlane);
+   line->span.color.index[i] = (GLint) solve_plane(fx, fy, line->iPlane);
 #endif
 #ifdef DO_SPEC
-   specRed   = solve_plane_chan(fx, fy, line->srPlane);
-   specGreen = solve_plane_chan(fx, fy, line->sgPlane);
-   specBlue  = solve_plane_chan(fx, fy, line->sbPlane);
-#else
-   (void) specRed;
-   (void) specGreen;
-   (void) specBlue;
+   line->span.specArray[i][RCOMP] = solve_plane_chan(fx, fy, line->srPlane);
+   line->span.specArray[i][GCOMP] = solve_plane_chan(fx, fy, line->sgPlane);
+   line->span.specArray[i][BCOMP] = solve_plane_chan(fx, fy, line->sbPlane);
 #endif
 #ifdef DO_TEX
    {
-      GLfloat invQ = solve_plane_recip(fx, fy, line->vPlane[0]);
-      tex[0][0] = solve_plane(fx, fy, line->sPlane[0]) * invQ;
-      tex[0][1] = solve_plane(fx, fy, line->tPlane[0]) * invQ;
-      tex[0][2] = solve_plane(fx, fy, line->uPlane[0]) * invQ;
-      lambda[0] = compute_lambda(line->sPlane[0], line->tPlane[0], invQ,
-                                 line->texWidth[0], line->texHeight[0]);
+      const GLfloat invQ = solve_plane_recip(fx, fy, line->vPlane[0]);
+      line->span.texcoords[0][i][0] = solve_plane(fx, fy, line->sPlane[0]) * invQ;
+      line->span.texcoords[0][i][1] = solve_plane(fx, fy, line->tPlane[0]) * invQ;
+      line->span.texcoords[0][i][2] = solve_plane(fx, fy, line->uPlane[0]) * invQ;
+      line->span.lambda[0][i] = compute_lambda(line->sPlane[0], line->tPlane[0], invQ,
+                                          line->texWidth[0], line->texHeight[0]);
    }
 #elif defined(DO_MULTITEX)
    {
       GLuint unit;
       for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
          if (ctx->Texture.Unit[unit]._ReallyEnabled) {
-            GLfloat invQ = solve_plane_recip(fx, fy, line->vPlane[unit]);
-            tex[unit][0] = solve_plane(fx, fy, line->sPlane[unit]) * invQ;
-            tex[unit][1] = solve_plane(fx, fy, line->tPlane[unit]) * invQ;
-            tex[unit][2] = solve_plane(fx, fy, line->uPlane[unit]) * invQ;
-            lambda[unit] = compute_lambda(line->sPlane[unit],
-                                          line->tPlane[unit], invQ,
-                                          line->texWidth[unit], line->texHeight[unit]);
+            const GLfloat invQ = solve_plane_recip(fx, fy, line->vPlane[unit]);
+            line->span.texcoords[unit][i][0] = solve_plane(fx, fy, line->sPlane[unit]) * invQ;
+            line->span.texcoords[unit][i][1] = solve_plane(fx, fy, line->tPlane[unit]) * invQ;
+            line->span.texcoords[unit][i][2] = solve_plane(fx, fy, line->uPlane[unit]) * invQ;
+            line->span.lambda[unit][i] = compute_lambda(line->sPlane[unit],
+                                               line->tPlane[unit], invQ,
+                                               line->texWidth[unit], line->texHeight[unit]);
          }
       }
    }
-#else
-   (void) tex[0][0];
-   (void) lambda[0];
 #endif
 
-
-   PB_COVERAGE(pb, coverage);
-
-#if defined(DO_MULTITEX)
-#if defined(DO_SPEC)
-   PB_WRITE_MULTITEX_SPEC_PIXEL(pb, ix, iy, z, fog, red, green, blue, alpha,
-                                specRed, specGreen, specBlue, tex);
-#else
-   PB_WRITE_MULTITEX_PIXEL(pb, ix, iy, z, fog, red, green, blue, alpha, tex);
-#endif
-#elif defined(DO_TEX)
-   PB_WRITE_TEX_PIXEL(pb, ix, iy, z, fog, red, green, blue, alpha,
-                      tex[0][0], tex[0][1], tex[0][2]);
+   if (line->span.end == MAX_WIDTH) {
+#ifdef DO_TEX
+      _mesa_write_texture_span(ctx, &line->span, GL_LINE);
 #elif defined(DO_RGBA)
-   PB_WRITE_RGBA_PIXEL(pb, ix, iy, z, fog, red, green, blue, alpha);
-#elif defined(DO_INDEX)
-   PB_WRITE_CI_PIXEL(pb, ix, iy, z, fog, index);
+      _mesa_write_rgba_span(ctx, &line->span, GL_LINE);
+#else
+      _mesa_write_index_span(ctx, &line->span, GL_LINE);
 #endif
-
-   pb->haveCoverage = GL_TRUE;
-   PB_CHECK_FLUSH(ctx, pb);
+   }
 }
 
 
@@ -146,7 +119,6 @@ static void
 NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   struct pixel_buffer *pb = SWRAST_CONTEXT(ctx)->PB;
    GLfloat tStart, tEnd;   /* segment start, end along line length */
    GLboolean inSegment;
    GLint iLen, i;
@@ -165,18 +137,24 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
    if (line.len == 0.0 || IS_INF_OR_NAN(line.len))
       return;
 
+   INIT_SPAN(line.span);
+   line.span.arrayMask |= (SPAN_XY | SPAN_COVERAGE);
+
    line.xAdj = line.dx / line.len * line.halfWidth;
    line.yAdj = line.dy / line.len * line.halfWidth;
 
 #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->fog, v1->fog, line.fPlane);
 #endif
 #ifdef DO_RGBA
+   line.span.arrayMask |= SPAN_RGBA;
    if (ctx->Light.ShadeModel == GL_SMOOTH) {
       compute_plane(line.x0, line.y0, line.x1, line.y1,
                     v0->color[RCOMP], v1->color[RCOMP], line.rPlane);
@@ -195,6 +173,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
    }
 #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);
@@ -210,6 +189,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
    }
 #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,
                     (GLfloat) v0->index, (GLfloat) v1->index, line.iPlane);
@@ -232,6 +212,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
       const GLfloat r1 = v1->texcoord[0][2] * invW0;
       const GLfloat q0 = v0->texcoord[0][3] * invW0;
       const GLfloat q1 = v1->texcoord[0][3] * invW0;
+      line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
       compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[0]);
       compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[0]);
       compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[0]);
@@ -242,6 +223,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
 #elif defined(DO_MULTITEX)
    {
       GLuint u;
+      line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
          if (ctx->Texture.Unit[u]._ReallyEnabled) {
             const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;
@@ -291,7 +273,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
             /* stipple bit is off */
             if (inSegment && (tEnd > tStart)) {
                /* draw the segment */
-               segment(ctx, &line, NAME(plot), pb, tStart, tEnd);
+               segment(ctx, &line, NAME(plot), tStart, tEnd);
                inSegment = GL_FALSE;
             }
             else {
@@ -303,13 +285,21 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
 
       if (inSegment) {
          /* draw the final segment of the line */
-         segment(ctx, &line, NAME(plot), pb, tStart, 1.0F);
+         segment(ctx, &line, NAME(plot), tStart, 1.0F);
       }
    }
    else {
       /* non-stippled */
-      segment(ctx, &line, NAME(plot), pb, 0.0, 1.0);
+      segment(ctx, &line, NAME(plot), 0.0, 1.0);
    }
+
+#ifdef DO_TEX
+   _mesa_write_texture_span(ctx, &line.span, GL_LINE);
+#elif defined(DO_RGBA)
+   _mesa_write_rgba_span(ctx, &line.span, GL_LINE);
+#else
+   _mesa_write_index_span(ctx, &line.span, GL_LINE);
+#endif
 }
 
 
index 5b7936b..167a655 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: s_accum.c,v 1.13 2001/09/19 20:30:44 kschultz Exp $ */
+/* $Id: s_accum.c,v 1.14 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -474,7 +474,7 @@ _swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value,
                   rgba[i][ACOMP] = multTable[acc[i4+3]];
                }
                if (colorMask != 0xffffffff) {
-                  _mesa_mask_rgba_span( ctx, width, xpos, ypos, rgba );
+                  _mesa_mask_rgba_array( ctx, width, xpos, ypos, rgba );
                }
                (*swrast->Driver.WriteRGBASpan)( ctx, width, xpos, ypos,
                                              (const GLchan (*)[4])rgba, NULL );
@@ -509,7 +509,7 @@ _swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value,
                   rgba[i][ACOMP] = CLAMP( a, 0, CHAN_MAX );
                }
                if (colorMask != 0xffffffff) {
-                  _mesa_mask_rgba_span( ctx, width, xpos, ypos, rgba );
+                  _mesa_mask_rgba_array( ctx, width, xpos, ypos, rgba );
                }
                (*swrast->Driver.WriteRGBASpan)( ctx, width, xpos, ypos,
                                              (const GLchan (*)[4])rgba, NULL );
index 6252fad..13ca384 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: s_bitmap.c,v 1.13 2001/12/14 02:50:57 brianp Exp $ */
+/* $Id: s_bitmap.c,v 1.14 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
 #include "glheader.h"
 #include "image.h"
 #include "macros.h"
+#include "mmath.h"
 #include "pixel.h"
 
 #include "s_context.h"
 #include "s_fog.h"
-#include "s_pb.h"
+#include "s_span.h"
 
 
 
@@ -46,10 +47,9 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
                const GLubyte *bitmap )
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   struct pixel_buffer *PB = swrast->PB;
    GLint row, col;
-   GLdepth fragZ;
-   GLfloat fog;
+   GLuint count = 0;
+   struct sw_span span;
 
    ASSERT(ctx->RenderMode == GL_RENDER);
    ASSERT(bitmap);
@@ -59,41 +59,40 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
    if (SWRAST_CONTEXT(ctx)->NewState)
       _swrast_validate_derived( ctx );
 
-   /* Set bitmap drawing color */
+   INIT_SPAN(span);
+   span.arrayMask |= SPAN_XY;
+   span.end = width;
    if (ctx->Visual.rgbMode) {
-      GLint r, g, b, a;
-      r = (GLint) (ctx->Current.RasterColor[0] * CHAN_MAXF);
-      g = (GLint) (ctx->Current.RasterColor[1] * CHAN_MAXF);
-      b = (GLint) (ctx->Current.RasterColor[2] * CHAN_MAXF);
-      a = (GLint) (ctx->Current.RasterColor[3] * CHAN_MAXF);
-      PB_SET_COLOR( PB, r, g, b, a );
+      span.interpMask |= SPAN_RGBA;
+      span.red   = FloatToFixed(ctx->Current.RasterColor[0] * CHAN_MAXF);
+      span.green = FloatToFixed(ctx->Current.RasterColor[1] * CHAN_MAXF);
+      span.blue  = FloatToFixed(ctx->Current.RasterColor[2] * CHAN_MAXF);
+      span.alpha = FloatToFixed(ctx->Current.RasterColor[3] * CHAN_MAXF);
+      span.redStep = span.greenStep = span.blueStep = span.alphaStep = 0;
    }
    else {
-      PB_SET_INDEX( PB, ctx->Current.RasterIndex );
+      span.interpMask |= SPAN_INDEX;
+      span.index = ChanToFixed(ctx->Current.RasterIndex);
+      span.indexStep = 0;
    }
 
-   fragZ = (GLdepth) ( ctx->Current.RasterPos[2] * ctx->DepthMaxF);
+   if (ctx->Depth.Test)
+      _mesa_span_default_z(ctx, &span);
+   if (ctx->Fog.Enabled)
+      _mesa_span_default_fog(ctx, &span);
 
-   if (ctx->Fog.Enabled) {
-      if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
-         fog = _mesa_z_to_fogfactor(ctx, ctx->Current.Attrib[VERT_ATTRIB_FOG][0]);
-      else
-         fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
-   }
-   else {
-      fog = 0.0;
-   }
-
-   for (row=0; row<height; row++) {
+   for (row = 0; row < height; row++, span.y++) {
       const GLubyte *src = (const GLubyte *) _mesa_image_address( unpack,
                  bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, 0, row, 0 );
 
       if (unpack->LsbFirst) {
          /* Lsb first */
          GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
-         for (col=0; col<width; col++) {
+         for (col = 0; col < width; col++) {
             if (*src & mask) {
-               PB_WRITE_PIXEL( PB, px+col, py+row, fragZ, fog );
+               span.xArray[count] = px + col;
+               span.yArray[count] = py + row;
+               count++;
             }
             if (mask == 128U) {
                src++;
@@ -104,8 +103,6 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
             }
          }
 
-         PB_CHECK_FLUSH( ctx, PB );
-
          /* get ready for next row */
          if (mask != 1)
             src++;
@@ -113,9 +110,11 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
       else {
          /* Msb first */
          GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
-         for (col=0; col<width; col++) {
+         for (col = 0; col < width; col++) {
             if (*src & mask) {
-               PB_WRITE_PIXEL( PB, px+col, py+row, fragZ, fog );
+               span.xArray[count] = px + col;
+               span.yArray[count] = py + row;
+               count++;
             }
             if (mask == 1U) {
                src++;
@@ -126,15 +125,22 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
             }
          }
 
-         PB_CHECK_FLUSH( ctx, PB );
-
          /* get ready for next row */
          if (mask != 128)
             src++;
       }
-   }
 
-   _mesa_flush_pb(ctx);
+      if (count + width >= MAX_WIDTH || row + 1 == height) {
+         /* flush the span */
+         span.end = count;
+         if (ctx->Visual.rgbMode)
+            _mesa_write_rgba_span(ctx, &span, GL_BITMAP);
+         else
+            _mesa_write_index_span(ctx, &span, GL_BITMAP);
+         span.end = 0;
+         count = 0;
+      }
+   }
 
    RENDER_FINISH(swrast,ctx);
 }
index 3860497..8541b9a 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: s_blend.c,v 1.10 2001/12/13 16:14:26 brianp Exp $ */
+/* $Id: s_blend.c,v 1.11 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
  * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -668,28 +668,39 @@ void _swrast_choose_blend_func( GLcontext *ctx )
 
 /*
  * Apply the blending operator to a span of pixels.
- * Input:  n - number of pixels in span
- *         x, y - location of leftmost pixel in span in window coords.
- *         mask - boolean mask indicating which pixels to blend.
- * In/Out:  rgba - pixel values
+ * We can handle horizontal runs of pixels (spans) or arrays of x/y
+ * pixel coordinates.
  */
 void
-_mesa_blend_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
-                  GLchan rgba[][4], const GLubyte mask[] )
+_mesa_blend_span( GLcontext *ctx, const struct sw_span *span,
+                  GLchan rgba[][4] )
 {
-   GLchan dest[MAX_WIDTH][4];
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+   GLchan framebuffer[MAX_WIDTH][4];
 
-   /* Check if device driver can do the work */
-   if (ctx->Color.BlendEquation==GL_LOGIC_OP &&
-       !ctx->Color.ColorLogicOpEnabled) {
-      return;
-   }
+   ASSERT(span->end < MAX_WIDTH);
+   ASSERT(span->arrayMask & SPAN_RGBA);
+   ASSERT(!ctx->Color.ColorLogicOpEnabled);
 
    /* Read span of current frame buffer pixels */
-   _mesa_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest );
+   if (span->arrayMask & SPAN_XY) {
+      /* array of x/y pixel coords */
+      (*swrast->Driver.ReadRGBAPixels)( ctx, span->end,
+                                        span->xArray, span->yArray,
+                                        framebuffer, span->mask );
+      if (swrast->_RasterMask & ALPHABUF_BIT) {
+         _mesa_read_alpha_pixels( ctx, span->end, span->xArray, span->yArray,
+                                  framebuffer, span->mask );
+      }
+   }
+   else {
+      /* horizontal run of pixels */
+      _mesa_read_rgba_span( ctx, ctx->DrawBuffer, span->end,
+                            span->x, span->y, framebuffer );
+   }
 
-   SWRAST_CONTEXT(ctx)->BlendFunc( ctx, n, mask, rgba,
-                                  (const GLchan (*)[4]) dest );
+   SWRAST_CONTEXT(ctx)->BlendFunc( ctx, span->end, span->mask, rgba,
+                                  (const GLchan (*)[4]) framebuffer );
 }
 
 
@@ -709,11 +720,7 @@ _mesa_blend_pixels( GLcontext *ctx,
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    GLchan dest[PB_SIZE][4];
 
-   /* Check if device driver can do the work */
-   if (ctx->Color.BlendEquation==GL_LOGIC_OP &&
-       !ctx->Color.ColorLogicOpEnabled) {
-      return;
-   }
+   ASSERT(!ctx->Color.ColorLogicOpEnabled);
 
    /* Read pixels from current color buffer */
    (*swrast->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask );
index 1448806..b431647 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_blend.h,v 1.4 2001/03/12 00:48:41 gareth Exp $ */
+/* $Id: s_blend.h,v 1.5 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -35,8 +35,8 @@
 
 
 extern void
-_mesa_blend_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
-                  GLchan rgba[][4], const GLubyte mask[] );
+_mesa_blend_span( GLcontext *ctx, const struct sw_span *span,
+                  GLchan rgba[][4] );
 
 
 extern void
index 409c3f6..5051541 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: s_buffers.c,v 1.8 2001/03/19 02:25:36 keithw Exp $ */
+/* $Id: s_buffers.c,v 1.9 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -67,7 +67,7 @@ clear_color_buffer_with_masking( GLcontext *ctx )
             rgba[j][BCOMP] = b;
             rgba[j][ACOMP] = a;
          }
-         _mesa_mask_rgba_span( ctx, width, x, y + i, rgba );
+         _mesa_mask_rgba_array( ctx, width, x, y + i, rgba );
          (*swrast->Driver.WriteRGBASpan)( ctx, width, x, y + i,
                                       (CONST GLchan (*)[4]) rgba, NULL );
       }
@@ -82,7 +82,7 @@ clear_color_buffer_with_masking( GLcontext *ctx )
          for (j=0;j<width;j++) {
             span[j] = ctx->Color.ClearIndex;
          }
-         _mesa_mask_index_span( ctx, width, x, y + i, span );
+         _mesa_mask_index_array( ctx, width, x, y + i, span );
          (*swrast->Driver.WriteCI32Span)( ctx, width, x, y + i, span, mask );
       }
    }
index 1298af1..b9b7a87 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_context.c,v 1.27 2002/01/10 16:54:28 brianp Exp $ */
+/* $Id: s_context.c,v 1.28 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -56,7 +56,7 @@ _swrast_update_rasterflags( GLcontext *ctx )
    if (ctx->Color.BlendEnabled)           RasterMask |= BLEND_BIT;
    if (ctx->Depth.Test)                   RasterMask |= DEPTH_BIT;
    if (ctx->Fog.Enabled)                  RasterMask |= FOG_BIT;
-   if (ctx->Scissor.Enabled)              RasterMask |= SCISSOR_BIT;
+   if (ctx->Scissor.Enabled)              RasterMask |= CLIP_BIT;
    if (ctx->Stencil.Enabled)              RasterMask |= STENCIL_BIT;
    if (ctx->Visual.rgbMode) {
       const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
@@ -78,7 +78,7 @@ _swrast_update_rasterflags( GLcontext *ctx )
        || ctx->Viewport.X + ctx->Viewport.Width > ctx->DrawBuffer->Width
        || ctx->Viewport.Y < 0
        || ctx->Viewport.Y + ctx->Viewport.Height > ctx->DrawBuffer->Height) {
-      RasterMask |= WINCLIP_BIT;
+      RasterMask |= CLIP_BIT;
    }
 
    if (ctx->Depth.OcclusionTest)
index 317317a..59e029b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_context.h,v 1.14 2002/01/10 16:54:29 brianp Exp $ */
+/* $Id: s_context.h,v 1.15 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -73,11 +73,10 @@ typedef void (*swrast_tri_func)( GLcontext *ctx, const SWvertex *,
 #define DEPTH_BIT              0x004   /* Depth-test pixels */
 #define FOG_BIT                        0x008   /* Fog pixels */
 #define LOGIC_OP_BIT           0x010   /* Apply logic op in software */
-#define SCISSOR_BIT            0x020   /* Scissor pixels */
+#define CLIP_BIT               0x020   /* Scissor or window clip pixels */
 #define STENCIL_BIT            0x040   /* Stencil pixels */
 #define MASKING_BIT            0x080   /* Do glColorMask or glIndexMask */
 #define ALPHABUF_BIT           0x100   /* Using software alpha buffer */
-#define WINCLIP_BIT            0x200   /* Clip pixels/primitives to window */
 #define MULTI_DRAW_BIT         0x400   /* Write to more than one color- */
                                         /* buffer or no buffers. */
 #define OCCLUSION_BIT           0x800   /* GL_HP_occlusion_test enabled */
index 1962dbe..0dba77c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_depth.c,v 1.13 2002/01/28 00:07:33 brianp Exp $ */
+/* $Id: s_depth.c,v 1.14 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -44,9 +44,11 @@ GLvoid *
 _mesa_zbuffer_address(GLcontext *ctx, GLint x, GLint y)
 {
    if (ctx->Visual.depthBits <= 16)
-      return (GLushort *) ctx->DrawBuffer->DepthBuffer + ctx->DrawBuffer->Width * y + x;
+      return (GLushort *) ctx->DrawBuffer->DepthBuffer
+         + ctx->DrawBuffer->Width * y + x;
    else
-      return (GLuint *) ctx->DrawBuffer->DepthBuffer + ctx->DrawBuffer->Width * y + x;
+      return (GLuint *) ctx->DrawBuffer->DepthBuffer
+         + ctx->DrawBuffer->Width * y + x;
 }
 
 
@@ -73,7 +75,7 @@ _mesa_zbuffer_address(GLcontext *ctx, GLint x, GLint y)
  * Return:  number of fragments which pass the test.
  */
 static GLuint
-depth_test_span16( GLcontext *ctx, GLuint n, GLint x, GLint y,
+depth_test_span16( GLcontext *ctx, GLuint n,
                    GLushort zbuffer[], const GLdepth z[], GLubyte mask[] )
 {
    GLuint passed = 0;
@@ -302,7 +304,7 @@ depth_test_span16( GLcontext *ctx, GLuint n, GLint x, GLint y,
 
 
 static GLuint
-depth_test_span32( GLcontext *ctx, GLuint n, GLint x, GLint y,
+depth_test_span32( GLcontext *ctx, GLuint n,
                    GLuint zbuffer[], const GLdepth z[], GLubyte mask[] )
 {
    GLuint passed = 0;
@@ -544,7 +546,7 @@ _old_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
       GLdepth zbuffer[MAX_WIDTH];
       GLuint passed;
       (*swrast->Driver.ReadDepthSpan)(ctx, n, x, y, zbuffer);
-      passed = depth_test_span32(ctx, n, x, y, zbuffer, z, mask);
+      passed = depth_test_span32(ctx, n, zbuffer, z, mask);
       assert(swrast->Driver.WriteDepthSpan);
       (*swrast->Driver.WriteDepthSpan)(ctx, n, x, y, zbuffer, mask);
       return passed;
@@ -553,22 +555,23 @@ _old_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
       /* software depth buffer */
       if (ctx->Visual.depthBits <= 16) {
          GLushort *zptr = (GLushort *) Z_ADDRESS16(ctx, x, y);
-         GLuint passed = depth_test_span16(ctx, n, x, y, zptr, z, mask);
+         GLuint passed = depth_test_span16(ctx, n, zptr, z, mask);
          return passed;
       }
       else {
          GLuint *zptr = (GLuint *) Z_ADDRESS32(ctx, x, y);
-         GLuint passed = depth_test_span32(ctx, n, x, y, zptr, z, mask);
+         GLuint passed = depth_test_span32(ctx, n, zptr, z, mask);
          return passed;
       }
    }
 }
 
+
 /*
  * Apply depth test to span of fragments.  Hardware or software z buffer.
  */
-GLuint
-_mesa_depth_test_span( GLcontext *ctx, struct sw_span *span)
+static GLuint
+depth_test_span( GLcontext *ctx, struct sw_span *span)
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
@@ -579,7 +582,7 @@ _mesa_depth_test_span( GLcontext *ctx, struct sw_span *span)
       GLdepth zbuffer[MAX_WIDTH];
       GLuint passed;
       (*swrast->Driver.ReadDepthSpan)(ctx, span->end, span->x, span->y, zbuffer);
-      passed = depth_test_span32(ctx, span->end, span->x, span->y,
+      passed = depth_test_span32(ctx, span->end,
                                 zbuffer, span->zArray, span->mask);
       ASSERT(swrast->Driver.WriteDepthSpan);
       (*swrast->Driver.WriteDepthSpan)(ctx, span->end, span->x, span->y, zbuffer, span->mask);
@@ -592,11 +595,11 @@ _mesa_depth_test_span( GLcontext *ctx, struct sw_span *span)
       /* software depth buffer */
       if (ctx->Visual.depthBits <= 16) {
          GLushort *zptr = (GLushort *) Z_ADDRESS16(ctx, span->x, span->y);
-         passed = depth_test_span16(ctx, span->end, span->x, span->y, zptr, span->zArray, span->mask);
+         passed = depth_test_span16(ctx, span->end, zptr, span->zArray, span->mask);
       }
       else {
          GLuint *zptr = (GLuint *) Z_ADDRESS32(ctx, span->x, span->y);
-         passed = depth_test_span32(ctx, span->end, span->x, span->y, zptr, span->zArray, span->mask);
+         passed = depth_test_span32(ctx, span->end, zptr, span->zArray, span->mask);
       }
       if (passed < span->end)
          span->writeAll = GL_FALSE;
@@ -1361,6 +1364,20 @@ _mesa_depth_test_pixels( GLcontext *ctx,
 
 
 
+GLuint
+_mesa_depth_test_span( GLcontext *ctx, struct sw_span *span)
+{
+   if (span->arrayMask & SPAN_XY) {
+      _mesa_depth_test_pixels(ctx, span->end,
+                              span->xArray, span->yArray,
+                              span->zArray, span->mask);
+      return 1;
+   }
+   else {
+      return depth_test_span(ctx, span);
+   }
+}
+
 
 
 /**********************************************************************/
index 5ce9469..434b714 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_drawpix.c,v 1.28 2002/01/31 00:27:43 brianp Exp $ */
+/* $Id: s_drawpix.c,v 1.29 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -117,7 +117,7 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
    if (ctx->Fog.Enabled)
       _mesa_span_default_fog(ctx, &span);
 
-   if ((SWRAST_CONTEXT(ctx)->_RasterMask&(~(SCISSOR_BIT|WINCLIP_BIT)))==0
+   if ((SWRAST_CONTEXT(ctx)->_RasterMask & ~CLIP_BIT) == 0
        && ctx->Texture._ReallyEnabled == 0
        && unpack->Alignment == 1
        && !unpack->SwapBytes
@@ -740,27 +740,10 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
    if (fast_draw_pixels(ctx, x, y, width, height, format, type, pixels))
       return;
 
-   /* Fragment depth values */
-   if (ctx->Depth.Test || ctx->Fog.Enabled) {
-      /* fill in array of z values */
-      GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->DepthMaxF);
-      GLfloat fog;
-      GLint i;
-
-      if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
-         fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterFogCoord);
-      else
-         fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
-
-      for (i=0;i<width;i++) {
-        span.zArray[i] = z;
-         span.fogArray[i] = fog;
-      }
-   }
-
+   if (ctx->Depth.Test)
+      _mesa_span_default_z(ctx, &span);
    if (ctx->Fog.Enabled)
       _mesa_span_default_fog(ctx, &span);
-   span.arrayMask |= SPAN_Z;
 
    if (SWRAST_CONTEXT(ctx)->_RasterMask == 0 && !zoom && x >= 0 && y >= 0
        && x + width <= ctx->DrawBuffer->Width
index 9d61230..d2f20b7 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: s_logic.c,v 1.8 2001/07/13 20:07:37 brianp Exp $ */
+/* $Id: s_logic.c,v 1.9 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -40,9 +40,9 @@
 /*
  * Apply logic op to array of CI pixels.
  */
-static void index_logicop( GLcontext *ctx, GLuint n,
-                           GLuint index[], const GLuint dest[],
-                           const GLubyte mask[] )
+static void
+index_logicop( GLcontext *ctx, GLuint n, GLuint index[], const GLuint dest[],
+               const GLubyte mask[] )
 {
    GLuint i;
    switch (ctx->Color.LogicOp) {
@@ -166,14 +166,24 @@ static void index_logicop( GLcontext *ctx, GLuint n,
  * used if the device driver can't do logic ops.
  */
 void
-_mesa_logicop_ci_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
-                       GLuint index[], const GLubyte mask[] )
+_mesa_logicop_ci_span( GLcontext *ctx, const struct sw_span *span,
+                       GLuint index[] )
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    GLuint dest[MAX_WIDTH];
+
+   ASSERT(span->end < MAX_WIDTH);
+
    /* Read dest values from frame buffer */
-   (*swrast->Driver.ReadCI32Span)( ctx, n, x, y, dest );
-   index_logicop( ctx, n, index, dest, mask );
+   if (span->arrayMask & SPAN_XY) {
+      (*swrast->Driver.ReadCI32Pixels)( ctx, span->end, span->xArray,
+                                        span->yArray, dest, span->mask );
+   }
+   else {
+      (*swrast->Driver.ReadCI32Span)( ctx, span->end, span->x, span->y, dest );
+   }
+
+   index_logicop( ctx, span->end, index, dest, span->mask );
 }
 
 
@@ -207,9 +217,9 @@ _mesa_logicop_ci_pixels( GLcontext *ctx,
  * Note:  Since the R, G, B, and A channels are all treated the same we
  * process them as 4-byte GLuints instead of four GLubytes.
  */
-static void rgba_logicop_ui( const GLcontext *ctx, GLuint n,
-                             const GLubyte mask[],
-                             GLuint src[], const GLuint dest[] )
+static void
+rgba_logicop_ui( const GLcontext *ctx, GLuint n, const GLubyte mask[],
+                 GLuint src[], const GLuint dest[] )
 {
    GLuint i;
    switch (ctx->Color.LogicOp) {
@@ -332,9 +342,9 @@ static void rgba_logicop_ui( const GLcontext *ctx, GLuint n,
  * As above, but operate on GLchan values
  * Note: need to pass n = numPixels * 4.
  */
-static void rgba_logicop_chan( const GLcontext *ctx, GLuint n,
-                               const GLubyte mask[],
-                               GLchan srcPtr[], const GLchan destPtr[] )
+static void
+rgba_logicop_chan( const GLcontext *ctx, GLuint n, const GLubyte mask[],
+                   GLchan srcPtr[], const GLchan destPtr[] )
 {
 #if CHAN_TYPE == GL_FLOAT
    GLuint *src = (GLuint *) srcPtr;
@@ -466,20 +476,39 @@ static void rgba_logicop_chan( const GLcontext *ctx, GLuint n,
 
 /*
  * Apply the current logic operator to a span of RGBA pixels.
- * This is only used if the device driver can't do logic ops.
+ * We can handle horizontal runs of pixels (spans) or arrays of x/y
+ * pixel coordinates.
  */
 void
-_mesa_logicop_rgba_span( GLcontext *ctx,
-                         GLuint n, GLint x, GLint y,
-                         GLchan rgba[][4], const GLubyte mask[] )
+_mesa_logicop_rgba_span( GLcontext *ctx, const struct sw_span *span,
+                         GLchan rgba[][4] )
 {
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
    GLchan dest[MAX_WIDTH][4];
-   _mesa_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest );
+
+   ASSERT(span->end < MAX_WIDTH);
+   ASSERT(span->arrayMask & SPAN_RGBA);
+
+   if (span->arrayMask & SPAN_XY) {
+      (*swrast->Driver.ReadRGBAPixels)(ctx, span->end,
+                                       span->xArray, span->yArray,
+                                       dest, span->mask);
+      if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
+         _mesa_read_alpha_pixels(ctx, span->end, span->xArray, span->yArray,
+                                 dest, span->mask);
+      }
+   }
+   else {
+      _mesa_read_rgba_span(ctx, ctx->DrawBuffer, span->end,
+                           span->x, span->y, dest);
+   }
+
    if (sizeof(GLchan) * 4 == sizeof(GLuint)) {
-      rgba_logicop_ui(ctx, n, mask, (GLuint *) rgba, (const GLuint *) dest);
+      rgba_logicop_ui(ctx, span->end, span->mask,
+                      (GLuint *) rgba, (const GLuint *) dest);
    }
    else {
-      rgba_logicop_chan(ctx, 4 * n, mask,
+      rgba_logicop_chan(ctx, 4 * span->end, span->mask,
                         (GLchan *) rgba, (const GLchan *) dest);
    }
 }
index 76cd7f8..bc3cded 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: s_logic.h,v 1.3 2001/03/12 00:48:42 gareth Exp $ */
+/* $Id: s_logic.h,v 1.4 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -34,9 +34,8 @@
 
 
 extern void
-_mesa_logicop_ci_span( GLcontext *ctx,
-                       GLuint n, GLint x, GLint y, GLuint index[],
-                       const GLubyte mask[] );
+_mesa_logicop_ci_span( GLcontext *ctx, const struct sw_span *span,
+                       GLuint index[] );
 
 
 extern void
@@ -46,8 +45,8 @@ _mesa_logicop_ci_pixels( GLcontext *ctx,
 
 
 extern void
-_mesa_logicop_rgba_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
-                         GLchan rgba[][4], const GLubyte mask[] );
+_mesa_logicop_rgba_span( GLcontext *ctx, const struct sw_span *span,
+                         GLchan rgba[][4] );
 
 
 extern void
index b4433b2..968a2b9 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: s_masking.c,v 1.5 2001/03/19 02:25:36 keithw Exp $ */
+/* $Id: s_masking.c,v 1.6 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
 #include "s_span.h"
 
 
+
+void
+_mesa_mask_rgba_span( GLcontext *ctx, const struct sw_span *span,
+                     GLchan rgba[][4] )
+{
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+   GLchan dest[MAX_WIDTH][4];
+#if CHAN_BITS == 8
+   GLuint srcMask = *((GLuint*)ctx->Color.ColorMask);
+   GLuint dstMask = ~srcMask;
+   GLuint *rgba32 = (GLuint *) rgba;
+   GLuint *dest32 = (GLuint *) dest;
+#else
+   const GLboolean rMask = ctx->Color.ColorMask[RCOMP];
+   const GLboolean gMask = ctx->Color.ColorMask[GCOMP];
+   const GLboolean bMask = ctx->Color.ColorMask[BCOMP];
+   const GLboolean aMask = ctx->Color.ColorMask[ACOMP];
+#endif
+   const GLuint n = span->end;
+   GLuint i;
+
+   ASSERT(n < MAX_WIDTH);
+   ASSERT(span->arrayMask & SPAN_RGBA);
+
+   if (span->arrayMask & SPAN_XY) {
+      (*swrast->Driver.ReadRGBAPixels)(ctx, n, span->xArray, span->yArray,
+                                       dest, span->mask);
+      if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
+         _mesa_read_alpha_pixels(ctx, n, span->xArray, span->yArray,
+                                 dest, span->mask );
+      }
+   }
+   else {
+      _mesa_read_rgba_span(ctx, ctx->DrawBuffer, n, span->x, span->y, dest);
+   }
+
+#if CHAN_BITS == 8
+   for (i = 0; i < n; i++) {
+      rgba32[i] = (rgba32[i] & srcMask) | (dest32[i] & dstMask);
+   }
+#else
+   for (i = 0; i < n; i++) {
+      if (!rMask)  rgba[i][RCOMP] = dest[i][RCOMP];
+      if (!gMask)  rgba[i][GCOMP] = dest[i][GCOMP];
+      if (!bMask)  rgba[i][BCOMP] = dest[i][BCOMP];
+      if (!aMask)  rgba[i][ACOMP] = dest[i][ACOMP];
+   }
+#endif
+}
+
+
+
+
 /*
  * Apply glColorMask to a span of RGBA pixels.
  */
 void
-_mesa_mask_rgba_span( GLcontext *ctx,
-                      GLuint n, GLint x, GLint y, GLchan rgba[][4] )
+_mesa_mask_rgba_array( GLcontext *ctx,
+                       GLuint n, GLint x, GLint y, GLchan rgba[][4] )
 {
    GLchan dest[MAX_WIDTH][4];
    GLuint i;
@@ -135,12 +188,46 @@ _mesa_mask_rgba_pixels( GLcontext *ctx,
 
 
 
+void
+_mesa_mask_index_span( GLcontext *ctx, const struct sw_span *span,
+                       GLuint index[] )
+{
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+   const GLuint msrc = ctx->Color.IndexMask;
+   const GLuint mdest = ~msrc;
+   GLuint fbindexes[MAX_WIDTH];
+   GLuint i;
+
+   ASSERT(span->arrayMask & SPAN_INDEX);
+   ASSERT(span->end < MAX_WIDTH);
+
+   if (span->arrayMask & SPAN_XY) {
+
+      (*swrast->Driver.ReadCI32Pixels)(ctx, span->end, span->xArray,
+                                       span->yArray, fbindexes, span->mask);
+
+      for (i = 0; i < span->end; i++) {
+         index[i] = (index[i] & msrc) | (fbindexes[i] & mdest);
+      }
+   }
+   else {
+      _mesa_read_index_span(ctx, ctx->DrawBuffer, span->end, span->x, span->y,
+                            fbindexes );
+
+      for (i = 0; i < span->end; i++) {
+         index[i] = (index[i] & msrc) | (fbindexes[i] & mdest);
+      }
+   }
+}
+
+
+
 /*
  * Apply glIndexMask to a span of CI pixels.
  */
 void
-_mesa_mask_index_span( GLcontext *ctx,
-                       GLuint n, GLint x, GLint y, GLuint index[] )
+_mesa_mask_index_array( GLcontext *ctx,
+                        GLuint n, GLint x, GLint y, GLuint index[] )
 {
    GLuint i;
    GLuint fbindexes[MAX_WIDTH];
@@ -180,3 +267,4 @@ _mesa_mask_index_pixels( GLcontext *ctx,
       index[i] = (index[i] & msrc) | (fbindexes[i] & mdest);
    }
 }
+
index 4f324aa..3d4aaaa 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: s_masking.h,v 1.3 2001/03/12 00:48:42 gareth Exp $ */
+/* $Id: s_masking.h,v 1.4 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  * Implement glColorMask for a span of RGBA pixels.
  */
 extern void
-_mesa_mask_rgba_span( GLcontext *ctx,
-                      GLuint n, GLint x, GLint y,
+_mesa_mask_rgba_span( GLcontext *ctx, const struct sw_span *span,
                       GLchan rgba[][4] );
 
 
+extern void
+_mesa_mask_rgba_array( GLcontext *ctx, GLuint n, GLint x, GLint y,
+                       GLchan rgba[][4] );
+
 
 /*
  * Implement glColorMask for an array of RGBA pixels.
@@ -57,8 +60,17 @@ _mesa_mask_rgba_pixels( GLcontext *ctx,
  * Implement glIndexMask for a span of CI pixels.
  */
 extern void
-_mesa_mask_index_span( GLcontext *ctx,
-                       GLuint n, GLint x, GLint y, GLuint index[] );
+_mesa_mask_index_span( GLcontext *ctx, const struct sw_span *span,
+                       GLuint index[] );
+
+
+
+/*
+ * Implement glIndexMask for a span of CI pixels.
+ */
+extern void
+_mesa_mask_index_array( GLcontext *ctx,
+                        GLuint n, GLint x, GLint y, GLuint index[] );
 
 
 
index d2b9a24..2eac602 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: s_points.c,v 1.16 2002/01/06 20:39:19 brianp Exp $ */
+/* $Id: s_points.c,v 1.17 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
 #include "texstate.h"
 #include "s_context.h"
 #include "s_feedback.h"
-#include "s_pb.h"
 #include "s_points.h"
 #include "s_span.h"
 
 
 
-#define INDEX      0x0
 #define RGBA       0x1
-#define SMOOTH     0x2
-#define TEXTURE    0x4
-#define SPECULAR   0x8
-#define LARGE     0x10
-#define ATTENUATE 0x20
-#define SPRITE    0x40
+#define INDEX      0x2
+#define SMOOTH     0x4
+#define TEXTURE    0x8
+#define SPECULAR  0x10
+#define LARGE     0x20
+#define ATTENUATE 0x40
+#define SPRITE    0x80
 
 
 /*
index 4c843b3..02dc9fe 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: s_pointtemp.h,v 1.11 2001/12/05 10:24:31 keithw Exp $ */
+/* $Id: s_pointtemp.h,v 1.12 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -53,7 +53,7 @@
  * else if d > rmax2 then
  *    fragment has 0% coverage
  * else
- *    fragement has % coverage = (d - rmin2) / (rmax2 - rmin2)
+ *    fragment has % coverage = (d - rmin2) / (rmax2 - rmin2)
  */
 
 
 static void
 NAME ( GLcontext *ctx, const SWvertex *vert )
 {
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   struct pixel_buffer *PB = swrast->PB;
-
-   const GLint z = (GLint) (vert->win[2]);
-
-#if FLAGS & RGBA
-   const GLchan red   = vert->color[0];
-   const GLchan green = vert->color[1];
-   const GLchan blue  = vert->color[2];
-   GLchan alpha = vert->color[3];
-#if FLAGS & SPECULAR
-   const GLchan sRed   = vert->specular[0];
-   const GLchan sGreen = vert->specular[1];
-   const GLchan sBlue  = vert->specular[2];
-#endif
-#else
-   GLint index = vert->index;
+#if FLAGS & TEXTURE
+   GLuint u;
 #endif
 #if FLAGS & (ATTENUATE | LARGE | SMOOTH)
    GLfloat size;
@@ -85,25 +70,76 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
 #if FLAGS & ATTENUATE
    GLfloat alphaAtten;
 #endif
+#if (FLAGS & RGBA) && (FLAGS & SMOOTH)
+   const GLchan red   = vert->color[0];
+   const GLchan green = vert->color[1];
+   const GLchan blue  = vert->color[2];
+   const GLchan alpha = vert->color[3];
+#endif
+
+   struct sw_span span;
+
+   /* Cull primitives with malformed coordinates.
+    */
+   {
+      float tmp = vert->win[0] + vert->win[1];
+      if (IS_INF_OR_NAN(tmp))
+        return;
+   }
+
+   INIT_SPAN(span);
 
+   span.arrayMask |= (SPAN_XY | SPAN_Z);
+   span.interpMask |= SPAN_FOG;
+   span.fog = vert->fog;
+   span.fogStep = 0.0;
+
+#if (FLAGS & RGBA)
+#if (FLAGS & SMOOTH)
+   span.arrayMask |= SPAN_RGBA;
+#else
+   span.interpMask |= SPAN_RGBA;
+   span.red = ChanToFixed(vert->color[0]);
+   span.green = ChanToFixed(vert->color[1]);
+   span.blue = ChanToFixed(vert->color[2]);
+   span.alpha = ChanToFixed(vert->color[3]);
+   span.redStep = span.greenStep = span.blueStep = span.alphaStep = 0;
+#endif /*SMOOTH*/
+#endif /*RGBA*/
+#if FLAGS & SPECULAR
+   span.interpMask |= SPAN_SPEC;
+   span.specRed = ChanToFixed(vert->specular[0]);
+   span.specGreen = ChanToFixed(vert->specular[1]);
+   span.specBlue = ChanToFixed(vert->specular[2]);
+   span.specRedStep = span.specGreenStep = span.specBlueStep = 0;
+#endif
+#if FLAGS & INDEX
+   span.interpMask |= SPAN_INDEX;
+   span.index = IntToFixed(vert->index);
+   span.indexStep = 0;
+#endif
 #if FLAGS & TEXTURE
-   GLfloat texcoord[MAX_TEXTURE_UNITS][4];
-   GLuint u;
+   span.interpMask |= SPAN_TEXTURE;
+   span.arrayMask |= SPAN_LAMBDA;
    for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
       if (ctx->Texture.Unit[u]._ReallyEnabled) {
-         if (vert->texcoord[u][3] != 1.0 && vert->texcoord[u][3] != 0.0) {
-            texcoord[u][0] = vert->texcoord[u][0] / vert->texcoord[u][3];
-            texcoord[u][1] = vert->texcoord[u][1] / vert->texcoord[u][3];
-            texcoord[u][2] = vert->texcoord[u][2] / vert->texcoord[u][3];
-         }
-         else {
-            texcoord[u][0] = vert->texcoord[u][0];
-            texcoord[u][1] = vert->texcoord[u][1];
-            texcoord[u][2] = vert->texcoord[u][2];
-         }
+         const GLfloat q = vert->texcoord[u][3];
+         const GLfloat invQ = (q == 0.0 || q == 1.0) ? 1.0 : (1.0 / q);
+         span.tex[u][0] = vert->texcoord[u][0] * invQ;
+         span.tex[u][1] = vert->texcoord[u][1] * invQ;
+         span.tex[u][2] = vert->texcoord[u][2] * invQ;
+         span.tex[u][3] = q;
+         span.texStep[u][0] = 0.0;
+         span.texStep[u][1] = 0.0;
+         span.texStep[u][2] = 0.0;
+         span.texStep[u][3] = 0.0;
+         span.rho[u] = 0.0;
       }
    }
 #endif
+#if FLAGS & SMOOTH
+   span.arrayMask |= SPAN_COVERAGE;
+#endif
 
 #if FLAGS & ATTENUATE
    if (vert->pointSize >= ctx->Point.Threshold) {
@@ -119,14 +155,6 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
    size = ctx->Point._Size;
 #endif
 
-   /* Cull primitives with malformed coordinates.
-    */
-   {
-      float tmp = vert->win[0] + vert->win[1];
-      if (IS_INF_OR_NAN(tmp))
-        return;
-   }
-
 #if FLAGS & SPRITE
    {
       SWcontext *swctx = SWRAST_CONTEXT(ctx);
@@ -134,11 +162,12 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
       SWvertex v0, v1, v2, v3;
       GLuint unit;
 
+#if (FLAGS & RGBA) && (FLAGS & SMOOTH)
       (void) red;
       (void) green;
       (void) blue;
       (void) alpha;
-      (void) z;
+#endif
 
       /* lower left corner */
       v0 = *vert;
@@ -187,6 +216,8 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
    {
       GLint x, y;
       const GLfloat radius = 0.5F * size;
+      const GLint z = (GLint) (vert->win[2]);
+      GLuint count = 0;
 #if FLAGS & SMOOTH
       const GLfloat rmin = radius - 0.7071F;  /* 0.7071 = sqrt(2)/2 */
       const GLfloat rmax = radius + 0.7071F;
@@ -218,9 +249,9 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
          ymin = (GLint) vert->win[1] - iRadius + 1;
          ymax = ymin + iSize - 1;
       }
-#endif
-      (void) radius;
+#endif /*SMOOTH*/
 
+      (void) radius;
       for (y = ymin; y <= ymax; y++) {
          for (x = xmin; x <= xmax; x++) {
 #if FLAGS & SMOOTH
@@ -229,98 +260,70 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
             const GLfloat dy = y - vert->win[1] + 0.5F;
             const GLfloat dist2 = dx * dx + dy * dy;
             if (dist2 < rmax2) {
-#if FLAGS & RGBA
-               alpha = vert->color[3];
-#endif
                if (dist2 >= rmin2) {
                   /* compute partial coverage */
-                  PB_COVERAGE(PB, 1.0F - (dist2 - rmin2) * cscale);
-              }
-               else {
-                  /* full coverage */
-                  PB_COVERAGE(PB, 1.0F);
-               }
-
-#endif /* SMOOTH */
-
-#if ((FLAGS & (ATTENUATE | RGBA)) == (ATTENUATE | RGBA))
-              alpha = (GLchan) (alpha * alphaAtten);
+                  span.coverage[count] = 1.0F - (dist2 - rmin2) * cscale;
+#if FLAGS & INDEX
+                  span.coverage[count] *= 15.0; /* coverage in [0,15] */
 #endif
-
-#if FLAGS & SPECULAR
-               PB_WRITE_MULTITEX_SPEC_PIXEL(PB, x, y, z, vert->fog,
-                                            red, green, blue, alpha,
-                                            sRed, sGreen, sBlue,
-                                            texcoord);
-#elif FLAGS & TEXTURE
-              if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) {
-                 PB_WRITE_MULTITEX_PIXEL(PB, x, y, z, vert->fog,
-                                         red, green, blue, alpha,
-                                         texcoord);
-              }
-              else if (ctx->Texture._ReallyEnabled) {
-                 PB_WRITE_TEX_PIXEL(PB, x,y,z, vert->fog,
-                                    red, green, blue, alpha,
-                                    texcoord[0][0],
-                                    texcoord[0][1],
-                                    texcoord[0][2]);
-              }
+               }
                else {
-                  PB_WRITE_RGBA_PIXEL(PB, x, y, z, vert->fog,
-                                      red, green, blue, alpha);
+                  /* full coverage */
+                  span.coverage[count] = 1.0F;
                }
-#elif FLAGS & RGBA
-              PB_WRITE_RGBA_PIXEL(PB, x, y, z, vert->fog,
-                                   red, green, blue, alpha);
-#else /* color index */
-               PB_WRITE_CI_PIXEL(PB, x, y, z, vert->fog, index);
-#endif
-#if FLAGS & SMOOTH
-           }
-#endif
-        }
-      }
 
-#if FLAGS & SMOOTH
-      PB->haveCoverage = GL_TRUE;
-#endif
+               span.xArray[count] = x;
+               span.yArray[count] = y;
+               span.zArray[count] = z;
 
-      PB_CHECK_FLUSH(ctx,PB);
+#if FLAGS & RGBA
+               span.color.rgba[count][RCOMP] = red;
+               span.color.rgba[count][GCOMP] = green;
+               span.color.rgba[count][BCOMP] = blue;
+#if FLAGS & ATTENUATE
+               span.color.rgba[count][ACOMP] = (GLchan) (alpha * alphaAtten);
+#else
+               span.color.rgba[count][ACOMP] = alpha;
+#endif /*ATTENUATE*/
+#endif /*RGBA*/
+               count++;
+            } /*if*/
+#else /*SMOOTH*/
+            /* not smooth (square points */
+            span.xArray[count] = x;
+            span.yArray[count] = y;
+            span.zArray[count] = z;
+            count++;
+#endif /*SMOOTH*/
+        } /*for x*/
+      } /*for y*/
+      span.end = count;
    }
 
 #else /* LARGE || ATTENUATE || SMOOTH*/
 
    {
       /* size == 1 */
-      GLint x = (GLint) vert->win[0];
-      GLint y = (GLint) vert->win[1];
-#if ((FLAGS & (SPECULAR | TEXTURE)) == (SPECULAR | TEXTURE))
-      PB_WRITE_MULTITEX_SPEC_PIXEL(PB, x, y, z, vert->fog,
-                                   red, green, blue, alpha,
-                                   sRed, sGreen, sBlue,
-                                   texcoord);
-#elif FLAGS & TEXTURE
-      if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) {
-         PB_WRITE_MULTITEX_PIXEL(PB, x, y, z, vert->fog,
-                                 red, green, blue, alpha, texcoord );
-      }
-      else {
-         PB_WRITE_TEX_PIXEL(PB, x, y, z, vert->fog,
-                            red, green, blue, alpha,
-                            texcoord[0][0], texcoord[0][1], texcoord[0][2]);
-      }
-#elif FLAGS & RGBA
-      /* rgba size 1 point */
-      alpha = vert->color[3];
-      PB_WRITE_RGBA_PIXEL(PB, x, y, z, vert->fog, red, green, blue, alpha);
-#else
-      /* color index size 1 point */
-      PB_WRITE_CI_PIXEL(PB, x, y, z, vert->fog, index);
-#endif
+      span.xArray[0] = (GLint) vert->win[0];
+      span.yArray[0] = (GLint) vert->win[1];
+      span.zArray[0] = (GLint) vert->win[2];
+      span.end = 1;
    }
+
 #endif /* LARGE || ATTENUATE || SMOOTH */
 
-   PB_CHECK_FLUSH(ctx, PB);
+   ASSERT(span.end > 0);
+
+#if FLAGS & TEXTURE
+   if (ctx->Texture._ReallyEnabled)
+      _mesa_write_texture_span(ctx, &span, GL_POINT);
+   else
+      _mesa_write_rgba_span(ctx, &span, GL_POINT);
+#elif FLAGS & RGBA
+   _mesa_write_rgba_span(ctx, &span, GL_POINT);
+#else
+   _mesa_write_index_span(ctx, &span, GL_POINT);
+#endif
 }
 
 
index 4266f08..2242a08 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_span.c,v 1.28 2002/01/31 00:27:43 brianp Exp $ */
+/* $Id: s_span.c,v 1.29 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -358,7 +358,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
          span->arrayMask |= SPAN_LAMBDA;
       }
       else {
-         /* just texture 0, witout lambda */
+         /* just texture 0, without lambda */
          const GLfloat ds = span->texStep[0][0];
          const GLfloat dt = span->texStep[0][1];
          const GLfloat dr = span->texStep[0][2];
@@ -387,12 +387,15 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
  * Apply the current polygon stipple pattern to a span of pixels.
  */
 static void
-stipple_polygon_span( GLcontext *ctx, struct sw_span *span)
+stipple_polygon_span( GLcontext *ctx, struct sw_span *span )
 {
    const GLuint highbit = 0x80000000;
-   GLuint i, m, stipple;
+   const GLuint stipple = ctx->PolygonStipple[span->y % 32];
+   GLuint i, m;
+
+   ASSERT(ctx->Polygon.StippleFlag);
+   ASSERT((span->arrayMask & SPAN_XY) == 0);
 
-   stipple = ctx->PolygonStipple[span->y % 32];
    m = highbit >> (GLuint) (span->x % 32);
 
    for (i = 0; i < span->end; i++) {
@@ -409,51 +412,61 @@ stipple_polygon_span( GLcontext *ctx, struct sw_span *span)
 
 
 /*
- * Clip a pixel span to the current buffer/window boundaries.
- * Return:   GL_TRUE   some pixel still visible
+ * Clip a pixel span to the current buffer/window boundaries:
+ * DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax.  This will accomplish
+ * window clipping and scissoring.
+ * Return:   GL_TRUE   some pixels still visible
  *           GL_FALSE  nothing visible
  */
 static GLuint
-clip_span( GLcontext *ctx, struct sw_span *span)
+clip_span( GLcontext *ctx, struct sw_span *span )
 {
-   GLint x = span->x, y = span->y, n = span->end;
-
-   /* Clip to top and bottom */
-   if (y < 0 || y >= ctx->DrawBuffer->Height) {
-      span->end = 0;
-      return GL_FALSE;
-   }
-
-   /* Clip to the left */
-   if (x < 0) {
-      if (x + n <= 0) {
-         /* completely off left side */
-        span->end = 0;
-         return GL_FALSE;
-      }
-      else {
-         /* partially off left side */
-        span->writeAll = GL_FALSE;
-         BZERO(span->mask, -x * sizeof(GLubyte));
-        return GL_TRUE;
+   const GLint xmin = ctx->DrawBuffer->_Xmin;
+   const GLint xmax = ctx->DrawBuffer->_Xmax;
+   const GLint ymin = ctx->DrawBuffer->_Ymin;
+   const GLint ymax = ctx->DrawBuffer->_Ymax;
+
+   if (span->arrayMask & SPAN_XY) {
+      /* arrays of x/y pixel coords */
+      const GLint *x = span->xArray;
+      const GLint *y = span->yArray;
+      const GLint n = span->end;
+      GLubyte *mask = span->mask;
+      GLint i;
+      /* note: using & intead of && to reduce branches */
+      for (i = 0; i < n; i++) {
+         mask[i] = (x[i] >= xmin) & (x[i] < xmax)
+                 & (y[i] >= ymin) & (y[i] < ymax);
       }
+      return GL_TRUE;  /* some pixels visible */
    }
+   else {
+      /* horizontal span of pixels */
+      const GLint x = span->x;
+      const GLint y = span->y;
+      const GLint n = span->end;
+
+      /* Trivial rejection tests */
+      if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) {
+         span->end = 0;
+         return GL_FALSE;  /* all pixels clipped */
+      }
 
-   /* Clip to right */
-   if (x + n > ctx->DrawBuffer->Width) {
-      if (x >= ctx->DrawBuffer->Width) {
-         /* completely off right side */
-        span->end = 0;
-         return GL_FALSE;
+      /* Clip to the left */
+      if (x < xmin) {
+         ASSERT(x + n > xmin);
+         span->writeAll = GL_FALSE;
+         BZERO(span->mask, (xmin - x) * sizeof(GLubyte));
       }
-      else {
-         /* partially off right side */
-         span->end = ctx->DrawBuffer->Width - x;
-        return GL_TRUE;
+
+      /* Clip to right */
+      if (x + n > xmax) {
+         ASSERT(x < xmax);
+         span->end = xmax - x;
       }
-   }
 
-   return GL_TRUE;
+      return GL_TRUE;  /* some pixels visible */
+   }
 }
 
 
@@ -462,20 +475,16 @@ clip_span( GLcontext *ctx, struct sw_span *span)
  * Draw to more than one color buffer (or none).
  */
 static void
-multi_write_index_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
-                        const GLuint indexes[], const GLubyte mask[] )
+multi_write_index_span( GLcontext *ctx, struct sw_span *span )
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    GLuint bufferBit;
 
-   if (ctx->Color.DrawBuffer == GL_NONE)
-      return;
-
    /* loop over four possible dest color buffers */
    for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
       if (bufferBit & ctx->Color.DrawDestMask) {
          GLuint indexTmp[MAX_WIDTH];
-         ASSERT(n < MAX_WIDTH);
+         ASSERT(span->end < MAX_WIDTH);
 
          if (bufferBit == FRONT_LEFT_BIT)
             (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT);
@@ -487,14 +496,27 @@ multi_write_index_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
             (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT);
 
          /* make copy of incoming indexes */
-         MEMCPY( indexTmp, indexes, n * sizeof(GLuint) );
+         MEMCPY( indexTmp, span->color.index, span->end * sizeof(GLuint) );
+
          if (ctx->Color.IndexLogicOpEnabled) {
-            _mesa_logicop_ci_span( ctx, n, x, y, indexTmp, mask );
+            _mesa_logicop_ci_span(ctx, span, indexTmp);
          }
+
          if (ctx->Color.IndexMask != 0xffffffff) {
-            _mesa_mask_index_span( ctx, n, x, y, indexTmp );
+            _mesa_mask_index_span(ctx, span, indexTmp);
+         }
+
+         if (span->arrayMask & SPAN_XY) {
+            /* array of pixel coords */
+            (*swrast->Driver.WriteCI32Pixels)(ctx, span->end,
+                                              span->xArray, span->yArray,
+                                              indexTmp, span->mask);
+         }
+         else {
+            /* horizontal run of pixels */
+            (*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y,
+                                            indexTmp, span->mask);
          }
-         (*swrast->Driver.WriteCI32Span)( ctx, n, x, y, indexTmp, mask );
       }
    }
 
@@ -509,13 +531,14 @@ multi_write_index_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
  * have been done first.
  */
 static void
-multi_write_rgba_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
-                       CONST GLchan rgba[][4], const GLubyte mask[] )
+multi_write_rgba_span( GLcontext *ctx, struct sw_span *span )
 {
    const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
    GLuint bufferBit;
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
+   ASSERT(colorMask != 0x0);
+
    if (ctx->Color.DrawBuffer == GL_NONE)
       return;
 
@@ -523,7 +546,7 @@ multi_write_rgba_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
    for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
       if (bufferBit & ctx->Color.DrawDestMask) {
          GLchan rgbaTmp[MAX_WIDTH][4];
-         ASSERT(n < MAX_WIDTH);
+         ASSERT(span->end < MAX_WIDTH);
 
          if (bufferBit == FRONT_LEFT_BIT) {
             (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT);
@@ -543,26 +566,42 @@ multi_write_rgba_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
          }
 
          /* make copy of incoming colors */
-         MEMCPY( rgbaTmp, rgba, 4 * n * sizeof(GLchan) );
+         MEMCPY( rgbaTmp, span->color.rgba, 4 * span->end * sizeof(GLchan) );
 
          if (ctx->Color.ColorLogicOpEnabled) {
-            _mesa_logicop_rgba_span( ctx, n, x, y, rgbaTmp, mask );
+            _mesa_logicop_rgba_span(ctx, span, rgbaTmp);
          }
          else if (ctx->Color.BlendEnabled) {
-            _mesa_blend_span( ctx, n, x, y, rgbaTmp, mask );
+            _mesa_blend_span(ctx, span, rgbaTmp);
          }
-         if (colorMask == 0x0) {
-            break;
-         }
-         else if (colorMask != 0xffffffff) {
-            _mesa_mask_rgba_span( ctx, n, x, y, rgbaTmp );
+
+         if (colorMask != 0xffffffff) {
+            _mesa_mask_rgba_span(ctx, span, rgbaTmp);
          }
 
-         (*swrast->Driver.WriteRGBASpan)( ctx, n, x, y,
-                                      (const GLchan (*)[4]) rgbaTmp, mask );
-         if (swrast->_RasterMask & ALPHABUF_BIT) {
-            _mesa_write_alpha_span( ctx, n, x, y,
-                                    (const GLchan (*)[4])rgbaTmp, mask );
+         if (span->arrayMask & SPAN_XY) {
+            /* array of pixel coords */
+            (*swrast->Driver.WriteRGBAPixels)(ctx, span->end,
+                                              span->xArray, span->yArray,
+                                              (const GLchan (*)[4]) rgbaTmp,
+                                              span->mask);
+            if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
+               _mesa_write_alpha_pixels(ctx, span->end,
+                                        span->xArray, span->yArray,
+                                        (const GLchan (*)[4]) rgbaTmp,
+                                        span->mask);
+            }
+         }
+         else {
+            /* horizontal run of pixels */
+            (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y,
+                                            (const GLchan (*)[4]) rgbaTmp,
+                                            span->mask);
+            if (swrast->_RasterMask & ALPHABUF_BIT) {
+               _mesa_write_alpha_span(ctx, span->end, span->x, span->y,
+                                      (const GLchan (*)[4]) rgbaTmp,
+                                      span->mask);
+            }
          }
       }
    }
@@ -586,27 +625,29 @@ _mesa_write_index_span( GLcontext *ctx, struct sw_span *span,
    const GLuint origInterpMask = span->interpMask;
    const GLuint origArrayMask = span->arrayMask;
 
+   ASSERT(span->end <= MAX_WIDTH);
+   ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX);
    ASSERT((span->interpMask & span->arrayMask) == 0);
 
-   MEMSET(span->mask, 1, span->end);
-   span->writeAll = GL_TRUE;
-
-   /* Window clipping */
-   if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
-      if (clip_span(ctx,span) == GL_FALSE) {
-         return;
-      }
+   if (span->arrayMask & SPAN_MASK) {
+      /* mask was initialized by caller, probably glBitmap */
+      span->writeAll = GL_FALSE;
+   }
+   else {
+      MEMSET(span->mask, 1, span->end);
+      span->writeAll = GL_TRUE;
    }
 
-   /* Scissor test */
-   if (ctx->Scissor.Enabled) {
-      if (_mesa_scissor_span( ctx, span ) == GL_FALSE) {
+   /* Clipping */
+   if ((swrast->_RasterMask & CLIP_BIT) || (primitive == GL_BITMAP)
+       || (primitive == GL_POINT)) {
+      if (!clip_span(ctx, span)) {
          return;
       }
    }
 
    /* Polygon Stippling */
-   if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) {
+   if (ctx->Polygon.StippleFlag && primitive == GL_POLYGON) {
       stipple_polygon_span(ctx, span);
    }
 
@@ -671,31 +712,46 @@ _mesa_write_index_span( GLcontext *ctx, struct sw_span *span,
 
    if (swrast->_RasterMask & MULTI_DRAW_BIT) {
       /* draw to zero or two or more buffers */
-      multi_write_index_span( ctx, span->end, span->x, span->y,
-                             span->color.index, span->mask );
+      multi_write_index_span(ctx, span);
    }
    else {
       /* normal situation: draw to exactly one buffer */
       if (ctx->Color.IndexLogicOpEnabled) {
-         _mesa_logicop_ci_span( ctx, span->end, span->x, span->y,
-                               span->color.index, span->mask );
+         _mesa_logicop_ci_span(ctx, span, span->color.index);
       }
 
       if (ctx->Color.IndexMask != 0xffffffff) {
-         _mesa_mask_index_span( ctx, span->end, span->x, span->y,
-                                span->color.index );
+         _mesa_mask_index_span(ctx, span, span->color.index);
       }
 
       /* write pixels */
-      if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) {
-         /* all pixels have same color index */
-         (*swrast->Driver.WriteMonoCISpan)( ctx, span->end, span->x, span->y,
-                                            FixedToInt(span->index),
-                                            span->mask );
+      if (span->arrayMask & SPAN_XY) {
+         /* array of pixel coords */
+         if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) {
+            /* all pixels have same color index */
+            (*swrast->Driver.WriteMonoCIPixels)(ctx, span->end,
+                                                span->xArray, span->yArray,
+                                                FixedToInt(span->index),
+                                                span->mask);
+         }
+         else {
+            (*swrast->Driver.WriteCI32Pixels)(ctx, span->end, span->xArray,
+                                              span->yArray, span->color.index,
+                                              span->mask );
+         }
       }
       else {
-         (*swrast->Driver.WriteCI32Span)( ctx, span->end, span->x, span->y,
-                                          span->color.index, span->mask );
+         /* horizontal run of pixels */
+         if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) {
+            /* all pixels have same color index */
+            (*swrast->Driver.WriteMonoCISpan)(ctx, span->end, span->x, span->y,
+                                              FixedToInt(span->index),
+                                              span->mask);
+         }
+         else {
+            (*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y,
+                                            span->color.index, span->mask);
+         }
       }
    }
 
@@ -719,27 +775,34 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span,
    const GLuint origArrayMask = span->arrayMask;
    GLboolean monoColor;
 
+   ASSERT(span->end <= MAX_WIDTH);
    ASSERT((span->interpMask & span->arrayMask) == 0);
    ASSERT((span->interpMask | span->arrayMask) & SPAN_RGBA);
+   if (ctx->Fog.Enabled)
+      ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG);
+
+   /*
+     printf("%s()  interp 0x%x  array 0x%x  p=0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask, primitive);
+   */
 
-   MEMSET(span->mask, 1, span->end);
-   span->writeAll = GL_TRUE;
+   if (span->arrayMask & SPAN_MASK) {
+      /* mask was initialized by caller, probably glBitmap */
+      span->writeAll = GL_FALSE;
+   }
+   else {
+      MEMSET(span->mask, 1, span->end);
+      span->writeAll = GL_TRUE;
+   }
 
    /* Determine if we have mono-chromatic colors */
    monoColor = (span->interpMask & SPAN_RGBA) &&
       span->redStep == 0 && span->greenStep == 0 &&
       span->blueStep == 0 && span->alphaStep == 0;
 
-   /* Window clipping */
-   if ((swrast->_RasterMask & WINCLIP_BIT) || primitive == GL_BITMAP) {
-      if (clip_span(ctx, span) == GL_FALSE) {
-         return;
-      }
-   }
-
-   /* Scissor test */
-   if (ctx->Scissor.Enabled) {
-      if (!_mesa_scissor_span(ctx, span)) {
+   /* Clipping */
+   if ((swrast->_RasterMask & CLIP_BIT) || (primitive == GL_BITMAP)
+       || (primitive == GL_POINT)) {
+      if (!clip_span(ctx, span)) {
          return;
       }
    }
@@ -802,11 +865,13 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span,
    /* Fog */
    /* XXX try to simplify the fog code! */
    if (ctx->Fog.Enabled) {
-      if ((span->arrayMask & SPAN_FOG) && !swrast->_PreferPixelFog)
+      if ((span->arrayMask & SPAN_FOG) && !swrast->_PreferPixelFog) {
         _mesa_fog_rgba_pixels_with_array(ctx, span, span->fogArray,
                                           span->color.rgba);
-      else if ((span->interpMask & SPAN_FOG) && !swrast->_PreferPixelFog)
+      }
+      else if ((span->interpMask & SPAN_FOG) && !swrast->_PreferPixelFog) {
          _mesa_fog_rgba_pixels(ctx, span, span->color.rgba);
+      }
       else {
          if ((span->interpMask & SPAN_Z) && (span->arrayMask & SPAN_Z) == 0)
             interpolate_z(ctx, span);
@@ -826,51 +891,63 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span,
    }
 
    if (swrast->_RasterMask & MULTI_DRAW_BIT) {
-      multi_write_rgba_span( ctx, span->end, span->x, span->y,
-                             (const GLchan (*)[4]) span->color.rgba,
-                             span->mask );
+      multi_write_rgba_span(ctx, span);
    }
    else {
       /* normal: write to exactly one buffer */
+#if 1
       if (ctx->Color.ColorLogicOpEnabled) {
-         _mesa_logicop_rgba_span( ctx, span->end, span->x, span->y,
-                                  span->color.rgba, span->mask );
+         _mesa_logicop_rgba_span(ctx, span, span->color.rgba);
          monoColor = GL_FALSE;
       }
       else if (ctx->Color.BlendEnabled) {
-         _mesa_blend_span( ctx, span->end, span->x, span->y,
-                           span->color.rgba, span->mask );
+         _mesa_blend_span(ctx, span, span->color.rgba);
          monoColor = GL_FALSE;
       }
-
+#endif
       /* Color component masking */
       if (colorMask != 0xffffffff) {
-         _mesa_mask_rgba_span( ctx, span->end, span->x, span->y,
-                               span->color.rgba );
+         _mesa_mask_rgba_span(ctx, span, span->color.rgba);
          monoColor = GL_FALSE;
       }
 
       /* write pixels */
-      if (monoColor) {
-         /* all pixels have same color */
-         GLchan color[4];
-         color[RCOMP] = FixedToChan(span->red);
-         color[GCOMP] = FixedToChan(span->green);
-         color[BCOMP] = FixedToChan(span->blue);
-         color[ACOMP] = FixedToChan(span->alpha);
-         (*swrast->Driver.WriteMonoRGBASpan)( ctx, span->end, span->x, span->y,
-                                              color, span->mask);
+      if (span->arrayMask & SPAN_XY) {
+         /* array of pixel coords */
+         /* XXX test for mono color */
+         (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->xArray,
+             span->yArray, (const GLchan (*)[4]) span->color.rgba, span->mask);
+         if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
+            _mesa_write_alpha_pixels(ctx, span->end,
+                                     span->xArray, span->yArray,
+                                     (const GLchan (*)[4]) span->color.rgba,
+                                     span->mask);
+         }
       }
       else {
-         (*swrast->Driver.WriteRGBASpan)( ctx, span->end, span->x, span->y,
+         /* horizontal run of pixels */
+         if (monoColor) {
+            /* all pixels have same color */
+            GLchan color[4];
+            color[RCOMP] = FixedToChan(span->red);
+            color[GCOMP] = FixedToChan(span->green);
+            color[BCOMP] = FixedToChan(span->blue);
+            color[ACOMP] = FixedToChan(span->alpha);
+            (*swrast->Driver.WriteMonoRGBASpan)(ctx, span->end, span->x,
+                                                span->y, color, span->mask);
+            /* XXX software alpha buffer writes! */
+         }
+         else {
+            /* each pixel is a different color */
+            (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y,
                       (const GLchan (*)[4]) span->color.rgba,
-                      span->writeAll ? ((const GLubyte *) NULL) : span->mask );
-      }
-
-      if (swrast->_RasterMask & ALPHABUF_BIT) {
-         _mesa_write_alpha_span( ctx, span->end, span->x, span->y,
+                      span->writeAll ? ((const GLubyte *) NULL) : span->mask);
+            if (swrast->_RasterMask & ALPHABUF_BIT) {
+               _mesa_write_alpha_span(ctx, span->end, span->x, span->y,
                       (const GLchan (*)[4]) span->color.rgba,
-                      span->writeAll ? ((const GLubyte *) NULL) : span->mask );
+                      span->writeAll ? ((const GLubyte *) NULL) : span->mask);
+            }
+         }
       }
    }
 
@@ -918,6 +995,7 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span,
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    const GLuint origArrayMask = span->arrayMask;
 
+   ASSERT(span->end <= MAX_WIDTH);
    ASSERT((span->interpMask & span->arrayMask) == 0);
    ASSERT(ctx->Texture._ReallyEnabled);
 
@@ -925,26 +1003,26 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span,
    printf("%s()  interp 0x%x  array 0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask);
    */
 
-   MEMSET(span->mask, 1, span->end);
-   span->writeAll = GL_TRUE;
-
-   /* clip against window bounds */
-   if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
-      if (clip_span(ctx,span) == GL_FALSE) {
-        return;
-      }
+   if (span->arrayMask & SPAN_MASK) {
+      /* mask was initialized by caller, probably glBitmap */
+      span->writeAll = GL_FALSE;
+   }
+   else {
+      MEMSET(span->mask, 1, span->end);
+      span->writeAll = GL_TRUE;
    }
 
-   /* Scissor test */
-   if (ctx->Scissor.Enabled) {
-      if (_mesa_scissor_span( ctx, span ) == GL_FALSE) {
-         return;
+   /* Clipping */
+   if ((swrast->_RasterMask & CLIP_BIT) || (primitive == GL_BITMAP)
+       || (primitive == GL_POINT)) {
+      if (!clip_span(ctx, span)) {
+        return;
       }
    }
 
    /* Polygon Stippling */
-   if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) {
-      stipple_polygon_span( ctx, span);
+   if (ctx->Polygon.StippleFlag && primitive == GL_POLYGON) {
+      stipple_polygon_span(ctx, span);
    }
 
    /* Need texture coordinates now */
@@ -1052,33 +1130,43 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span,
    }
 
    if (swrast->_RasterMask & MULTI_DRAW_BIT) {
-      multi_write_rgba_span( ctx, span->end, span->x, span->y,
-                             (const GLchan (*)[4]) span->color.rgba,
-                             span->mask );
+      multi_write_rgba_span(ctx, span);
    }
    else {
       /* normal: write to exactly one buffer */
       if (ctx->Color.ColorLogicOpEnabled) {
-         _mesa_logicop_rgba_span( ctx, span->end, span->x, span->y,
-                                  span->color.rgba, span->mask );
+         _mesa_logicop_rgba_span(ctx, span, span->color.rgba);
       }
       else  if (ctx->Color.BlendEnabled) {
-         _mesa_blend_span( ctx, span->end, span->x, span->y,
-                           span->color.rgba, span->mask);
+         _mesa_blend_span(ctx, span, span->color.rgba);
       }
 
       if (colorMask != 0xffffffff) {
-         _mesa_mask_rgba_span( ctx, span->end, span->x, span->y,
-                               span->color.rgba );
+         _mesa_mask_rgba_span(ctx, span, span->color.rgba);
       }
 
-      (*swrast->Driver.WriteRGBASpan)( ctx, span->end, span->x, span->y,
+      if (span->arrayMask & SPAN_XY) {
+         /* array of pixel coords */
+         (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->xArray,
+             span->yArray, (const GLchan (*)[4]) span->color.rgba, span->mask);
+         if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
+            _mesa_write_alpha_pixels(ctx, span->end,
+                                     span->xArray, span->yArray,
+                                     (const GLchan (*)[4]) span->color.rgba,
+                                     span->mask);
+         }
+      }
+      else {
+         /* horizontal run of pixels */
+         (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y,
                                        (const GLchan (*)[4]) span->color.rgba,
-                                       span->writeAll ? NULL : span->mask );
-      if (swrast->_RasterMask & ALPHABUF_BIT) {
-         _mesa_write_alpha_span( ctx, span->end, span->x, span->y,
-                                 (const GLchan (*)[4]) span->color.rgba,
-                                 span->writeAll ? NULL : span->mask );
+                                       span->writeAll ? NULL : span->mask);
+         if (swrast->_RasterMask & ALPHABUF_BIT) {
+            _mesa_write_alpha_span(ctx, span->end, span->x, span->y,
+                                   (const GLchan (*)[4]) span->color.rgba,
+                                   span->writeAll ? NULL : span->mask);
+         }
       }
    }
 
@@ -1133,7 +1221,7 @@ _mesa_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer,
 
       (*swrast->Driver.ReadRGBASpan)( ctx, length, x + skip, y, rgba + skip );
       if (buffer->UseSoftwareAlphaBuffers) {
-         _mesa_read_alpha_span( ctx, length, x + skip, y, rgba + skip );
+         _mesa_read_alpha_span(ctx, length, x + skip, y, rgba + skip);
       }
    }
 }
index 29d161e..809b1ee 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_stencil.c,v 1.17 2002/01/28 00:07:33 brianp Exp $ */
+/* $Id: s_stencil.c,v 1.18 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -37,8 +37,6 @@
 
 
 
-
-
 /* Stencil Logic:
 
 IF stencil test fails THEN
@@ -55,8 +53,6 @@ ENDIF
 */
 
 
-
-
 /*
  * Return the address of a stencil buffer value given the window coords:
  */
@@ -488,7 +484,6 @@ stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
 }
 
 
-
 /*
  * Apply stencil and depth testing to the span of pixels.
  * Both software and hardware stencil buffers are acceptable.
@@ -501,55 +496,8 @@ stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
  *         GL_FALSE - one or more fragments passed the testing
  *
  */
-GLboolean
-_old_stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
-                              const GLdepth z[], GLubyte mask[] )
-{
-   SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   GLstencil stencilRow[MAX_WIDTH];
-   GLstencil *stencil;
-   GLboolean result;
-
-   ASSERT(ctx->Stencil.Enabled);
-   ASSERT(n <= MAX_WIDTH);
-
-   /* Get initial stencil values */
-   if (swrast->Driver.WriteStencilSpan) {
-      ASSERT(swrast->Driver.ReadStencilSpan);
-      /* Get stencil values from the hardware stencil buffer */
-      (*swrast->Driver.ReadStencilSpan)(ctx, n, x, y, stencilRow);
-      stencil = stencilRow;
-   }
-   else {
-      /* software stencil buffer */
-      stencil = STENCIL_ADDRESS(x, y);
-   }
-
-   /* do all the stencil/depth testing/updating */
-   result = stencil_and_ztest_span( ctx, n, x, y, z, stencil, mask );
-
-   if (swrast->Driver.WriteStencilSpan) {
-      /* Write updated stencil values into hardware stencil buffer */
-      (swrast->Driver.WriteStencilSpan)(ctx, n, x, y, stencil, mask );
-   }
-
-   return result;
-}
-
-/*
- * Apply stencil and depth testing to the span of pixels.
- * Both software and hardware stencil buffers are acceptable.
- * Input:  n - number of pixels in the span
- *         x, y - location of leftmost pixel in span
- *         z - array [n] of z values
- *         mask - array [n] of flags  (1=test this pixel, 0=skip the pixel)
- * Output:  mask - array [n] of flags (1=stencil and depth test passed)
- * Return: GL_TRUE - all fragments failed the testing
- *         GL_FALSE - one or more fragments passed the testing
- *
- */
-GLboolean
-_mesa_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span)
+static GLboolean
+stencil_and_ztest_span2(GLcontext *ctx, struct sw_span *span)
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
@@ -1058,6 +1006,20 @@ _mesa_stencil_and_ztest_pixels( GLcontext *ctx,
 
 
 
+GLboolean
+_mesa_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span)
+{
+   if (span->arrayMask & SPAN_XY) {
+      return _mesa_stencil_and_ztest_pixels(ctx, span->end,
+                                            span->xArray, span->yArray,
+                                            span->zArray, span->mask);
+   }
+   else {
+      return stencil_and_ztest_span2(ctx, span);
+   }
+}
+
+
 /*
  * Return a span of stencil values from the stencil buffer.
  * Used for glRead/CopyPixels
index a8a3e33..8c4c3b3 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: s_stencil.h,v 1.4 2001/12/17 04:54:35 brianp Exp $ */
+/* $Id: s_stencil.h,v 1.5 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -33,9 +33,7 @@
 #include "swrast.h"
 
 
-extern GLboolean
-_old_stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
-                              const GLdepth z[], GLubyte mask[] );
+
 extern GLboolean
 _mesa_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span);
 
index 40a8922..9bdc203 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_triangle.c,v 1.53 2002/01/30 16:54:02 brianp Exp $ */
+/* $Id: s_triangle.c,v 1.54 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -158,14 +158,17 @@ static void smooth_rgba_triangle( GLcontext *ctx,
 #define INTERP_RGB 1
 #define INTERP_ALPHA 1
 
-#define RENDER_SPAN( span )                            \
-   ASSERT(span.interpMask & SPAN_RGBA);                        \
-   _mesa_write_rgba_span(ctx, &span, GL_POLYGON);
+#define SETUP_CODE                             \
+   {                                           \
+      /* texturing must be off */              \
+      ASSERT(!ctx->Texture._ReallyEnabled);    \
+      ASSERT(ctx->Light.ShadeModel==GL_SMOOTH);        \
+   }
+
+#define RENDER_SPAN( span )  _mesa_write_rgba_span(ctx, &span, GL_POLYGON)
 
 #include "s_tritemp.h"
 
-   ASSERT(!ctx->Texture._ReallyEnabled);  /* texturing must be off */
-   ASSERT(ctx->Light.ShadeModel==GL_SMOOTH);
 }
 
 
@@ -545,7 +548,8 @@ affine_span(GLcontext *ctx, struct sw_span *span,
       }
       break;
    }
-   ASSERT(span->interpMask & SPAN_RGBA);
+   ASSERT(span->interpMask & SPAN_RGBA); /* XXXX unset */
+   span->interpMask &= ~SPAN_RGBA;
    ASSERT(span->arrayMask & SPAN_RGBA);
    _mesa_write_rgba_span(ctx, span, GL_POLYGON);
 
index 7a69625..b4586c1 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_zoom.c,v 1.12 2002/01/31 00:27:43 brianp Exp $ */
+/* $Id: s_zoom.c,v 1.13 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -53,6 +53,9 @@ zoom_span( GLcontext *ctx, const struct sw_span *span,
    const GLchan (*rgb)[3] = (const GLchan (*)[3]) src;
    const GLuint *indexes = (const GLuint *) src;
 
+   /* no pixel arrays! */
+   ASSERT((span->arrayMask & SPAN_XY) == 0);
+
    INIT_SPAN(zoomed);
    if (format == GL_RGBA || format == GL_RGB) {
       zoomed.z = span->z;
index 93263ff..9359b26 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: swrast.h,v 1.19 2002/01/28 04:25:56 brianp Exp $ */
+/* $Id: swrast.h,v 1.20 2002/02/02 17:24:11 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -95,6 +95,8 @@ typedef struct {
 #define SPAN_LAMBDA       0x080
 #define SPAN_COVERAGE     0x100
 #define SPAN_FLAT         0x200  /* flat shading? */
+#define SPAN_XY           0x400  /* arrayMask only - for xArray, yArray */
+#define SPAN_MASK         0x800  /* arrayMask only */
 
 
 struct sw_span {
@@ -152,6 +154,8 @@ struct sw_span {
       GLuint index[MAX_WIDTH];
    } color;
    GLchan  specArray[MAX_WIDTH][4];
+   GLint   xArray[MAX_WIDTH];  /* X/Y used for point/line rendering only */
+   GLint   yArray[MAX_WIDTH];
    GLdepth zArray[MAX_WIDTH];
    GLfloat fogArray[MAX_WIDTH];
    GLfloat texcoords[MAX_TEXTURE_UNITS][MAX_WIDTH][4];