More span rendering optimizations from Klaus Niederkrueger
authorBrian Paul <brian.paul@tungstengraphics.com>
Mon, 19 Nov 2001 01:18:28 +0000 (01:18 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Mon, 19 Nov 2001 01:18:28 +0000 (01:18 +0000)
src/mesa/swrast/s_span.c
src/mesa/swrast/s_span.h
src/mesa/swrast/s_texture.c
src/mesa/swrast/s_triangle.c

index 2c02e0368e8ef41d4e298725693f2621e3c5da4d..e475da3d042decf25c63ea2d0edfe5ec26d8e212 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_span.c,v 1.18 2001/10/17 23:03:56 brianp Exp $ */
+/* $Id: s_span.c,v 1.19 2001/11/19 01:18:28 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -33,6 +33,7 @@
 
 #include "glheader.h"
 #include "colormac.h"
+#include "context.h"
 #include "macros.h"
 #include "mem.h"
 
@@ -482,7 +483,6 @@ _mesa_write_rgba_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
    GLboolean write_all = GL_TRUE;
    GLchan rgbaBackup[MAX_WIDTH][4];
    GLchan (*rgba)[4];
-   const GLubyte *Null = 0;
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
    /* init mask to 1's (all pixels are to be written) */
@@ -591,13 +591,13 @@ _mesa_write_rgba_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
 
       /* write pixels */
       (*swrast->Driver.WriteRGBASpan)( ctx, n, x, y,
-                                   (const GLchan (*)[4]) rgba,
-                                   write_all ? Null : mask );
+                                 (const GLchan (*)[4]) rgba,
+                                 write_all ? ((const GLubyte *) NULL) : mask );
 
       if (swrast->_RasterMask & ALPHABUF_BIT) {
          _mesa_write_alpha_span( ctx, n, x, y,
                                  (const GLchan (*)[4]) rgba,
-                                 write_all ? Null : mask );
+                                 write_all ? ((const GLubyte *) NULL) : mask );
       }
    }
 }
@@ -626,7 +626,6 @@ _mesa_write_monocolor_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
    GLubyte mask[MAX_WIDTH];
    GLboolean write_all = GL_TRUE;
    GLchan rgba[MAX_WIDTH][4];
-   const GLubyte *Null = 0;
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
    /* init mask to 1's (all pixels are to be written) */
@@ -740,12 +739,12 @@ _mesa_write_monocolor_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
 
          /* write pixels */
          (*swrast->Driver.WriteRGBASpan)( ctx, n, x, y,
-                                      (const GLchan (*)[4]) rgba,
-                                      write_all ? Null : mask );
+                                (const GLchan (*)[4]) rgba,
+                                 write_all ? ((const GLubyte *) NULL) : mask );
          if (swrast->_RasterMask & ALPHABUF_BIT) {
             _mesa_write_alpha_span( ctx, n, x, y,
-                                    (const GLchan (*)[4]) rgba,
-                                    write_all ? Null : mask );
+                                 (const GLchan (*)[4]) rgba,
+                                 write_all ? ((const GLubyte *) NULL) : mask );
          }
       }
    }
@@ -767,7 +766,7 @@ _mesa_write_monocolor_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
          (*swrast->Driver.WriteMonoRGBASpan)( ctx, n, x, y, color, mask );
          if (swrast->_RasterMask & ALPHABUF_BIT) {
             _mesa_write_mono_alpha_span( ctx, n, x, y, (GLchan) color[ACOMP],
-                                         write_all ? Null : mask );
+                                 write_all ? ((const GLubyte *) NULL) : mask );
          }
       }
    }
@@ -801,6 +800,661 @@ add_colors(GLuint n, GLchan rgba[][4], CONST GLchan specular[][4] )
 }
 
 
+/*
+ * Write a horizontal span of textured pixels to the frame buffer.
+ * The color of each pixel is different.
+ * Depth-testing, stenciling, scissor-testing etc. should already 
+ * have been done,
+ * only if alpha-testing is used, depth-testing is still done in this
+ * function.
+ * Input:  n - number of pixels in the span
+ *         x, y - location of leftmost pixel in the span
+ *         z - array of [n] z-values
+ *         s, t - array of (s,t) texture coordinates for each pixel
+ *         lambda - array of texture lambda values
+ *         rgba - array of [n] color components
+ *         mask - masked pixels
+ *         primitive - either GL_POINT, GL_LINE, GL_POLYGON or GL_BITMAP.
+ * Contributed by Klaus Niederkrueger.
+ */
+static void
+masked_texture_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
+                     const GLdepth z[], const GLfloat fog[],
+                     const GLfloat s[], const GLfloat t[],
+                     const GLfloat u[], GLfloat lambda[],
+                     GLchan rgbaIn[][4], CONST GLchan spec[][4],
+                     const GLfloat coverage[], GLubyte mask[],
+                     GLboolean write_all )
+{
+   const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
+   GLchan rgbaBackup[MAX_WIDTH][4];
+   GLchan (*rgba)[4];   /* points to either rgbaIn or rgbaBackup */
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+
+   if (swrast->_RasterMask & MULTI_DRAW_BIT) {
+      /* must make a copy of the colors since they may be modified */
+      MEMCPY(rgbaBackup, rgbaIn, 4 * n * sizeof(GLchan));
+      rgba = rgbaBackup;
+   }
+   else {
+      rgba = rgbaIn;
+   }
+
+
+   ASSERT(ctx->Texture._ReallyEnabled);
+   _swrast_texture_fragments( ctx, 0, n, s, t, u, lambda,
+                             (CONST GLchan (*)[4]) rgba, rgba );
+
+
+   /* Texture with alpha test */
+   if (ctx->Color.AlphaEnabled) {
+      /* Do the alpha test */
+      if (_mesa_alpha_test( ctx, n, (const GLchan (*)[4]) rgba, mask ) == 0) {
+         return;
+      }
+      write_all = GL_FALSE;
+      
+      /* Depth test usually in 'rasterize_span' but if alpha test
+         needed, we have to wait for that test before depth test can
+         be done. */
+      if (ctx->Stencil.Enabled) {
+       /* first stencil test */
+       if (_mesa_stencil_and_ztest_span(ctx, n, x, y, z, mask) == GL_FALSE) {
+         return;
+       }
+       write_all = GL_FALSE;
+      }
+      else if (ctx->Depth.Test) {
+       /* regular depth testing */
+       GLuint m = _mesa_depth_test_span( ctx, n, x, y, z, mask );
+       if (m == 0) {
+         return;
+       }
+       if (m < n) {
+         write_all = GL_FALSE;
+       }
+      }
+   }
+
+   /* if we get here, something passed the depth test */
+   ctx->OcclusionResult = GL_TRUE;
+
+
+   /* Add base and specular colors */
+   if (spec &&
+       (ctx->Fog.ColorSumEnabled ||
+       (ctx->Light.Enabled &&
+         ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)))
+      add_colors( n, rgba, spec );   /* rgba = rgba + spec */
+
+   /* Per-pixel fog */
+   if (ctx->Fog.Enabled) {
+      if (fog && !swrast->_PreferPixelFog)
+        _mesa_fog_rgba_pixels( ctx, n, fog, rgba );
+      else
+        _mesa_depth_fog_rgba_pixels( ctx, n, z, rgba );
+   }
+
+   /* Antialias coverage application */
+   if (coverage) {
+      GLuint i;
+      for (i = 0; i < n; i++) {
+         rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]);
+      }
+   }
+
+   if (swrast->_RasterMask & MULTI_DRAW_BIT) {
+      multi_write_rgba_span( ctx, n, x, y, (const GLchan (*)[4]) rgba, mask );
+   }
+   else {
+      /* normal: write to exactly one buffer */
+      if (ctx->Color.ColorLogicOpEnabled) {
+         _mesa_logicop_rgba_span( ctx, n, x, y, rgba, mask );
+      }
+      else  if (ctx->Color.BlendEnabled) {
+         _mesa_blend_span( ctx, n, x, y, rgba, mask );
+      }
+      if (colorMask == 0x0) {
+         return;
+      }
+      else if (colorMask != 0xffffffff) {
+         _mesa_mask_rgba_span( ctx, n, x, y, rgba );
+      }
+
+      (*swrast->Driver.WriteRGBASpan)( ctx, n, x, y, (const GLchan (*)[4])rgba,
+                                   write_all ? NULL : mask );
+      if (swrast->_RasterMask & ALPHABUF_BIT) {
+         _mesa_write_alpha_span( ctx, n, x, y, (const GLchan (*)[4]) rgba,
+                                 write_all ? NULL : mask );
+      }
+   }
+}
+
+
+/*
+ * As above but perform multiple stages of texture application.
+ * Contributed by Klaus Niederkrueger.
+ */
+static void
+masked_multitexture_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
+                          const GLdepth z[], const GLfloat fog[],
+                          CONST GLfloat s[MAX_TEXTURE_UNITS][MAX_WIDTH],
+                          CONST GLfloat t[MAX_TEXTURE_UNITS][MAX_WIDTH],
+                          CONST GLfloat u[MAX_TEXTURE_UNITS][MAX_WIDTH],
+                          GLfloat lambda[][MAX_WIDTH],
+                          GLchan rgbaIn[MAX_TEXTURE_UNITS][4],
+                          CONST GLchan spec[MAX_TEXTURE_UNITS][4],
+                          const GLfloat coverage[], GLubyte mask[],
+                          GLboolean write_all )
+{
+   GLchan rgbaBackup[MAX_WIDTH][4];
+   GLchan (*rgba)[4];   /* points to either rgbaIn or rgbaBackup */
+   GLuint i;
+   const GLuint texUnits = ctx->Const.MaxTextureUnits;
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+
+   if ( (swrast->_RasterMask & MULTI_DRAW_BIT) || texUnits > 1) {
+      /* must make a copy of the colors since they may be modified */
+      MEMCPY(rgbaBackup, rgbaIn, 4 * n * sizeof(GLchan));
+      rgba = rgbaBackup;
+   }
+   else {
+      rgba = rgbaIn;
+   }
+
+
+   ASSERT(ctx->Texture._ReallyEnabled);
+   for (i = 0; i < texUnits; i++)
+     _swrast_texture_fragments( ctx, i, n, s[i], t[i], u[i], lambda[i],
+                               (CONST GLchan (*)[4]) rgbaIn, rgba );
+
+   /* Texture with alpha test */
+   if (ctx->Color.AlphaEnabled) {
+      /* Do the alpha test */
+      if (_mesa_alpha_test( ctx, n, (const GLchan (*)[4])rgba, mask ) == 0) {
+         return;
+      }
+      write_all = GL_FALSE;
+      /* Depth test usually in 'rasterize_span' but if alpha test
+         needed, we have to wait for that test before depth test can
+         be done. */
+      if (ctx->Stencil.Enabled) {
+       /* first stencil test */
+       if (_mesa_stencil_and_ztest_span(ctx, n, x, y, z, mask) == GL_FALSE) {
+         return;
+       }
+       write_all = GL_FALSE;
+      }
+      else if (ctx->Depth.Test) {
+       /* regular depth testing */
+       GLuint m = _mesa_depth_test_span( ctx, n, x, y, z, mask );
+       if (m == 0) {
+         return;
+       }
+       if (m < n) {
+         write_all = GL_FALSE;
+       }
+      }
+   }
+
+   /* if we get here, something passed the depth test */
+   ctx->OcclusionResult = GL_TRUE;
+
+
+   /* Add base and specular colors */
+   if (spec &&
+       (ctx->Fog.ColorSumEnabled ||
+       (ctx->Light.Enabled &&
+        ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)))
+      add_colors( n, rgba, spec );   /* rgba = rgba + spec */
+
+   /* Per-pixel fog */
+   if (ctx->Fog.Enabled) {
+      if (fog && !swrast->_PreferPixelFog)
+        _mesa_fog_rgba_pixels( ctx, n, fog, rgba );
+      else
+        _mesa_depth_fog_rgba_pixels( ctx, n, z, rgba );
+   }
+
+   /* Antialias coverage application */
+   if (coverage) {
+      GLuint i;
+      for (i = 0; i < n; i++) {
+         rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]);
+      }
+   }
+
+   if (swrast->_RasterMask & MULTI_DRAW_BIT) {
+      multi_write_rgba_span( ctx, n, x, y, (const GLchan (*)[4]) rgba, mask );
+   }
+   else {
+      /* normal: write to exactly one buffer */
+      const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
+
+      if (ctx->Color.ColorLogicOpEnabled) {
+         _mesa_logicop_rgba_span( ctx, n, x, y, rgba, mask );
+      }
+      else  if (ctx->Color.BlendEnabled) {
+         _mesa_blend_span( ctx, n, x, y, rgba, mask );
+      }
+
+      if (colorMask == 0x0) {
+         return;
+      }
+      else if (colorMask != 0xffffffff) {
+         _mesa_mask_rgba_span( ctx, n, x, y, rgba );
+      }
+
+      (*swrast->Driver.WriteRGBASpan)( ctx, n, x, y, (const GLchan (*)[4])rgba,
+                                    write_all ? NULL : mask );
+      if (swrast->_RasterMask & ALPHABUF_BIT) {
+         _mesa_write_alpha_span( ctx, n, x, y, (const GLchan (*)[4])rgba,
+                                 write_all ? NULL : mask );
+      }
+   }
+}
+
+
+/*
+ * Generate arrays of fragment colors, z, fog, texcoords, etc from a
+ * triangle span object.  Then call the span/fragment processsing
+ * functions in s_span.[ch].  This is used by a bunch of the textured
+ * triangle functions.
+ * Contributed by Klaus Niederkrueger.
+ */
+void
+_mesa_rasterize_span(GLcontext *ctx, struct triangle_span *span)
+{
+   DEFARRAY(GLubyte, mask, MAX_WIDTH);
+   DEFMARRAY(GLchan, rgba, MAX_WIDTH, 4);
+   DEFMARRAY(GLchan, spec, MAX_WIDTH, 4);
+   DEFARRAY(GLuint, index, MAX_WIDTH);
+   DEFARRAY(GLuint, z, MAX_WIDTH);
+   DEFARRAY(GLfloat, fog, MAX_WIDTH);
+   DEFARRAY(GLfloat, sTex, MAX_WIDTH);
+   DEFARRAY(GLfloat, tTex, MAX_WIDTH);
+   DEFARRAY(GLfloat, rTex, MAX_WIDTH);
+   DEFARRAY(GLfloat, lambda, MAX_WIDTH);
+   DEFMARRAY(GLfloat, msTex, MAX_TEXTURE_UNITS, MAX_WIDTH);
+   DEFMARRAY(GLfloat, mtTex, MAX_TEXTURE_UNITS, MAX_WIDTH);
+   DEFMARRAY(GLfloat, mrTex, MAX_TEXTURE_UNITS, MAX_WIDTH);
+   DEFMARRAY(GLfloat, mLambda, MAX_TEXTURE_UNITS, MAX_WIDTH);
+
+   GLboolean write_all = GL_TRUE;
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+   CHECKARRAY(mask, return);
+   CHECKARRAY(rgba, return);
+   CHECKARRAY(spec, return);
+   CHECKARRAY(index, return);
+   CHECKARRAY(z, return);
+   CHECKARRAY(fog, return);
+   CHECKARRAY(sTex, return);
+   CHECKARRAY(tTex, return);
+   CHECKARRAY(rTex, return);
+   CHECKARRAY(lambda, return);
+   CHECKARRAY(msTex, return);
+   CHECKARRAY(mtTex, return);
+   CHECKARRAY(mrTex, return);
+   CHECKARRAY(mLambda, return);
+
+   /* init mask to 1's (all pixels are to be written) */
+   MEMSET(mask, 1, span->count);
+
+   if (swrast->_RasterMask & WINCLIP_BIT) {
+      if ((span->count = clip_span(ctx, span->count, span->x, span->y, mask))
+         == 0) {
+        return;
+      }
+      if (mask[0] == 0)
+       write_all = GL_FALSE;
+   }
+
+   /* Do the scissor test */
+   if (ctx->Scissor.Enabled) {
+      if ((span->count = _mesa_scissor_span(ctx, span->count, span->x, span->y, mask )) == 0) {
+         return;
+      }
+      if (mask[0] == 0)
+         write_all = GL_FALSE;
+   }
+
+   /* Polygon Stippling */
+   if (ctx->Polygon.StippleFlag) {
+      stipple_polygon_span( ctx, span->count, span->x, span->y, mask );
+      write_all = GL_FALSE;
+   }
+
+
+
+   if (span->activeMask & SPAN_Z) {
+      if (ctx->Visual.depthBits <= 16) {
+         GLuint i;
+         GLfixed zval = span->z;
+         for (i = 0; i < span->count; i++) {
+            z[i] = FixedToInt(zval);
+            zval += span->zStep;
+         }
+      }
+      else {
+         /* Deep Z buffer, no fixed->int shift */
+         GLuint i;
+         GLfixed zval = span->z;
+         for (i = 0; i < span->count; i++) {
+            z[i] = zval;
+            zval += span->zStep;
+         }
+      }
+   }
+
+   /* Correct order: texturing --> alpha test --> depth test.  But if
+      no alpha test needed, we can do here the depth test and
+      potentially avoid some of the texturing (otherwise alpha test,
+      depth test etc.  happens in masked_texture_span(). */
+   if (!ctx->Color.AlphaEnabled) {
+     if (ctx->Stencil.Enabled) {
+       /* first stencil test */
+       if (_mesa_stencil_and_ztest_span(ctx, span->count, span->x,
+                                       span->y, z, mask) == GL_FALSE) {
+        return;
+       }
+       write_all = GL_FALSE;
+     }
+     else if (ctx->Depth.Test) {
+       /* regular depth testing */
+       GLuint m = _mesa_depth_test_span( ctx, span->count, span->x,
+                                        span->y, z, mask );
+       if (m == 0) {
+         return;
+       }
+       if (m < span->count) {
+         write_all = GL_FALSE;
+       }
+     }
+   }
+
+   if (span->activeMask & SPAN_RGBA) {
+      if (span->activeMask & SPAN_FLAT) {
+         GLuint i;
+         GLchan color[4];
+         color[RCOMP] = FixedToChan(span->red);
+         color[GCOMP] = FixedToChan(span->green);
+         color[BCOMP] = FixedToChan(span->blue);
+         color[ACOMP] = FixedToChan(span->alpha);
+         for (i = 0; i < span->count; i++) {
+            COPY_CHAN4(rgba[i], color);
+         }
+      }
+      else {
+         /* smooth interpolation */
+#if CHAN_TYPE == GL_FLOAT
+         GLfloat r = span->red;
+         GLfloat g = span->green;
+         GLfloat b = span->blue;
+         GLfloat a = span->alpha;
+#else
+         GLfixed r = span->red;
+         GLfixed g = span->green;
+         GLfixed b = span->blue;
+         GLfixed a = span->alpha;
+#endif
+         GLuint i;
+         for (i = 0; i < span->count; i++) {
+            rgba[i][RCOMP] = FixedToChan(r);
+            rgba[i][GCOMP] = FixedToChan(g);
+            rgba[i][BCOMP] = FixedToChan(b);
+            rgba[i][ACOMP] = FixedToChan(a);
+            r += span->redStep;
+            g += span->greenStep;
+            b += span->blueStep;
+            a += span->alphaStep;
+         }
+      }
+   }
+
+   if (span->activeMask & SPAN_SPEC) {
+      if (span->activeMask & SPAN_FLAT) {
+         const GLchan r = FixedToChan(span->specRed);
+         const GLchan g = FixedToChan(span->specGreen);
+         const GLchan b = FixedToChan(span->specBlue);
+         GLuint i;
+         for (i = 0; i < span->count; i++) {
+            spec[i][RCOMP] = r;
+            spec[i][GCOMP] = g;
+            spec[i][BCOMP] = b;
+         }
+      }
+      else {
+         /* smooth interpolation */
+#if CHAN_TYPE == GL_FLOAT
+         GLfloat r = span->specRed;
+         GLfloat g = span->specGreen;
+         GLfloat b = span->specBlue;
+#else
+         GLfixed r = span->specRed;
+         GLfixed g = span->specGreen;
+         GLfixed b = span->specBlue;
+#endif
+         GLuint i;
+         for (i = 0; i < span->count; i++) {
+            spec[i][RCOMP] = FixedToChan(r);
+            spec[i][GCOMP] = FixedToChan(g);
+            spec[i][BCOMP] = FixedToChan(b);
+            r += span->specRedStep;
+            g += span->specGreenStep;
+            b += span->specBlueStep;
+         }
+      }
+   }
+
+   if (span->activeMask & SPAN_INDEX) {
+      if (span->activeMask & SPAN_FLAT) {
+         GLuint i;
+         const GLint indx = FixedToInt(span->index);
+         for (i = 0; i < span->count; i++) {
+            index[i] = indx;
+         }
+      }
+      else {
+         /* smooth interpolation */
+         GLuint i;
+         GLfixed ind = span->index;
+         for (i = 0; i < span->count; i++) {
+            index[i] = FixedToInt(ind);
+            ind += span->indexStep;
+         }
+      }
+   }
+
+   if (span->activeMask & SPAN_FOG) {
+      GLuint i;
+      GLfloat f = span->fog;
+      for (i = 0; i < span->count; i++) {
+         fog[i] = f;
+         f += span->fogStep;
+      }
+   }
+   if (span->activeMask & SPAN_TEXTURE) {
+      if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) {
+         /* multitexture */
+         if (span->activeMask & SPAN_LAMBDA) {
+            /* with lambda */
+            GLuint u;
+           /* multitexture, lambda */
+           for (u = 0; u < MAX_TEXTURE_UNITS; u++) {
+               if (ctx->Texture.Unit[u]._ReallyEnabled) {
+                  GLfloat s = span->tex[u][0];
+                  GLfloat t = span->tex[u][1];
+                  GLfloat r = span->tex[u][2];
+                  GLfloat q = span->tex[u][3];
+                  GLuint i;
+                  for (i = 0; i < span->count; i++) {
+                   const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
+                   msTex[u][i] = s * invQ;
+                   mtTex[u][i] = t * invQ;
+                   mrTex[u][i] = r * invQ;
+                   mLambda[u][i] = (GLfloat) 
+                     (log(span->rho[u] * invQ * invQ) * 1.442695F * 0.5F);
+                   s += span->texStep[u][0];
+                   t += span->texStep[u][1];
+                   r += span->texStep[u][2];
+                   q += span->texStep[u][3];
+                  }
+               }
+             }
+         }
+         else {
+           /* without lambda */
+           GLuint u;
+           /* multitexture, no lambda */
+           for (u = 0; u < MAX_TEXTURE_UNITS; u++) {
+               if (ctx->Texture.Unit[u]._ReallyEnabled) {
+                  GLfloat s = span->tex[u][0];
+                  GLfloat t = span->tex[u][1];
+                  GLfloat r = span->tex[u][2];
+                  GLfloat q = span->tex[u][3];
+                  GLuint i;
+                  for (i = 0; i < span->count; i++) {
+                   const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
+                   msTex[u][i] = s * invQ;
+                   mtTex[u][i] = t * invQ;
+                   mrTex[u][i] = r * invQ;
+                   s += span->texStep[u][0];
+                   t += span->texStep[u][1];
+                   r += span->texStep[u][2];
+                   q += span->texStep[u][3];
+                  }
+               }
+             }
+        }
+      }
+      else {
+         /* just texture unit 0 */
+         if (span->activeMask & SPAN_LAMBDA) {
+            /* with lambda */
+            GLfloat s = span->tex[0][0];
+            GLfloat t = span->tex[0][1];
+            GLfloat r = span->tex[0][2];
+            GLfloat q = span->tex[0][3];
+            GLuint i;
+           /* single texture, lambda */
+           for (i = 0; i < span->count; i++) {
+               const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
+               sTex[i] = s * invQ;
+               tTex[i] = t * invQ;
+               rTex[i] = r * invQ;
+               lambda[i] = (GLfloat)
+                 (log(span->rho[0] * invQ * invQ) * 1.442695F * 0.5F);
+               s += span->texStep[0][0];
+               t += span->texStep[0][1];
+               r += span->texStep[0][2];
+               q += span->texStep[0][3];
+             }
+         }
+         else {
+            /* without lambda */
+            GLfloat s = span->tex[0][0];
+            GLfloat t = span->tex[0][1];
+            GLfloat r = span->tex[0][2];
+            GLfloat q = span->tex[0][3];
+            GLuint i;
+           /* single texture, no lambda */
+           for (i = 0; i < span->count; i++) {
+               const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
+               sTex[i] = s * invQ;
+               tTex[i] = t * invQ;
+               rTex[i] = r * invQ;
+               s += span->texStep[0][0];
+               t += span->texStep[0][1];
+               r += span->texStep[0][2];
+               q += span->texStep[0][3];
+           }
+         }
+      }
+   }
+   /* XXX keep this? */
+   if (span->activeMask & SPAN_INT_TEXTURE) {
+      GLint intTexcoord[MAX_WIDTH][2];
+      GLfixed s = span->intTex[0];
+      GLfixed t = span->intTex[1];
+      GLuint i;
+      for (i = 0; i < span->count; i++) {
+         intTexcoord[i][0] = FixedToInt(s);
+         intTexcoord[i][1] = FixedToInt(t);
+         s += span->intTexStep[0];
+         t += span->intTexStep[1];
+      }
+   }
+
+   /* examine activeMask and call a s_span.c function */
+   if (span->activeMask & SPAN_TEXTURE) {
+      const GLfloat *fogPtr;
+      if (span->activeMask & SPAN_FOG)
+         fogPtr = fog;
+      else
+         fogPtr = NULL;
+
+      if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) {
+         if (span->activeMask & SPAN_SPEC) {
+            masked_multitexture_span(ctx, span->count, span->x, span->y,
+                                     z, fogPtr,
+                                     (const GLfloat (*)[MAX_WIDTH]) msTex,
+                                     (const GLfloat (*)[MAX_WIDTH]) mtTex,
+                                     (const GLfloat (*)[MAX_WIDTH]) mrTex,
+                                     (GLfloat (*)[MAX_WIDTH]) mLambda,
+                                     rgba, (CONST GLchan (*)[4]) spec,
+                                     NULL, mask, write_all );
+         }
+         else {
+            masked_multitexture_span(ctx, span->count, span->x, span->y,
+                                     z, fogPtr,
+                                     (const GLfloat (*)[MAX_WIDTH]) msTex,
+                                     (const GLfloat (*)[MAX_WIDTH]) mtTex,
+                                     (const GLfloat (*)[MAX_WIDTH]) mrTex,
+                                     (GLfloat (*)[MAX_WIDTH]) mLambda,
+                                     rgba, NULL, NULL, mask, write_all );
+         }
+      }
+      else {
+         /* single texture */
+         if (span->activeMask & SPAN_SPEC) {
+            masked_texture_span(ctx, span->count, span->x, span->y,
+                                z, fogPtr, sTex, tTex, rTex,
+                                lambda, rgba,
+                                (CONST GLchan (*)[4]) spec,
+                                NULL, mask, write_all);
+         }
+         else {
+            masked_texture_span(ctx, span->count, span->x, span->y,
+                                z, fogPtr, sTex, tTex, rTex, 
+                                lambda, rgba, NULL, NULL,
+                                mask, write_all);
+         }
+      }
+   }
+   else {
+      _mesa_problem(ctx, "rasterize_span() should only be used for texturing");
+   }
+
+   UNDEFARRAY(mask);
+   UNDEFARRAY(rgba);
+   UNDEFARRAY(spec);
+   UNDEFARRAY(index);
+   UNDEFARRAY(z);
+   UNDEFARRAY(fog);
+   UNDEFARRAY(sTex);
+   UNDEFARRAY(tTex);
+   UNDEFARRAY(rTex);
+   UNDEFARRAY(lambda);
+   UNDEFARRAY(msTex);
+   UNDEFARRAY(mtTex);
+   UNDEFARRAY(mrTex);
+   UNDEFARRAY(mLambda);
+}
+
+
 /*
  * Write a horizontal span of textured pixels to the frame buffer.
  * The color of each pixel is different.
@@ -828,7 +1482,6 @@ _mesa_write_texture_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
    GLboolean write_all = GL_TRUE;
    GLchan rgbaBackup[MAX_WIDTH][4];
    GLchan (*rgba)[4];   /* points to either rgbaIn or rgbaBackup */
-   const GLubyte *Null = 0;
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
    /* init mask to 1's (all pixels are to be written) */
@@ -952,10 +1605,10 @@ _mesa_write_texture_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
       }
 
       (*swrast->Driver.WriteRGBASpan)( ctx, n, x, y, (const GLchan (*)[4])rgba,
-                                   write_all ? Null : mask );
+                                 write_all ? ((const GLubyte *) NULL) : mask );
       if (swrast->_RasterMask & ALPHABUF_BIT) {
          _mesa_write_alpha_span( ctx, n, x, y, (const GLchan (*)[4]) rgba,
-                                 write_all ? Null : mask );
+                                 write_all ? ((const GLubyte *) NULL) : mask );
       }
    }
 }
@@ -1123,7 +1776,6 @@ _mesa_write_multitexture_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
 }
 
 
-
 /*
  * Read RGBA pixels from frame buffer.  Clipping will be done to prevent
  * reading ouside the buffer's boundaries.
index 5c5e49c12d048a1955bba7035f8f760f5cd9d0d6..522ec93329c28a00125740c6b1f493e3c0122b08 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_span.h,v 1.6 2001/05/15 21:30:27 brianp Exp $ */
+/* $Id: s_span.h,v 1.7 2001/11/19 01:18:28 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -31,6 +31,7 @@
 
 #include "mtypes.h"
 #include "swrast.h"
+#include "s_trispan.h"
 
 
 extern void
@@ -61,6 +62,10 @@ _mesa_write_monocolor_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
                             GLenum primitive );
 
 
+extern void
+_mesa_rasterize_span(GLcontext *ctx, struct triangle_span *span);
+
+
 extern void
 _mesa_write_texture_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
                           const GLdepth z[], const GLfloat fog[],
index 244022592336f82945bdd1a61369ef1f29559891..e1e1d0f0ceb674f2c72fc6917e183cdf4c0eb958 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_texture.c,v 1.41 2001/10/17 23:03:34 brianp Exp $ */
+/* $Id: s_texture.c,v 1.42 2001/11/19 01:18:28 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -956,6 +956,28 @@ opt_sample_rgba_2d( GLcontext *ctx, GLuint texUnit,
    }
 }
 
+#ifdef DEBUG
+static int
+span_is_monotonous (GLuint n, const GLfloat lambda[])
+{
+  GLuint i;
+
+  if (n <= 1) /* array too short */
+    return GL_TRUE;
+  else if (lambda[0] >= lambda[n-1]) { /* decreasing */
+    for (i=0; i<n-1; i++)
+      if (lambda[i] < lambda[i+1])
+       return GL_FALSE;
+  }
+  else { /* increasing */
+    for (i=0; i<n-1; i++)
+      if (lambda[i] > lambda[i+1])
+       return GL_FALSE;
+  }
+
+  return GL_TRUE;
+}
+#endif /* DEBUG */
 
 /*
  * Given an array of (s,t) texture coordinate and lambda (level of detail)
@@ -973,6 +995,10 @@ sample_lambda_2d( GLcontext *ctx, GLuint texUnit,
    GLuint i;
    (void) u;
 
+#ifdef DEBUG
+   ASSERT (span_is_monotonous(n, lambda) == GL_TRUE);
+#endif /* DEBUG */
+
    /* since lambda is monotonous-array use this check first */
    if (lambda[0] <= minMagThresh && lambda[n-1] <= minMagThresh) {
       /* magnification for whole span */
index 02c27d52968ec506fa59488f1184217e6b4afd8d..7d6a87ddfaca5d72298bb244700ea4630cb12ab7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_triangle.c,v 1.39 2001/09/19 22:21:13 brianp Exp $ */
+/* $Id: s_triangle.c,v 1.40 2001/11/19 01:18:28 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -349,7 +349,7 @@ struct affine_info
  * textures with GL_REPLACE, GL_MODULATE, GL_BLEND, GL_DECAL or GL_ADD
  * texture env modes.
  */
-static void
+static INLINE void
 affine_span(GLcontext *ctx, struct triangle_span *span,
             struct affine_info *info)
 {
@@ -694,7 +694,7 @@ struct persp_info
 };
 
 
-static void
+static INLINE void
 fast_persp_span(GLcontext *ctx, struct triangle_span *span,
                struct persp_info *info)
 {
@@ -973,335 +973,6 @@ static void persp_textured_triangle( GLcontext *ctx,
 
 #endif /* CHAN_BITS != GL_FLOAT */
 
-
-/*
- * Generate arrays of fragment colors, z, fog, texcoords, etc from a
- * triangle span object.  Then call the span/fragment processsing
- * functions in s_span.[ch].  This is used by a bunch of the textured
- * triangle functions.
- */
-static void
-rasterize_span(GLcontext *ctx, const struct triangle_span *span)
-{
-   DEFMARRAY(GLchan, rgba, MAX_WIDTH, 4);
-   DEFMARRAY(GLchan, spec, MAX_WIDTH, 4);
-   DEFARRAY(GLuint, index, MAX_WIDTH);
-   DEFARRAY(GLuint, z, MAX_WIDTH);
-   DEFARRAY(GLfloat, fog, MAX_WIDTH);
-   DEFARRAY(GLfloat, sTex, MAX_WIDTH);
-   DEFARRAY(GLfloat, tTex, MAX_WIDTH);
-   DEFARRAY(GLfloat, rTex, MAX_WIDTH);
-   DEFARRAY(GLfloat, lambda, MAX_WIDTH);
-   DEFMARRAY(GLfloat, msTex, MAX_TEXTURE_UNITS, MAX_WIDTH);
-   DEFMARRAY(GLfloat, mtTex, MAX_TEXTURE_UNITS, MAX_WIDTH);
-   DEFMARRAY(GLfloat, mrTex, MAX_TEXTURE_UNITS, MAX_WIDTH);
-   DEFMARRAY(GLfloat, mLambda, MAX_TEXTURE_UNITS, MAX_WIDTH);
-
-   CHECKARRAY(rgba, return);
-   CHECKARRAY(spec, return);
-   CHECKARRAY(index, return);
-   CHECKARRAY(z, return);
-   CHECKARRAY(fog, return);
-   CHECKARRAY(sTex, return);
-   CHECKARRAY(tTex, return);
-   CHECKARRAY(rTex, return);
-   CHECKARRAY(lambda, return);
-   CHECKARRAY(msTex, return);
-   CHECKARRAY(mtTex, return);
-   CHECKARRAY(mrTex, return);
-   CHECKARRAY(mLambda, return);
-
-   if (span->activeMask & SPAN_RGBA) {
-      if (span->activeMask & SPAN_FLAT) {
-         GLuint i;
-         GLchan color[4];
-         color[RCOMP] = FixedToChan(span->red);
-         color[GCOMP] = FixedToChan(span->green);
-         color[BCOMP] = FixedToChan(span->blue);
-         color[ACOMP] = FixedToChan(span->alpha);
-         for (i = 0; i < span->count; i++) {
-            COPY_CHAN4(rgba[i], color);
-         }
-      }
-      else {
-         /* smooth interpolation */
-#if CHAN_TYPE == GL_FLOAT
-         GLfloat r = span->red;
-         GLfloat g = span->green;
-         GLfloat b = span->blue;
-         GLfloat a = span->alpha;
-#else
-         GLfixed r = span->red;
-         GLfixed g = span->green;
-         GLfixed b = span->blue;
-         GLfixed a = span->alpha;
-#endif
-         GLuint i;
-         for (i = 0; i < span->count; i++) {
-            rgba[i][RCOMP] = FixedToChan(r);
-            rgba[i][GCOMP] = FixedToChan(g);
-            rgba[i][BCOMP] = FixedToChan(b);
-            rgba[i][ACOMP] = FixedToChan(a);
-            r += span->redStep;
-            g += span->greenStep;
-            b += span->blueStep;
-            a += span->alphaStep;
-         }
-      }
-   }
-
-   if (span->activeMask & SPAN_SPEC) {
-      if (span->activeMask & SPAN_FLAT) {
-         const GLchan r = FixedToChan(span->specRed);
-         const GLchan g = FixedToChan(span->specGreen);
-         const GLchan b = FixedToChan(span->specBlue);
-         GLuint i;
-         for (i = 0; i < span->count; i++) {
-            spec[i][RCOMP] = r;
-            spec[i][GCOMP] = g;
-            spec[i][BCOMP] = b;
-         }
-      }
-      else {
-         /* smooth interpolation */
-#if CHAN_TYPE == GL_FLOAT
-         GLfloat r = span->specRed;
-         GLfloat g = span->specGreen;
-         GLfloat b = span->specBlue;
-#else
-         GLfixed r = span->specRed;
-         GLfixed g = span->specGreen;
-         GLfixed b = span->specBlue;
-#endif
-         GLuint i;
-         for (i = 0; i < span->count; i++) {
-            spec[i][RCOMP] = FixedToChan(r);
-            spec[i][GCOMP] = FixedToChan(g);
-            spec[i][BCOMP] = FixedToChan(b);
-            r += span->specRedStep;
-            g += span->specGreenStep;
-            b += span->specBlueStep;
-         }
-      }
-   }
-
-   if (span->activeMask & SPAN_INDEX) {
-      if (span->activeMask & SPAN_FLAT) {
-         GLuint i;
-         const GLint indx = FixedToInt(span->index);
-         for (i = 0; i < span->count; i++) {
-            index[i] = indx;
-         }
-      }
-      else {
-         /* smooth interpolation */
-         GLuint i;
-         GLfixed ind = span->index;
-         for (i = 0; i < span->count; i++) {
-            index[i] = FixedToInt(ind);
-            ind += span->indexStep;
-         }
-      }
-   }
-
-   if (span->activeMask & SPAN_Z) {
-      if (ctx->Visual.depthBits <= 16) {
-         GLuint i;
-         GLfixed zval = span->z;
-         for (i = 0; i < span->count; i++) {
-            z[i] = FixedToInt(zval);
-            zval += span->zStep;
-         }
-      }
-      else {
-         /* Deep Z buffer, no fixed->int shift */
-         GLuint i;
-         GLfixed zval = span->z;
-         for (i = 0; i < span->count; i++) {
-            z[i] = zval;
-            zval += span->zStep;
-         }
-      }
-   }
-   if (span->activeMask & SPAN_FOG) {
-      GLuint i;
-      GLfloat f = span->fog;
-      for (i = 0; i < span->count; i++) {
-         fog[i] = f;
-         f += span->fogStep;
-      }
-   }
-   if (span->activeMask & SPAN_TEXTURE) {
-      if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) {
-         /* multitexture */
-         if (span->activeMask & SPAN_LAMBDA) {
-            /* with lambda */
-            GLuint u;
-            for (u = 0; u < MAX_TEXTURE_UNITS; u++) {
-               if (ctx->Texture.Unit[u]._ReallyEnabled) {
-                  GLfloat s = span->tex[u][0];
-                  GLfloat t = span->tex[u][1];
-                  GLfloat r = span->tex[u][2];
-                  GLfloat q = span->tex[u][3];
-                  GLuint i;
-                  for (i = 0; i < span->count; i++) {
-                     const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
-                     msTex[u][i] = s * invQ;
-                     mtTex[u][i] = t * invQ;
-                     mrTex[u][i] = r * invQ;
-                     mLambda[u][i] = (GLfloat) 
-                        (log(span->rho[u] * invQ * invQ) * 1.442695F * 0.5F);
-                     s += span->texStep[u][0];
-                     t += span->texStep[u][1];
-                     r += span->texStep[u][2];
-                     q += span->texStep[u][3];
-                  }
-               }
-            }
-         }
-         else {
-            /* without lambda */
-            GLuint u;
-            for (u = 0; u < MAX_TEXTURE_UNITS; u++) {
-               if (ctx->Texture.Unit[u]._ReallyEnabled) {
-                  GLfloat s = span->tex[u][0];
-                  GLfloat t = span->tex[u][1];
-                  GLfloat r = span->tex[u][2];
-                  GLfloat q = span->tex[u][3];
-                  GLuint i;
-                  for (i = 0; i < span->count; i++) {
-                     const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
-                     msTex[u][i] = s * invQ;
-                     mtTex[u][i] = t * invQ;
-                     mrTex[u][i] = r * invQ;
-                     s += span->texStep[u][0];
-                     t += span->texStep[u][1];
-                     r += span->texStep[u][2];
-                     q += span->texStep[u][3];
-                  }
-               }
-            }
-         }
-      }
-      else {
-         /* just texture unit 0 */
-         if (span->activeMask & SPAN_LAMBDA) {
-            /* with lambda */
-            GLfloat s = span->tex[0][0];
-            GLfloat t = span->tex[0][1];
-            GLfloat r = span->tex[0][2];
-            GLfloat q = span->tex[0][3];
-            GLuint i;
-            for (i = 0; i < span->count; i++) {
-               const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
-               sTex[i] = s * invQ;
-               tTex[i] = t * invQ;
-               rTex[i] = r * invQ;
-               lambda[i] = (GLfloat)
-                  (log(span->rho[0] * invQ * invQ) * 1.442695F * 0.5F);
-               s += span->texStep[0][0];
-               t += span->texStep[0][1];
-               r += span->texStep[0][2];
-               q += span->texStep[0][3];
-            }
-         }
-         else {
-            /* without lambda */
-            GLfloat s = span->tex[0][0];
-            GLfloat t = span->tex[0][1];
-            GLfloat r = span->tex[0][2];
-            GLfloat q = span->tex[0][3];
-            GLuint i;
-            for (i = 0; i < span->count; i++) {
-               const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
-               sTex[i] = s * invQ;
-               tTex[i] = t * invQ;
-               rTex[i] = r * invQ;
-               s += span->texStep[0][0];
-               t += span->texStep[0][1];
-               r += span->texStep[0][2];
-               q += span->texStep[0][3];
-            }
-         }
-      }
-   }
-   /* XXX keep this? */
-   if (span->activeMask & SPAN_INT_TEXTURE) {
-      GLint intTexcoord[MAX_WIDTH][2];
-      GLfixed s = span->intTex[0];
-      GLfixed t = span->intTex[1];
-      GLuint i;
-      for (i = 0; i < span->count; i++) {
-         intTexcoord[i][0] = FixedToInt(s);
-         intTexcoord[i][1] = FixedToInt(t);
-         s += span->intTexStep[0];
-         t += span->intTexStep[1];
-      }
-   }
-
-   /* examine activeMask and call a s_span.c function */
-   if (span->activeMask & SPAN_TEXTURE) {
-      const GLfloat *fogPtr;
-      if (span->activeMask & SPAN_FOG)
-         fogPtr = fog;
-      else
-         fogPtr = NULL;
-
-      if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) {
-         if (span->activeMask & SPAN_SPEC) {
-            _mesa_write_multitexture_span(ctx, span->count, span->x, span->y,
-                                          z, fogPtr,
-                                          (const GLfloat (*)[MAX_WIDTH]) msTex,
-                                          (const GLfloat (*)[MAX_WIDTH]) mtTex,
-                                          (const GLfloat (*)[MAX_WIDTH]) mrTex,
-                                          (GLfloat (*)[MAX_WIDTH]) mLambda,
-                                          rgba, (CONST GLchan (*)[4]) spec,
-                                          NULL, GL_POLYGON );
-         }
-         else {
-            _mesa_write_multitexture_span(ctx, span->count, span->x, span->y,
-                                          z, fogPtr,
-                                          (const GLfloat (*)[MAX_WIDTH]) msTex,
-                                          (const GLfloat (*)[MAX_WIDTH]) mtTex,
-                                          (const GLfloat (*)[MAX_WIDTH]) mrTex,
-                                          (GLfloat (*)[MAX_WIDTH]) mLambda,
-                                          rgba, NULL, NULL, GL_POLYGON);
-         }
-      }
-      else {
-         /* single texture */
-         if (span->activeMask & SPAN_SPEC) {
-            _mesa_write_texture_span(ctx, span->count, span->x, span->y,
-                                     z, fogPtr, sTex, tTex, rTex, lambda,
-                                     rgba, (CONST GLchan (*)[4]) spec,
-                                     NULL, GL_POLYGON);
-         }
-         else {
-            _mesa_write_texture_span(ctx, span->count, span->x, span->y,
-                                     z, fogPtr, sTex, tTex, rTex, lambda,
-                                     rgba, NULL, NULL, GL_POLYGON);
-         }
-      }
-   }
-   else {
-      _mesa_problem(ctx, "rasterize_span() should only be used for texturing");
-   }
-
-   UNDEFARRAY(rgba);
-   UNDEFARRAY(spec);
-   UNDEFARRAY(index);
-   UNDEFARRAY(z);
-   UNDEFARRAY(fog);
-   UNDEFARRAY(sTex);
-   UNDEFARRAY(tTex);
-   UNDEFARRAY(rTex);
-   UNDEFARRAY(lambda);
-   UNDEFARRAY(msTex);
-   UNDEFARRAY(mtTex);
-   UNDEFARRAY(mrTex);
-   UNDEFARRAY(mLambda);
-}
-
                 
 
 
@@ -1400,7 +1071,7 @@ static void general_textured_spec_triangle( GLcontext *ctx,
    span.texHeight[0] = (GLfloat) texImage->Height;                     \
    (void) fixedToDepthShift;
 
-#define RENDER_SPAN( span )   rasterize_span(ctx, &span);
+#define RENDER_SPAN( span )   _mesa_rasterize_span(ctx, &span);
 
 #include "s_tritemp.h"
 }
@@ -1433,7 +1104,7 @@ static void lambda_textured_triangle( GLcontext *ctx,
    span.texHeight[0] = (GLfloat) texImage->Height;                     \
    (void) fixedToDepthShift;
 
-#define RENDER_SPAN( span )   rasterize_span(ctx, &span);
+#define RENDER_SPAN( span )   _mesa_rasterize_span(ctx, &span);
 
 #include "s_tritemp.h"
 }
@@ -1468,7 +1139,7 @@ static void lambda_textured_spec_triangle( GLcontext *ctx,
    span.texHeight[0] = (GLfloat) texImage->Height;                     \
    (void) fixedToDepthShift;
 
-#define RENDER_SPAN( span )   rasterize_span(ctx, &span);
+#define RENDER_SPAN( span )   _mesa_rasterize_span(ctx, &span);
 
 #include "s_tritemp.h"
 }
@@ -1510,7 +1181,7 @@ lambda_multitextured_triangle( GLcontext *ctx,
    }                                                                   \
    (void) fixedToDepthShift;
 
-#define RENDER_SPAN( span )   rasterize_span(ctx, &span);
+#define RENDER_SPAN( span )   _mesa_rasterize_span(ctx, &span);
 
 #include "s_tritemp.h"