From 9bf68ad963ba92b5d1e725f965979042495a5313 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 14 May 2001 16:23:04 +0000 Subject: New triangle rasterization code. Store per-span initial/step values in the new triangle_span struct. Much cleaner code and possibilities for future optimizations. --- src/mesa/drivers/osmesa/osmesa.c | 47 +- src/mesa/drivers/x11/xm_tri.c | 1036 ++++++++++---------- src/mesa/swrast/s_triangle.c | 1930 +++++++++++++++++++------------------- src/mesa/swrast/s_trispan.h | 79 ++ src/mesa/swrast/s_tritemp.h | 567 +++++------ 5 files changed, 1873 insertions(+), 1786 deletions(-) create mode 100644 src/mesa/swrast/s_trispan.h (limited to 'src') diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c index 65ab67798c..c046b18822 100644 --- a/src/mesa/drivers/osmesa/osmesa.c +++ b/src/mesa/drivers/osmesa/osmesa.c @@ -1,4 +1,4 @@ -/* $Id: osmesa.c,v 1.54 2001/05/10 12:22:32 keithw Exp $ */ +/* $Id: osmesa.c,v 1.55 2001/05/14 16:23:04 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -55,6 +55,7 @@ #include "swrast/s_depth.h" #include "swrast/s_lines.h" #include "swrast/s_triangle.h" +#include "swrast/s_trispan.h" #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" @@ -1600,21 +1601,24 @@ static void smooth_rgba_z_triangle( GLcontext *ctx, #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE #define INTERP_RGB 1 #define INTERP_ALPHA 1 -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, len = RIGHT-LEFT; \ - GLchan *img = PIXELADDR4(LEFT, Y); \ - for (i = 0; i < len; i++, img += 4) { \ - GLdepth z = FixedToDepth(ffz); \ +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLchan *img = PIXELADDR4(span.x, span.y); \ + for (i = 0; i < span.count; i++, img += 4) { \ + const GLdepth z = FixedToDepth(span.z); \ if (z < zRow[i]) { \ - PACK_RGBA(img, FixedToInt(ffr), FixedToInt(ffg), \ - FixedToInt(ffb), FixedToInt(ffa)); \ + PACK_RGBA(img, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue), \ + FixedToInt(span.alpha)); \ zRow[i] = z; \ } \ - ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; ffa += fdadx;\ - ffz += fdzdx; \ - } \ -} + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.alpha += span.alphaStep; \ + span.z += span.zStep; \ + } + #ifdef WIN32 #include "..\swrast\s_tritemp.h" #else @@ -1641,19 +1645,18 @@ static void flat_rgba_z_triangle( GLcontext *ctx, PACK_RGBA((GLchan *) &pixel, v0->color[0], v0->color[1], \ v0->color[2], v0->color[3]); -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, len = RIGHT-LEFT; \ - GLuint *img = (GLuint *) PIXELADDR4(LEFT, Y); \ - for (i=0;ixm_buffer, Y); \ - GLint len = RIGHT-LEFT; \ - for (i=0;ixm_buffer, span.y); \ + GLuint i; \ + for (i = 0; i < span.count; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + unsigned long p; \ + PACK_TRUECOLOR(p, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + XMesaPutPixel(img, x, y, p); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } + #include "swrast/s_tritemp.h" } @@ -102,20 +105,22 @@ static void smooth_8A8B8G8R_z_triangle( GLcontext *ctx, #define PIXEL_ADDRESS(X,Y) PIXELADDR4(xmesa->xm_buffer,X,Y) #define PIXEL_TYPE GLuint #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, len = RIGHT-LEFT; \ - for (i=0;ixm_buffer,X,Y) #define PIXEL_TYPE GLuint #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, len = RIGHT-LEFT; \ - for (i=0;ixm_buffer,X,Y) #define PIXEL_TYPE bgr_t #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, len = RIGHT-LEFT; \ - for (i=0;ir = FixedToInt(ffr); \ - ptr->g = FixedToInt(ffg); \ - ptr->b = FixedToInt(ffb); \ - zRow[i] = z; \ - } \ - ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \ - ffz += fdzdx; \ - } \ -} + +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.count; i++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + PIXEL_TYPE *ptr = pRow + i; \ + ptr->r = FixedToInt(span.red); \ + ptr->g = FixedToInt(span.green); \ + ptr->b = FixedToInt(span.blue); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } + #include "swrast/s_tritemp.h" } @@ -201,22 +210,25 @@ static void smooth_TRUEDITHER_z_triangle( GLcontext *ctx, #define INTERP_Z 1 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE #define INTERP_RGB 1 -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, xx = LEFT, yy = FLIP(xmesa->xm_buffer,Y), len = RIGHT-LEFT; \ - for (i=0;ixm_buffer, span.y); \ + for (i = 0; i < span.count; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + unsigned long p; \ + PACK_TRUEDITHER(p, x, y, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + XMesaPutPixel(img, x, y, p); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } + #include "swrast/s_tritemp.h" } @@ -236,20 +248,22 @@ static void smooth_5R6G5B_z_triangle( GLcontext *ctx, #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y) #define PIXEL_TYPE GLushort #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, len = RIGHT-LEFT; \ - for (i=0;ixm_buffer,X,Y) #define PIXEL_TYPE GLushort #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, len = RIGHT-LEFT; \ - GLint yy = FLIP(xmesa->xm_buffer, Y); \ - for (i=0;ixm_buffer, span.y); \ + for (i = 0; i < span.count; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + PACK_TRUEDITHER(pRow[i], x, y, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } + #include "swrast/s_tritemp.h" } @@ -303,21 +319,24 @@ static void smooth_DITHER8_z_triangle( GLcontext *ctx, #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y) #define PIXEL_TYPE GLubyte #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, xx = LEFT, yy = FLIP(xmesa->xm_buffer,Y), len = RIGHT-LEFT; \ - XDITHER_SETUP(yy); \ - for (i=0;ixm_buffer, span.y); \ + XDITHER_SETUP(y); \ + for (i = 0; i < span.count; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + pRow[i] = (PIXEL_TYPE) XDITHER(x, FixedToInt(span.red),\ + FixedToInt(span.green), FixedToInt(span.blue) ); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } + #include "swrast/s_tritemp.h" } @@ -335,25 +354,25 @@ static void smooth_DITHER_z_triangle( GLcontext *ctx, #define INTERP_Z 1 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE #define INTERP_RGB 1 -#define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y) -#define PIXEL_TYPE GLubyte -#define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, xx = LEFT, yy = FLIP(xmesa->xm_buffer,Y), len = RIGHT-LEFT; \ - XDITHER_SETUP(yy); \ - for (i=0;ixm_buffer, span.y); \ + XDITHER_SETUP(y); \ + for (i = 0; i < span.count; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + unsigned long p = XDITHER(x, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + XMesaPutPixel(img, x, y, p); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } + #include "swrast/s_tritemp.h" } @@ -373,21 +392,23 @@ static void smooth_LOOKUP8_z_triangle( GLcontext *ctx, #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y) #define PIXEL_TYPE GLubyte #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, len = RIGHT-LEFT; \ - LOOKUP_SETUP; \ - for (i=0;ixm_buffer,X,Y) #define PIXEL_TYPE GLubyte #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, xx = LEFT, yy = FLIP(xmesa->xm_buffer,Y), len = RIGHT-LEFT; \ - for (i=0;ixm_buffer, span.y); \ + for (i = 0; i < span.count; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + pRow[i] = DITHER_HPCR(x, y, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue) ); \ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } + #include "swrast/s_tritemp.h" } @@ -442,18 +466,18 @@ static void flat_TRUECOLOR_z_triangle( GLcontext *ctx, unsigned long pixel; \ PACK_TRUECOLOR(pixel, v2->color[0], v2->color[1], v2->color[2]); -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, xx = LEFT, yy = FLIP(xmesa->xm_buffer,Y), len = RIGHT-LEFT; \ - for (i=0;ixm_buffer, span.y); \ + for (i = 0; i < span.count; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + XMesaPutPixel(img, x, y, pixel); \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } + #include "swrast/s_tritemp.h" } @@ -475,18 +499,17 @@ static void flat_8A8B8G8R_z_triangle( GLcontext *ctx, #define SETUP_CODE \ unsigned long p = PACK_8B8G8R( v2->color[0], \ v2->color[1], v2->color[2] ); -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, len = RIGHT-LEFT; \ - for (i=0;ixm_buffer,X,Y) #define PIXEL_TYPE GLuint #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define SETUP_CODE \ +#define SETUP_CODE \ unsigned long p = PACK_8R8G8B( v2->color[0], \ v2->color[1], v2->color[2] ); -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, len = RIGHT-LEFT; \ - for (i=0;ixm_buffer,X,Y) #define PIXEL_TYPE bgr_t #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, len = RIGHT-LEFT; \ - for (i=0;ir = color[RCOMP]; \ ptr->g = color[GCOMP]; \ ptr->b = color[BCOMP]; \ zRow[i] = z; \ } \ - ffz += fdzdx; \ - } \ -} + span.z += span.zStep; \ + } + #include "swrast/s_tritemp.h" } @@ -570,21 +591,21 @@ static void flat_TRUEDITHER_z_triangle( GLcontext *ctx, XMesaImage *img = xmesa->xm_buffer->backimage; #define INTERP_Z 1 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, xx = LEFT, yy = FLIP(xmesa->xm_buffer,Y), len = RIGHT-LEFT; \ - for (i=0;icolor[0], \ - v2->color[1], v2->color[2] ); \ - XMesaPutPixel( img, xx, yy, p ); \ - zRow[i] = z; \ - } \ - ffz += fdzdx; \ - } \ -} +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = FLIP(xmesa->xm_buffer, span.y); \ + for (i = 0; i < span.count; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + unsigned long p; \ + PACK_TRUEDITHER(p, x, y, v2->color[0], \ + v2->color[1], v2->color[2]); \ + XMesaPutPixel(img, x, y, p); \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } + #include "swrast/s_tritemp.h" } @@ -603,21 +624,20 @@ static void flat_5R6G5B_z_triangle( GLcontext *ctx, #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y) #define PIXEL_TYPE GLushort #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define SETUP_CODE \ +#define SETUP_CODE \ unsigned long p = PACK_5R6G5B( v2->color[0], \ v2->color[1], v2->color[2] ); -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, len = RIGHT-LEFT; \ - for (i=0;ixm_buffer,X,Y) #define PIXEL_TYPE GLushort #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, len = RIGHT-LEFT; \ - GLint yy = FLIP(xmesa->xm_buffer, Y); \ - for (i=0;ixm_buffer, span.y); \ + for (i = 0; i < span.count; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ if (z < zRow[i]) { \ - PACK_TRUEDITHER(pRow[i], LEFT+i, yy, color[RCOMP], \ + PACK_TRUEDITHER(pRow[i], x, y, color[RCOMP], \ color[GCOMP], color[BCOMP]); \ zRow[i] = z; \ } \ - ffz += fdzdx; \ - } \ -} + span.z += span.zStep; \ + } + #include "swrast/s_tritemp.h" } @@ -672,19 +691,19 @@ static void flat_DITHER8_z_triangle( GLcontext *ctx, #define SETUP_CODE \ FLAT_DITHER_SETUP( v2->color[0], v2->color[1], v2->color[2] ); -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, xx = LEFT, yy = FLIP(xmesa->xm_buffer,Y), len = RIGHT-LEFT; \ - FLAT_DITHER_ROW_SETUP(FLIP(xmesa->xm_buffer, yy)); \ - for (i=0;ixm_buffer, span.y); \ + FLAT_DITHER_ROW_SETUP(FLIP(xmesa->xm_buffer, y)); \ + for (i = 0; i < span.count; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + pRow[i] = (PIXEL_TYPE) FLAT_DITHER(x); \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } + #include "swrast/s_tritemp.h" } @@ -704,20 +723,20 @@ static void flat_DITHER_z_triangle( GLcontext *ctx, #define SETUP_CODE \ FLAT_DITHER_SETUP( v2->color[0], v2->color[1], v2->color[2] ); -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, xx = LEFT, yy = FLIP(xmesa->xm_buffer,Y), len = RIGHT-LEFT; \ - FLAT_DITHER_ROW_SETUP(yy); \ - for (i=0;ixm_buffer, span.y); \ + FLAT_DITHER_ROW_SETUP(y); \ + for (i = 0; i < span.count; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + unsigned long p = FLAT_DITHER(x); \ + XMesaPutPixel(img, x, y, p); \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } + #include "swrast/s_tritemp.h" } @@ -736,22 +755,22 @@ static void flat_HPCR_z_triangle( GLcontext *ctx, #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y) #define PIXEL_TYPE GLubyte #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define SETUP_CODE \ +#define SETUP_CODE \ GLubyte r = v2->color[0]; \ GLubyte g = v2->color[1]; \ GLubyte b = v2->color[2]; -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, xx = LEFT, yy = FLIP(xmesa->xm_buffer,Y), len = RIGHT-LEFT; \ - for (i=0;ixm_buffer, span.y); \ + for (i = 0; i < span.count; i++, x++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + pRow[i] = (PIXEL_TYPE) DITHER_HPCR(x, y, r, g, b); \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } + #include "swrast/s_tritemp.h" } @@ -776,18 +795,17 @@ static void flat_LOOKUP8_z_triangle( GLcontext *ctx, GLubyte g = v2->color[1]; \ GLubyte b = v2->color[2]; \ GLubyte p = LOOKUP(r,g,b); -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint i, len = RIGHT-LEFT; \ - for (i=0;iDriverCtx; XMesaImage *img = xmesa->xm_buffer->backimage; #define INTERP_RGB 1 -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx, yy = FLIP(xmesa->xm_buffer, Y); \ - for (xx=LEFT;xxxm_buffer, span.y); \ + for (i = 0; i < span.count; i++, x++) { \ + unsigned long p; \ + PACK_TRUECOLOR(p, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + XMesaPutPixel(img, x, y, p); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } + #include "swrast/s_tritemp.h" } @@ -831,16 +852,16 @@ static void smooth_8A8B8G8R_triangle( GLcontext *ctx, #define PIXEL_ADDRESS(X,Y) PIXELADDR4(xmesa->xm_buffer,X,Y) #define PIXEL_TYPE GLuint #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx; \ - PIXEL_TYPE *pixel = pRow; \ - for (xx=LEFT;xxxm_buffer,X,Y) #define PIXEL_TYPE GLuint #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx; \ - PIXEL_TYPE *pixel = pRow; \ - for (xx=LEFT;xxxm_buffer,X,Y) #define PIXEL_TYPE bgr_t #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx; \ - PIXEL_TYPE *pixel = pRow; \ - for (xx=LEFT;xxr = FixedToInt(ffr); \ - pixel->g = FixedToInt(ffg); \ - pixel->b = FixedToInt(ffb); \ - ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \ - pixel++; \ - } \ -} +#define RENDER_SPAN( span ) \ + GLuint i; \ + PIXEL_TYPE *pixel = pRow; \ + for (i = 0; i < span.count; i++, pixel++) { \ + pixel->r = FixedToInt(span.red); \ + pixel->g = FixedToInt(span.green); \ + pixel->b = FixedToInt(span.blue); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } + #include "swrast/s_tritemp.h" } @@ -912,17 +933,19 @@ static void smooth_TRUEDITHER_triangle( GLcontext *ctx, XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; XMesaImage *img = xmesa->xm_buffer->backimage; #define INTERP_RGB 1 -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx, yy = FLIP(xmesa->xm_buffer, Y); \ - for (xx=LEFT;xxxm_buffer, span.y); \ + for (i = 0; i < span.count; i++, x++) { \ + unsigned long p; \ + PACK_TRUEDITHER(p, x, y, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + XMesaPutPixel(img, x, y, p ); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } + #include "swrast/s_tritemp.h" } @@ -940,16 +963,16 @@ static void smooth_5R6G5B_triangle( GLcontext *ctx, #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y) #define PIXEL_TYPE GLushort #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx; \ - PIXEL_TYPE *pixel = pRow; \ - for (xx=LEFT;xxxm_buffer,X,Y) #define PIXEL_TYPE GLushort #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx, yy = FLIP(xmesa->xm_buffer, Y); \ - PIXEL_TYPE *pixel = pRow; \ - for (xx=LEFT;xxxm_buffer, span.y); \ + for (i = 0; i < span.count; i++, x++) { \ + PACK_TRUEDITHER(pRow[i], x, y, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } + #include "swrast/s_tritemp.h" } @@ -994,17 +1018,18 @@ static void smooth_DITHER8_triangle( GLcontext *ctx, #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y) #define PIXEL_TYPE GLubyte #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx, yy = FLIP(xmesa->xm_buffer, Y); \ - PIXEL_TYPE *pixel = pRow; \ - XDITHER_SETUP(yy); \ - for (xx=LEFT;xxxm_buffer, span.y); \ + XDITHER_SETUP(y); \ + for (i = 0; i < span.count; i++, x++) { \ + pRow[i] = (PIXEL_TYPE) XDITHER(x, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue) ); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } + #include "swrast/s_tritemp.h" } @@ -1021,17 +1046,19 @@ static void smooth_DITHER_triangle( GLcontext *ctx, XMesaImage *img = xmesa->xm_buffer->backimage; #define INTERP_RGB 1 -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx, yy = FLIP(xmesa->xm_buffer, Y); \ - XDITHER_SETUP(yy); \ - for (xx=LEFT;xxxm_buffer, span.y); \ + XDITHER_SETUP(y); \ + for (i = 0; i < span.count; i++, x++) { \ + unsigned long p = XDITHER(x, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue) ); \ + XMesaPutPixel(img, x, y, p); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } + #include "swrast/s_tritemp.h" } @@ -1050,17 +1077,17 @@ static void smooth_LOOKUP8_triangle( GLcontext *ctx, #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y) #define PIXEL_TYPE GLubyte #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx; \ - PIXEL_TYPE *pixel = pRow; \ - LOOKUP_SETUP; \ - for (xx=LEFT;xxxm_buffer,X,Y) #define PIXEL_TYPE GLubyte #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx, yy = FLIP(xmesa->xm_buffer, Y); \ - PIXEL_TYPE *pixel = pRow; \ - for (xx=LEFT;xxxm_buffer, span.y); \ + for (i = 0; i < span.count; i++, x++) { \ + pRow[i] = DITHER_HPCR(x, y, FixedToInt(span.red), \ + FixedToInt(span.green), FixedToInt(span.blue)); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } + #include "swrast/s_tritemp.h" } @@ -1108,13 +1136,13 @@ static void flat_TRUECOLOR_triangle( GLcontext *ctx, unsigned long pixel; \ PACK_TRUECOLOR(pixel, v2->color[0], v2->color[1], v2->color[2]); -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx, yy = FLIP(xmesa->xm_buffer, Y); \ - for (xx=LEFT;xxxm_buffer, span.y); \ + for (i = 0; i < span.count; i++, x++) { \ + XMesaPutPixel(img, x, y, pixel); \ + } + #include "swrast/s_tritemp.h" } @@ -1132,16 +1160,14 @@ static void flat_8A8B8G8R_triangle( GLcontext *ctx, #define PIXEL_TYPE GLuint #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) #define SETUP_CODE \ - unsigned long p = PACK_8B8G8R( v2->color[0], \ + unsigned long p = PACK_8B8G8R( v2->color[0], \ v2->color[1], v2->color[2] ); -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx; \ - PIXEL_TYPE *pixel = pRow; \ - for (xx=LEFT;xxxm_buffer,X,Y) #define PIXEL_TYPE GLuint #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define SETUP_CODE \ +#define SETUP_CODE \ unsigned long p = PACK_8R8G8B( v2->color[0], \ v2->color[1], v2->color[2] ); -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx; \ - PIXEL_TYPE *pixel = pRow; \ - for (xx=LEFT;xxxm_buffer,X,Y) #define PIXEL_TYPE bgr_t #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx; \ +#define RENDER_SPAN( span ) \ + GLuint i; \ PIXEL_TYPE *pixel = pRow; \ - for (xx=LEFT;xxr = color[RCOMP]; \ pixel->g = color[GCOMP]; \ pixel->b = color[BCOMP]; \ - pixel++; \ - } \ -} + } + #include "swrast/s_tritemp.h" } @@ -1210,16 +1232,17 @@ static void flat_TRUEDITHER_triangle( GLcontext *ctx, { XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; XMesaImage *img = xmesa->xm_buffer->backimage; -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx, yy = FLIP(xmesa->xm_buffer, Y); \ - for (xx=LEFT;xxcolor[0], \ - v2->color[1], v2->color[2] ); \ - XMesaPutPixel( img, xx, yy, p ); \ - } \ -} + +#define RENDER_SPAN( span ) \ + GLuint i; \ + GLint x = span.x, y = FLIP(xmesa->xm_buffer, span.y); \ + for (i = 0; i < span.count; i++, x++) { \ + unsigned long p; \ + PACK_TRUEDITHER(p, x, y, v2->color[0], \ + v2->color[1], v2->color[2] ); \ + XMesaPutPixel(img, x, y, p); \ + } + #include "swrast/s_tritemp.h" } @@ -1240,14 +1263,12 @@ static void flat_5R6G5B_triangle( GLcontext *ctx, #define SETUP_CODE \ unsigned long p = PACK_5R6G5B( v2->color[0], \ v2->color[1], v2->color[2] ); -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx; \ - PIXEL_TYPE *pixel = pRow; \ - for (xx=LEFT;xxxm_buffer,X,Y) #define PIXEL_TYPE GLushort #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx, yy = FLIP(xmesa->xm_buffer, Y); \ - PIXEL_TYPE *pixel = pRow; \ - for (xx=LEFT;xxxm_buffer, span.y); \ + for (i = 0; i < span.count; i++, x++) { \ + PACK_TRUEDITHER(pRow[i], x, y, color[RCOMP], \ + color[GCOMP], color[BCOMP]); \ + } + #include "swrast/s_tritemp.h" } @@ -1293,15 +1313,14 @@ static void flat_DITHER8_triangle( GLcontext *ctx, #define SETUP_CODE \ FLAT_DITHER_SETUP( v2->color[0], v2->color[1], v2->color[2] ); -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx; \ - PIXEL_TYPE *pixel = pRow; \ - FLAT_DITHER_ROW_SETUP(FLIP(xmesa->xm_buffer, Y)); \ - for (xx=LEFT;xxxm_buffer, span.y); \ + FLAT_DITHER_ROW_SETUP(FLIP(xmesa->xm_buffer, y)); \ + for (i = 0; i < span.count; i++, x++) { \ + pRow[i] = (PIXEL_TYPE) FLAT_DITHER(x); \ + } + #include "swrast/s_tritemp.h" } @@ -1319,15 +1338,15 @@ static void flat_DITHER_triangle( GLcontext *ctx, #define SETUP_CODE \ FLAT_DITHER_SETUP( v2->color[0], v2->color[1], v2->color[2] ); -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx, yy = FLIP(xmesa->xm_buffer, Y); \ - FLAT_DITHER_ROW_SETUP(yy); \ - for (xx=LEFT;xxxm_buffer, span.y); \ + FLAT_DITHER_ROW_SETUP(y); \ + for (i = 0; i < span.count; i++, x++) { \ + unsigned long p = FLAT_DITHER(x); \ + XMesaPutPixel(img, x, y, p ); \ + } + #include "swrast/s_tritemp.h" } @@ -1348,14 +1367,13 @@ static void flat_HPCR_triangle( GLcontext *ctx, GLubyte r = v2->color[0]; \ GLubyte g = v2->color[1]; \ GLubyte b = v2->color[2]; -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx, yy = FLIP(xmesa->xm_buffer, Y); \ - PIXEL_TYPE *pixel = pRow; \ - for (xx=LEFT;xxxm_buffer, span.y); \ + for (i = 0; i < span.count; i++, x++) { \ + pRow[i] = (PIXEL_TYPE) DITHER_HPCR(x, y, r, g, b); \ + } + #include "swrast/s_tritemp.h" } @@ -1374,18 +1392,16 @@ static void flat_LOOKUP8_triangle( GLcontext *ctx, #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line) #define SETUP_CODE \ LOOKUP_SETUP; \ - GLubyte r = v2->color[0]; \ - GLubyte g = v2->color[1]; \ - GLubyte b = v2->color[2]; \ + GLubyte r = v2->color[0]; \ + GLubyte g = v2->color[1]; \ + GLubyte b = v2->color[2]; \ GLubyte p = LOOKUP(r,g,b); -#define INNER_LOOP( LEFT, RIGHT, Y ) \ -{ \ - GLint xx; \ - PIXEL_TYPE *pixel = pRow; \ - for (xx=LEFT;xx0) { \ - for (i=0;iindex, GL_POLYGON ); \ - } \ - } +#define RENDER_SPAN( span ) \ + GLdepth zSpan[MAX_WIDTH]; \ + GLfloat fogSpan[MAX_WIDTH]; \ + GLuint i; \ + for (i = 0; i < span.count; i++) { \ + zSpan[i] = FixedToDepth(span.z); \ + span.z += span.zStep; \ + fogSpan[i] = span.fog; \ + span.fog += span.fogStep; \ + } \ + _mesa_write_monoindex_span(ctx, span.count, span.x, span.y, \ + zSpan, fogSpan, v0->index, GL_POLYGON ); #include "s_tritemp.h" } @@ -113,26 +111,21 @@ static void smooth_ci_triangle( GLcontext *ctx, #define INTERP_FOG 1 #define INTERP_INDEX 1 -#define INNER_LOOP( LEFT, RIGHT, Y ) \ - { \ - const GLint n = RIGHT-LEFT; \ - GLint i; \ - GLdepth zspan[MAX_WIDTH]; \ - GLfloat fogspan[MAX_WIDTH]; \ - GLuint index[MAX_WIDTH]; \ - if (n>0) { \ - for (i=0;i0) { \ - for (i=0;icolor, \ - GL_POLYGON ); \ - } \ - } +#define RENDER_SPAN( span ) \ + GLdepth zSpan[MAX_WIDTH]; \ + GLfloat fogSpan[MAX_WIDTH]; \ + GLuint i; \ + for (i = 0; i < span.count; i++) { \ + zSpan[i] = FixedToDepth(span.z); \ + span.z += span.zStep; \ + fogSpan[i] = span.fog; \ + span.fog += span.fogStep; \ + } \ + _mesa_write_monocolor_span(ctx, span.count, span.x, span.y, \ + zSpan, fogSpan, v2->color, GL_POLYGON ); #include "s_tritemp.h" @@ -193,34 +180,28 @@ static void smooth_rgba_triangle( GLcontext *ctx, #define INTERP_RGB 1 #define INTERP_ALPHA 1 -#define INNER_LOOP( LEFT, RIGHT, Y ) \ - { \ - const GLint n = RIGHT-LEFT; \ - GLint i; \ - GLdepth zspan[MAX_WIDTH]; \ - GLchan rgba[MAX_WIDTH][4]; \ - GLfloat fogspan[MAX_WIDTH]; \ - if (n>0) { \ - for (i=0;iTexture.Unit[0].Current2D; \ GLint b = obj->BaseLevel; \ - GLfloat twidth = (GLfloat) obj->Image[b]->Width; \ - GLfloat theight = (GLfloat) obj->Image[b]->Height; \ - GLint twidth_log2 = obj->Image[b]->WidthLog2; \ + const GLfloat twidth = (GLfloat) obj->Image[b]->Width; \ + const GLfloat theight = (GLfloat) obj->Image[b]->Height; \ + const GLint twidth_log2 = obj->Image[b]->WidthLog2; \ const GLchan *texture = (const GLchan *) obj->Image[b]->Data; \ - GLint smask = obj->Image[b]->Width - 1; \ - GLint tmask = obj->Image[b]->Height - 1; \ + const GLint smask = obj->Image[b]->Width - 1; \ + const GLint tmask = obj->Image[b]->Height - 1; \ if (!texture) { \ /* this shouldn't happen */ \ return; \ } -#define INNER_LOOP( LEFT, RIGHT, Y ) \ - { \ - CONST GLint n = RIGHT-LEFT; \ - GLint i; \ - GLchan rgb[MAX_WIDTH][3]; \ - if (n>0) { \ - ffs -= FIXED_HALF; /* off-by-one error? */ \ - fft -= FIXED_HALF; \ - for (i=0;iDriver.WriteRGBSpan)( ctx, n, LEFT, Y, \ - (CONST GLchan (*)[3]) rgb, NULL ); \ - } \ - } +#define RENDER_SPAN( span ) \ + GLchan rgbSpan[MAX_WIDTH][3]; \ + GLuint i; \ + span.intTex[0] -= FIXED_HALF; /* off-by-one error? */ \ + span.intTex[1] -= FIXED_HALF; \ + for (i = 0; i < span.count; i++) { \ + GLint s = FixedToInt(span.intTex[0]) & smask; \ + GLint t = FixedToInt(span.intTex[1]) & tmask; \ + GLint pos = (t << twidth_log2) + s; \ + pos = pos + pos + pos; /* multiply by 3 */ \ + rgbSpan[i][RCOMP] = texture[pos]; \ + rgbSpan[i][GCOMP] = texture[pos+1]; \ + rgbSpan[i][BCOMP] = texture[pos+2]; \ + span.intTex[0] += span.intTexStep[0]; \ + span.intTex[1] += span.intTexStep[1]; \ + } \ + (*swrast->Driver.WriteRGBSpan)(ctx, span.count, span.x, span.y, \ + (CONST GLchan (*)[3]) rgbSpan, NULL ); #include "s_tritemp.h" } @@ -303,6 +280,7 @@ static void simple_z_textured_triangle( GLcontext *ctx, #define INTERP_INT_TEX 1 #define S_SCALE twidth #define T_SCALE theight + #define SETUP_CODE \ SWcontext *swrast = SWRAST_CONTEXT(ctx); \ struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; \ @@ -318,110 +296,58 @@ static void simple_z_textured_triangle( GLcontext *ctx, return; \ } -#define INNER_LOOP( LEFT, RIGHT, Y ) \ - { \ - CONST GLint n = RIGHT-LEFT; \ - GLint i; \ - GLchan rgb[MAX_WIDTH][3]; \ - GLubyte mask[MAX_WIDTH]; \ - if (n>0) { \ - ffs -= FIXED_HALF; /* off-by-one error? */ \ - fft -= FIXED_HALF; \ - for (i=0;iDriver.WriteRGBSpan)( ctx, n, LEFT, Y, \ - (CONST GLchan (*)[3]) rgb, mask ); \ - } \ - } +#define RENDER_SPAN( span ) \ + GLchan rgbSpan[MAX_WIDTH][3]; \ + GLubyte mask[MAX_WIDTH]; \ + GLuint i; \ + span.intTex[0] -= FIXED_HALF; /* off-by-one error? */ \ + span.intTex[1] -= FIXED_HALF; \ + for (i = 0; i < span.count; i++) { \ + const GLdepth z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + GLint s = FixedToInt(span.intTex[0]) & smask; \ + GLint t = FixedToInt(span.intTex[1]) & tmask; \ + GLint pos = (t << twidth_log2) + s; \ + pos = pos + pos + pos; /* multiply by 3 */ \ + rgbSpan[i][RCOMP] = texture[pos]; \ + rgbSpan[i][GCOMP] = texture[pos+1]; \ + rgbSpan[i][BCOMP] = texture[pos+2]; \ + zRow[i] = z; \ + mask[i] = 1; \ + } \ + else { \ + mask[i] = 0; \ + } \ + span.intTex[0] += span.intTexStep[0]; \ + span.intTex[1] += span.intTexStep[1]; \ + span.z += span.zStep; \ + } \ + (*swrast->Driver.WriteRGBSpan)(ctx, span.count, span.x, span.y, \ + (CONST GLchan (*)[3]) rgbSpan, mask ); #include "s_tritemp.h" } -/* - * Render an RGB/RGBA textured triangle without perspective correction. - */ -static void affine_textured_triangle( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) +struct affine_info { -#define INTERP_Z 1 -#define INTERP_FOG 1 -#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE -#define INTERP_RGB 1 -#define INTERP_ALPHA 1 -#define INTERP_INT_TEX 1 -#define S_SCALE twidth -#define T_SCALE theight -#define SETUP_CODE \ - struct gl_texture_unit *unit = ctx->Texture.Unit+0; \ - struct gl_texture_object *obj = unit->Current2D; \ - GLint b = obj->BaseLevel; \ - GLfloat twidth = (GLfloat) obj->Image[b]->Width; \ - GLfloat theight = (GLfloat) obj->Image[b]->Height; \ - GLint twidth_log2 = obj->Image[b]->WidthLog2; \ - const GLchan *texture = (const GLchan *) obj->Image[b]->Data; \ - GLint smask = obj->Image[b]->Width - 1; \ - GLint tmask = obj->Image[b]->Height - 1; \ - GLint format = obj->Image[b]->Format; \ - GLint filter = obj->MinFilter; \ - GLint envmode = unit->EnvMode; \ - GLint comp, tbytesline, tsize; \ - GLfixed er, eg, eb, ea; \ - GLint tr, tg, tb, ta; \ - if (!texture) { \ - /* this shouldn't happen */ \ - return; \ - } \ - if (envmode == GL_BLEND || envmode == GL_ADD) { \ - /* potential off-by-one error here? (1.0f -> 2048 -> 0) */ \ - er = FloatToFixed(unit->EnvColor[RCOMP]); \ - eg = FloatToFixed(unit->EnvColor[GCOMP]); \ - eb = FloatToFixed(unit->EnvColor[BCOMP]); \ - ea = FloatToFixed(unit->EnvColor[ACOMP]); \ - } \ - switch (format) { \ - case GL_ALPHA: \ - case GL_LUMINANCE: \ - case GL_INTENSITY: \ - comp = 1; \ - break; \ - case GL_LUMINANCE_ALPHA: \ - comp = 2; \ - break; \ - case GL_RGB: \ - comp = 3; \ - break; \ - case GL_RGBA: \ - comp = 4; \ - break; \ - default: \ - _mesa_problem(NULL, "Bad texture format in affine_texture_triangle");\ - return; \ - } \ - tbytesline = obj->Image[b]->Width * comp; \ - tsize = obj->Image[b]->Height * tbytesline; + GLenum filter; + GLenum format; + GLenum envmode; + GLint smask, tmask; + GLint twidth_log2; + const GLchan *texture; + GLchan er, eg, eb, ea; + GLint tbytesline, tsize; + GLint fixedToDepthShift; +}; +static void +affine_span(GLcontext *ctx, struct triangle_span *span, + struct affine_info *info) +{ + GLint tr, tg, tb, ta; /* Instead of defining a function for each mode, a test is done * between the outer and inner loops. This is to reduce code size @@ -429,66 +355,75 @@ static void affine_textured_triangle( GLcontext *ctx, * unused variables (for instance tf,sf,ti,si in case of GL_NEAREST). */ -#define NEAREST_RGB \ - tr = tex00[RCOMP]; \ - tg = tex00[GCOMP]; \ - tb = tex00[BCOMP]; \ +#define NEAREST_RGB \ + tr = tex00[RCOMP]; \ + tg = tex00[GCOMP]; \ + tb = tex00[BCOMP]; \ ta = 0xff -#define LINEAR_RGB \ - tr = (ti * (si * tex00[0] + sf * tex01[0]) + \ - tf * (si * tex10[0] + sf * tex11[0])) >> 2 * FIXED_SHIFT; \ - tg = (ti * (si * tex00[1] + sf * tex01[1]) + \ - tf * (si * tex10[1] + sf * tex11[1])) >> 2 * FIXED_SHIFT; \ - tb = (ti * (si * tex00[2] + sf * tex01[2]) + \ - tf * (si * tex10[2] + sf * tex11[2])) >> 2 * FIXED_SHIFT; \ +#define LINEAR_RGB \ + tr = (ti * (si * tex00[0] + sf * tex01[0]) + \ + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * FIXED_SHIFT; \ + tg = (ti * (si * tex00[1] + sf * tex01[1]) + \ + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * FIXED_SHIFT; \ + tb = (ti * (si * tex00[2] + sf * tex01[2]) + \ + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * FIXED_SHIFT; \ ta = 0xff -#define NEAREST_RGBA \ - tr = tex00[RCOMP]; \ - tg = tex00[GCOMP]; \ - tb = tex00[BCOMP]; \ +#define NEAREST_RGBA \ + tr = tex00[RCOMP]; \ + tg = tex00[GCOMP]; \ + tb = tex00[BCOMP]; \ ta = tex00[ACOMP] -#define LINEAR_RGBA \ - tr = (ti * (si * tex00[0] + sf * tex01[0]) + \ - tf * (si * tex10[0] + sf * tex11[0])) >> 2 * FIXED_SHIFT; \ - tg = (ti * (si * tex00[1] + sf * tex01[1]) + \ - tf * (si * tex10[1] + sf * tex11[1])) >> 2 * FIXED_SHIFT; \ - tb = (ti * (si * tex00[2] + sf * tex01[2]) + \ - tf * (si * tex10[2] + sf * tex11[2])) >> 2 * FIXED_SHIFT; \ - ta = (ti * (si * tex00[3] + sf * tex01[3]) + \ +#define LINEAR_RGBA \ + tr = (ti * (si * tex00[0] + sf * tex01[0]) + \ + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * FIXED_SHIFT; \ + tg = (ti * (si * tex00[1] + sf * tex01[1]) + \ + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * FIXED_SHIFT; \ + tb = (ti * (si * tex00[2] + sf * tex01[2]) + \ + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * FIXED_SHIFT; \ + ta = (ti * (si * tex00[3] + sf * tex01[3]) + \ tf * (si * tex10[3] + sf * tex11[3])) >> 2 * FIXED_SHIFT -#define MODULATE \ - dest[RCOMP] = ffr * (tr + 1) >> (FIXED_SHIFT + 8); \ - dest[GCOMP] = ffg * (tg + 1) >> (FIXED_SHIFT + 8); \ - dest[BCOMP] = ffb * (tb + 1) >> (FIXED_SHIFT + 8); \ - dest[ACOMP] = ffa * (ta + 1) >> (FIXED_SHIFT + 8) - -#define DECAL \ - dest[RCOMP] = ((0xff - ta) * ffr + ((ta + 1) * tr << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \ - dest[GCOMP] = ((0xff - ta) * ffg + ((ta + 1) * tg << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \ - dest[BCOMP] = ((0xff - ta) * ffb + ((ta + 1) * tb << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \ - dest[ACOMP] = FixedToInt(ffa) - -#define BLEND \ - dest[RCOMP] = ((0xff - tr) * ffr + (tr + 1) * er) >> (FIXED_SHIFT + 8); \ - dest[GCOMP] = ((0xff - tg) * ffg + (tg + 1) * eg) >> (FIXED_SHIFT + 8); \ - dest[BCOMP] = ((0xff - tb) * ffb + (tb + 1) * eb) >> (FIXED_SHIFT + 8); \ - dest[ACOMP] = ffa * (ta + 1) >> (FIXED_SHIFT + 8) - -#define REPLACE \ - dest[RCOMP] = tr; \ - dest[GCOMP] = tg; \ - dest[BCOMP] = tb; \ +#define MODULATE \ + dest[RCOMP] = span->red * (tr + 1) >> (FIXED_SHIFT + 8); \ + dest[GCOMP] = span->green * (tg + 1) >> (FIXED_SHIFT + 8); \ + dest[BCOMP] = span->blue * (tb + 1) >> (FIXED_SHIFT + 8); \ + dest[ACOMP] = span->alpha * (ta + 1) >> (FIXED_SHIFT + 8) + +#define DECAL \ + dest[RCOMP] = ((0xff - ta) * span->red \ + + ((ta + 1) * tr << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \ + dest[GCOMP] = ((0xff - ta) * span->green \ + + ((ta + 1) * tg << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \ + dest[BCOMP] = ((0xff - ta) * span->blue \ + + ((ta + 1) * tb << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \ + dest[ACOMP] = FixedToInt(span->alpha) + +#define BLEND \ + dest[RCOMP] = ((0xff - tr) * span->red \ + + (tr + 1) * info->er) >> (FIXED_SHIFT + 8); \ + dest[GCOMP] = ((0xff - tg) * span->green \ + + (tg + 1) * info->eg) >> (FIXED_SHIFT + 8); \ + dest[BCOMP] = ((0xff - tb) * span->blue \ + + (tb + 1) * info->eb) >> (FIXED_SHIFT + 8); \ + dest[ACOMP] = span->alpha * (ta + 1) >> (FIXED_SHIFT + 8) + +#define REPLACE \ + dest[RCOMP] = tr; \ + dest[GCOMP] = tg; \ + dest[BCOMP] = tb; \ dest[ACOMP] = ta -#define ADD \ - dest[RCOMP] = ((ffr << 8) + (tr + 1) * er) >> (FIXED_SHIFT + 8); \ - dest[GCOMP] = ((ffg << 8) + (tg + 1) * eg) >> (FIXED_SHIFT + 8); \ - dest[BCOMP] = ((ffb << 8) + (tb + 1) * eb) >> (FIXED_SHIFT + 8); \ - dest[ACOMP] = ffa * (ta + 1) >> (FIXED_SHIFT + 8) +#define ADD \ + dest[RCOMP] = ((span->red << 8) \ + + (tr + 1) * info->er) >> (FIXED_SHIFT + 8); \ + dest[GCOMP] = ((span->green << 8) \ + + (tg + 1) * info->eg) >> (FIXED_SHIFT + 8); \ + dest[BCOMP] = ((span->blue << 8) \ + + (tb + 1) * info->eb) >> (FIXED_SHIFT + 8); \ + dest[ACOMP] = span->alpha * (ta + 1) >> (FIXED_SHIFT + 8) /* shortcuts */ @@ -496,180 +431,251 @@ static void affine_textured_triangle( GLcontext *ctx, #define NEAREST_RGBA_REPLACE *(GLint *)dest = *(GLint *)tex00 -#define SPAN1(DO_TEX,COMP) \ - for (i=0;icount; i++) { \ + GLint s = FixedToInt(span->intTex[0]) & info->smask; \ + GLint t = FixedToInt(span->intTex[1]) & info->tmask; \ + GLint pos = (t << info->twidth_log2) + s; \ + const GLchan *tex00 = info->texture + COMP * pos; \ + zspan[i] = FixedToDepth(span->z); \ + fogspan[i] = span->fog; \ + DO_TEX; \ + span->fog += span->fogStep; \ + span->z += span->zStep; \ + span->red += span->redStep; \ + span->green += span->greenStep; \ + span->blue += span->blueStep; \ + span->alpha += span->alphaStep; \ + span->intTex[0] += span->intTexStep[0]; \ + span->intTex[1] += span->intTexStep[1]; \ + dest += 4; \ } -#define SPAN2(DO_TEX,COMP) \ - for (i=0;icount; i++) { \ + GLint s = FixedToInt(span->intTex[0]) & info->smask; \ + GLint t = FixedToInt(span->intTex[1]) & info->tmask; \ + GLint sf = span->intTex[0] & FIXED_FRAC_MASK; \ + GLint tf = span->intTex[1] & FIXED_FRAC_MASK; \ + GLint si = FIXED_FRAC_MASK - sf; \ + GLint ti = FIXED_FRAC_MASK - tf; \ + GLint pos = (t << info->twidth_log2) + s; \ + const GLchan *tex00 = info->texture + COMP * pos; \ + const GLchan *tex10 = tex00 + info->tbytesline; \ + const GLchan *tex01 = tex00 + COMP; \ + const GLchan *tex11 = tex10 + COMP; \ + (void) ti; \ + (void) si; \ + if (t == info->tmask) { \ + tex10 -= info->tsize; \ + tex11 -= info->tsize; \ + } \ + if (s == info->smask) { \ + tex01 -= info->tbytesline; \ + tex11 -= info->tbytesline; \ + } \ + zspan[i] = FixedToDepth(span->z); \ + fogspan[i] = span->fog; \ + DO_TEX; \ + span->fog += span->fogStep; \ + span->z += span->zStep; \ + span->red += span->redStep; \ + span->green += span->greenStep; \ + span->blue += span->blueStep; \ + span->alpha += span->alphaStep; \ + span->intTex[0] += span->intTexStep[0]; \ + span->intTex[1] += span->intTexStep[1]; \ + dest += 4; \ } -/* here comes the heavy part.. (something for the compiler to chew on) */ -#define INNER_LOOP( LEFT, RIGHT, Y ) \ - { \ - CONST GLint n = RIGHT-LEFT; \ - GLint i; \ - GLdepth zspan[MAX_WIDTH]; \ - GLfloat fogspan[MAX_WIDTH]; \ - GLchan rgba[MAX_WIDTH][4]; \ - if (n>0) { \ - GLchan *dest = rgba[0]; \ - ffs -= FIXED_HALF; /* off-by-one error? */ \ - fft -= FIXED_HALF; \ - switch (filter) { \ - case GL_NEAREST: \ - switch (format) { \ - case GL_RGB: \ - switch (envmode) { \ - case GL_MODULATE: \ - SPAN1(NEAREST_RGB;MODULATE,3); \ - break; \ - case GL_DECAL: \ - case GL_REPLACE: \ - SPAN1(NEAREST_RGB_REPLACE,3); \ - break; \ - case GL_BLEND: \ - SPAN1(NEAREST_RGB;BLEND,3); \ - break; \ - case GL_ADD: \ - SPAN1(NEAREST_RGB;ADD,3); \ - break; \ - default: /* unexpected env mode */ \ - abort(); \ - } \ - break; \ - case GL_RGBA: \ - switch(envmode) { \ - case GL_MODULATE: \ - SPAN1(NEAREST_RGBA;MODULATE,4); \ - break; \ - case GL_DECAL: \ - SPAN1(NEAREST_RGBA;DECAL,4); \ - break; \ - case GL_BLEND: \ - SPAN1(NEAREST_RGBA;BLEND,4); \ - break; \ - case GL_ADD: \ - SPAN1(NEAREST_RGBA;ADD,4); \ - break; \ - case GL_REPLACE: \ - SPAN1(NEAREST_RGBA_REPLACE,4); \ - break; \ - default: /* unexpected env mode */ \ - abort(); \ - } \ - break; \ - } \ - break; \ - case GL_LINEAR: \ - ffs -= FIXED_HALF; \ - fft -= FIXED_HALF; \ - switch (format) { \ - case GL_RGB: \ - switch (envmode) { \ - case GL_MODULATE: \ - SPAN2(LINEAR_RGB;MODULATE,3); \ - break; \ - case GL_DECAL: \ - case GL_REPLACE: \ - SPAN2(LINEAR_RGB;REPLACE,3); \ - break; \ - case GL_BLEND: \ - SPAN2(LINEAR_RGB;BLEND,3); \ - break; \ - case GL_ADD: \ - SPAN2(LINEAR_RGB;ADD,3); \ - break; \ - default: /* unexpected env mode */ \ - abort(); \ - } \ - break; \ - case GL_RGBA: \ - switch (envmode) { \ - case GL_MODULATE: \ - SPAN2(LINEAR_RGBA;MODULATE,4); \ - break; \ - case GL_DECAL: \ - SPAN2(LINEAR_RGBA;DECAL,4); \ - break; \ - case GL_BLEND: \ - SPAN2(LINEAR_RGBA;BLEND,4); \ - break; \ - case GL_ADD: \ - SPAN2(LINEAR_RGBA;ADD,4); \ - break; \ - case GL_REPLACE: \ - SPAN2(LINEAR_RGBA;REPLACE,4); \ - break; \ - default: /* unexpected env mode */ \ - abort(); \ - } \ - break; \ - } \ - break; \ - } \ - _mesa_write_rgba_span(ctx, n, LEFT, Y, zspan, \ - fogspan, \ - rgba, GL_POLYGON); \ - /* explicit kill of variables: */ \ - ffr = ffg = ffb = ffa = 0; \ - } \ - } +#define FixedToDepth(F) ((F) >> fixedToDepthShift) + + GLuint i; + GLdepth zspan[MAX_WIDTH]; + GLfloat fogspan[MAX_WIDTH]; + GLchan rgba[MAX_WIDTH][4]; + GLchan *dest = rgba[0]; + const GLint fixedToDepthShift = info->fixedToDepthShift; + + span->intTex[0] -= FIXED_HALF; + span->intTex[1] -= FIXED_HALF; + switch (info->filter) { + case GL_NEAREST: + switch (info->format) { + case GL_RGB: + switch (info->envmode) { + case GL_MODULATE: + SPAN1(NEAREST_RGB;MODULATE,3); + break; + case GL_DECAL: + case GL_REPLACE: + SPAN1(NEAREST_RGB_REPLACE,3); + break; + case GL_BLEND: + SPAN1(NEAREST_RGB;BLEND,3); + break; + case GL_ADD: + SPAN1(NEAREST_RGB;ADD,3); + break; + default: + abort(); + } + break; + case GL_RGBA: + switch(info->envmode) { + case GL_MODULATE: + SPAN1(NEAREST_RGBA;MODULATE,4); + break; + case GL_DECAL: + SPAN1(NEAREST_RGBA;DECAL,4); + break; + case GL_BLEND: + SPAN1(NEAREST_RGBA;BLEND,4); + break; + case GL_ADD: + SPAN1(NEAREST_RGBA;ADD,4); + break; + case GL_REPLACE: + SPAN1(NEAREST_RGBA_REPLACE,4); + break; + default: + abort(); + } + break; + } + break; + + case GL_LINEAR: + span->intTex[0] -= FIXED_HALF; + span->intTex[1] -= FIXED_HALF; + switch (info->format) { + case GL_RGB: + switch (info->envmode) { + case GL_MODULATE: + SPAN2(LINEAR_RGB;MODULATE,3); + break; + case GL_DECAL: + case GL_REPLACE: + SPAN2(LINEAR_RGB;REPLACE,3); + break; + case GL_BLEND: + SPAN2(LINEAR_RGB;BLEND,3); + break; + case GL_ADD: + SPAN2(LINEAR_RGB;ADD,3); + break; + default: + abort(); + } + break; + case GL_RGBA: + switch (info->envmode) { + case GL_MODULATE: + SPAN2(LINEAR_RGBA;MODULATE,4); + break; + case GL_DECAL: + SPAN2(LINEAR_RGBA;DECAL,4); + break; + case GL_BLEND: + SPAN2(LINEAR_RGBA;BLEND,4); + break; + case GL_ADD: + SPAN2(LINEAR_RGBA;ADD,4); + break; + case GL_REPLACE: + SPAN2(LINEAR_RGBA;REPLACE,4); + break; + default: + abort(); + } break; + } + break; + } + _mesa_write_rgba_span(ctx, span->count, span->x, span->y, + zspan, fogspan, rgba, GL_POLYGON); -#include "s_tritemp.h" #undef SPAN1 #undef SPAN2 +#undef FixedToDepth } +/* + * Render an RGB/RGBA textured triangle without perspective correction. + */ +static void affine_textured_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define INTERP_ALPHA 1 +#define INTERP_INT_TEX 1 +#define S_SCALE twidth +#define T_SCALE theight + +#define SETUP_CODE + struct affine_info info; + struct gl_texture_unit *unit = ctx->Texture.Unit+0; \ + struct gl_texture_object *obj = unit->Current2D; \ + GLint b = obj->BaseLevel; \ + GLfloat twidth = (GLfloat) obj->Image[b]->Width; \ + GLfloat theight = (GLfloat) obj->Image[b]->Height; \ + info.fixedToDepthShift = ctx->Visual.depthBits <= 16 ? FIXED_SHIFT : 0;\ + info.texture = (const GLchan *) obj->Image[b]->Data; \ + info.twidth_log2 = obj->Image[b]->WidthLog2; \ + info.smask = obj->Image[b]->Width - 1; \ + info.tmask = obj->Image[b]->Height - 1; \ + info.format = obj->Image[b]->Format; \ + info.filter = obj->MinFilter; \ + info.envmode = unit->EnvMode; \ + \ + if (info.envmode == GL_BLEND) { \ + /* potential off-by-one error here? (1.0f -> 2048 -> 0) */ \ + info.er = FloatToFixed(unit->EnvColor[RCOMP]); \ + info.eg = FloatToFixed(unit->EnvColor[GCOMP]); \ + info.eb = FloatToFixed(unit->EnvColor[BCOMP]); \ + info.ea = FloatToFixed(unit->EnvColor[ACOMP]); \ + } \ + if (!info.texture) { \ + /* this shouldn't happen */ \ + return; \ + } \ + \ + switch (info.format) { \ + case GL_ALPHA: \ + case GL_LUMINANCE: \ + case GL_INTENSITY: \ + info.tbytesline = obj->Image[b]->Width; \ + break; \ + case GL_LUMINANCE_ALPHA: \ + info.tbytesline = obj->Image[b]->Width * 2; \ + break; \ + case GL_RGB: \ + info.tbytesline = obj->Image[b]->Width * 3; \ + break; \ + case GL_RGBA: \ + info.tbytesline = obj->Image[b]->Width * 4; \ + break; \ + default: \ + _mesa_problem(NULL, "Bad texture format in affine_texture_triangle");\ + return; \ + } \ + info.tsize = obj->Image[b]->Height * info.tbytesline; + +#define RENDER_SPAN( span ) \ + affine_span(ctx, &span, &info); + +#include "s_tritemp.h" + +} + + +#if 0 /* XXX disabled because of texcoord interpolation errors */ /* * Render an perspective corrected RGB/RGBA textured triangle. * The Q (aka V in Mesa) coordinate must be zero such that the divide @@ -681,7 +687,6 @@ static void affine_textured_triangle( GLcontext *ctx, * This function written by Klaus Niederkrueger * Send all questions and bug reports to him. */ -#if 0 /* XXX disabled because of texcoord interpolation errors */ static void near_persp_textured_triangle(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1, @@ -701,6 +706,7 @@ static void near_persp_textured_triangle(GLcontext *ctx, #define INTERP_RGB 1 #define INTERP_ALPHA 1 #define INTERP_TEX 1 + #define SETUP_CODE \ struct gl_texture_unit *unit = ctx->Texture.Unit+0; \ struct gl_texture_object *obj = unit->Current2D; \ @@ -737,15 +743,15 @@ static void near_persp_textured_triangle(GLcontext *ctx, GLint t = (int)(TT * invQ + BIAS) & tmask; \ GLint pos = COMP * ((t << twidth_log2) + s); \ const GLchan *tex00 = texture + pos; \ - zspan[i] = FixedToDepth(ffz); \ - fogspan[i] = ffog; \ + zspan[i] = FixedToDepth(span.z); \ + fogspan[i] = span.fog; \ DO_TEX; \ - ffog += dfogdx; \ - ffz += fdzdx; \ - ffr += fdrdx; \ - ffg += fdgdx; \ - ffb += fdbdx; \ - ffa += fdadx; \ + span.fog += span.fogStep; \ + span.z += span.zStep; \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.alpha += span.alphaStep; \ SS += dSdx; \ TT += dTdx; \ vv += dvdx; \ @@ -907,15 +913,15 @@ static void near_persp_textured_triangle(GLcontext *ctx, if (j>n || j<-100000) \ j = n; \ while (i * Send all questions and bug reports to him. */ -#if 0 /* XXX disabled because of texcoord interpolation errors */ static void lin_persp_textured_triangle( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1, @@ -1433,6 +1439,7 @@ static void lin_persp_textured_triangle( GLcontext *ctx, #define INTERP_RGB 1 #define INTERP_ALPHA 1 #define INTERP_TEX 1 + #define SETUP_CODE \ struct gl_texture_unit *unit = ctx->Texture.Unit+0; \ struct gl_texture_object *obj = unit->Current2D; \ @@ -1483,43 +1490,43 @@ static void lin_persp_textured_triangle( GLcontext *ctx, tsize = theight * tbytesline; -#define SPAN(DO_TEX,COMP) \ - for (i=0;iactiveMask & SPAN_RGBA) { + GLfixed r = span->red; + GLfixed g = span->green; + GLfixed b = span->blue; + GLfixed a = span->alpha; + GLuint i; + for (i = 0; i < span->count; i++) { + rgba[i][RCOMP] = FixedToInt(r); + rgba[i][GCOMP] = FixedToInt(g); + rgba[i][BCOMP] = FixedToInt(b); + rgba[i][ACOMP] = FixedToInt(a); + r += span->redStep; + g += span->greenStep; + b += span->blueStep; + a += span->alphaStep; + } + } + if (span->activeMask & SPAN_SPEC) { + GLfixed r = span->specRed; + GLfixed g = span->specGreen; + GLfixed b = span->specBlue; + GLuint i; + for (i = 0; i < span->count; i++) { + spec[i][RCOMP] = FixedToInt(r); + spec[i][GCOMP] = FixedToInt(g); + spec[i][BCOMP] = FixedToInt(b); + r += span->specRedStep; + g += span->specGreenStep; + b += span->specBlueStep; + } + } + if (span->activeMask & SPAN_INDEX) { + 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.0 : (1.0F / q); + msTex[u][i] = s * invQ; + mtTex[u][i] = t * invQ; + mrTex[u][i] = r * invQ; + mLambda[u][i] = 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.0 : (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.0 : (1.0F / q); + sTex[i] = s * invQ; + tTex[i] = t * invQ; + rTex[i] = r * invQ; + lambda[i] = 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.0 : (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, + 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, 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, + GL_POLYGON); + } + else { + _mesa_write_texture_span(ctx, span->count, span->x, span->y, + z, fogPtr, sTex, tTex, rTex, lambda, + rgba, NULL, GL_POLYGON); + } + } + } + else { + _mesa_problem(ctx, "rasterize_span() should only be used for texturing"); + } +} + + + + /* * Render a smooth-shaded, textured, RGBA triangle. - * Interpolate S,T,U with perspective correction, w/out mipmapping. - * Note: we use texture coordinates S,T,U,V instead of S,T,R,Q because - * R is already used for red. + * Interpolate S,T,R with perspective correction, w/out mipmapping. */ static void general_textured_triangle( GLcontext *ctx, const SWvertex *v0, @@ -1609,73 +1857,60 @@ static void general_textured_triangle( GLcontext *ctx, #define INTERP_RGB 1 #define INTERP_ALPHA 1 #define INTERP_TEX 1 -#define SETUP_CODE \ - GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT); \ - GLint r, g, b, a; \ - if (flat_shade) { \ - r = v2->color[RCOMP]; \ - g = v2->color[GCOMP]; \ - b = v2->color[BCOMP]; \ - a = v2->color[ACOMP]; \ - } -#define INNER_LOOP( LEFT, RIGHT, Y ) \ - { \ - GLint i; \ - const GLint n = RIGHT-LEFT; \ - GLdepth zspan[MAX_WIDTH]; \ - GLfloat fogspan[MAX_WIDTH]; \ - GLchan rgba[MAX_WIDTH][4]; \ - GLfloat s[MAX_WIDTH], t[MAX_WIDTH], u[MAX_WIDTH]; \ - if (n>0) { \ - if (flat_shade) { \ - for (i=0;iTexture.Unit[0]._Current; \ + const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];\ + const GLboolean flatShade = (ctx->Light.ShadeModel==GL_FLAT); \ + GLfixed rFlat, gFlat, bFlat, aFlat; \ + if (flatShade) { \ + rFlat = IntToFixed(v2->color[RCOMP]); \ + gFlat = IntToFixed(v2->color[GCOMP]); \ + bFlat = IntToFixed(v2->color[BCOMP]); \ + aFlat = IntToFixed(v2->color[ACOMP]); \ + } \ + span.texWidth[0] = (GLfloat) texImage->Width; \ + span.texHeight[0] = (GLfloat) texImage->Height; \ + (void) fixedToDepthShift; + +#define RENDER_SPAN( span ) \ + GLdepth zSpan[MAX_WIDTH]; \ + GLfloat fogSpan[MAX_WIDTH]; \ + GLchan rgbaSpan[MAX_WIDTH][4]; \ + GLfloat sSpan[MAX_WIDTH], tSpan[MAX_WIDTH], uSpan[MAX_WIDTH]; \ + GLuint i; \ + if (flatShade) { \ + span.red = rFlat; span.redStep = 0; \ + span.green = gFlat; span.greenStep = 0; \ + span.blue = bFlat; span.blueStep = 0; \ + span.alpha = aFlat; span.alphaStep = 0; \ + } \ + /* NOTE: we could just call rasterize_span() here instead */ \ + for (i = 0; i < span.count; i++) { \ + GLdouble invQ = span.tex[0][3] ? (1.0 / span.tex[0][3]) : 1.0; \ + zSpan[i] = FixedToDepth(span.z); \ + span.z += span.zStep; \ + fogSpan[i] = span.fog; \ + span.fog += span.fogStep; \ + rgbaSpan[i][RCOMP] = FixedToInt(span.red); \ + rgbaSpan[i][GCOMP] = FixedToInt(span.green); \ + rgbaSpan[i][BCOMP] = FixedToInt(span.blue); \ + rgbaSpan[i][ACOMP] = FixedToInt(span.alpha); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.alpha += span.alphaStep; \ + sSpan[i] = span.tex[0][0] * invQ; \ + tSpan[i] = span.tex[0][1] * invQ; \ + uSpan[i] = span.tex[0][2] * invQ; \ + span.tex[0][0] += span.texStep[0][0]; \ + span.tex[0][1] += span.texStep[0][1]; \ + span.tex[0][2] += span.texStep[0][2]; \ + span.tex[0][3] += span.texStep[0][3]; \ + } \ + _mesa_write_texture_span(ctx, span.count, span.x, span.y, \ + zSpan, fogSpan, sSpan, tSpan, uSpan, \ + NULL, rgbaSpan, NULL, GL_POLYGON ); #include "s_tritemp.h" } @@ -1684,18 +1919,12 @@ static void general_textured_triangle( GLcontext *ctx, /* * Render a smooth-shaded, textured, RGBA triangle with separate specular * color interpolation. - * Interpolate S,T,U with perspective correction, w/out mipmapping. - * Note: we use texture coordinates S,T,U,V instead of S,T,R,Q because - * R is already used for red. + * Interpolate texcoords with perspective correction, w/out mipmapping. */ -static void general_textured_spec_triangle1( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2, - GLdepth zspan[MAX_WIDTH], - GLfloat fogspan[MAX_WIDTH], - GLchan rgba[MAX_WIDTH][4], - GLchan spec[MAX_WIDTH][4] ) +static void general_textured_spec_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) { #define INTERP_Z 1 #define INTERP_FOG 1 @@ -1704,84 +1933,37 @@ static void general_textured_spec_triangle1( GLcontext *ctx, #define INTERP_SPEC 1 #define INTERP_ALPHA 1 #define INTERP_TEX 1 -#define SETUP_CODE \ - GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT); \ - GLint r, g, b, a, sr, sg, sb; \ - if (flat_shade) { \ - r = v2->color[RCOMP]; \ - g = v2->color[GCOMP]; \ - b = v2->color[BCOMP]; \ - a = v2->color[ACOMP]; \ - sr = v2->specular[RCOMP]; \ - sg = v2->specular[GCOMP]; \ - sb = v2->specular[BCOMP]; \ - } -#define INNER_LOOP( LEFT, RIGHT, Y ) \ - { \ - GLint i; \ - const GLint n = RIGHT-LEFT; \ - GLfloat s[MAX_WIDTH], t[MAX_WIDTH], u[MAX_WIDTH]; \ - if (n>0) { \ - if (flat_shade) { \ - for (i=0;iTexture.Unit[0]._Current; \ + const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];\ + const GLboolean flatShade = (ctx->Light.ShadeModel == GL_FLAT); \ + GLfixed rFlat, gFlat, bFlat, aFlat; \ + GLfixed srFlat, sgFlat, sbFlat; \ + if (flatShade) { \ + rFlat = IntToFixed(v2->color[RCOMP]); \ + gFlat = IntToFixed(v2->color[GCOMP]); \ + bFlat = IntToFixed(v2->color[BCOMP]); \ + aFlat = IntToFixed(v2->color[ACOMP]); \ + srFlat = IntToFixed(v2->specular[RCOMP]); \ + sgFlat = IntToFixed(v2->specular[GCOMP]); \ + sbFlat = IntToFixed(v2->specular[BCOMP]); \ + } \ + span.texWidth[0] = (GLfloat) texImage->Width; \ + span.texHeight[0] = (GLfloat) texImage->Height; \ + (void) fixedToDepthShift; + +#define RENDER_SPAN( span ) \ + if (flatShade) { \ + span.red = rFlat; span.redStep = 0; \ + span.green = gFlat; span.greenStep = 0; \ + span.blue = bFlat; span.blueStep = 0; \ + span.alpha = aFlat; span.alphaStep = 0; \ + span.specRed = srFlat; span.specRedStep = 0; \ + span.specGreen = sgFlat; span.specGreenStep = 0; \ + span.specBlue = sbFlat; span.specBlueStep = 0; \ + } \ + rasterize_span(ctx, &span); #include "s_tritemp.h" } @@ -1789,102 +1971,54 @@ static void general_textured_spec_triangle1( GLcontext *ctx, /* * Render a smooth-shaded, textured, RGBA triangle. - * Interpolate S,T,U with perspective correction and compute lambda for + * Interpolate S,T,R with perspective correction and compute lambda for * each fragment. Lambda is used to determine whether to use the * minification or magnification filter. If minification and using * mipmaps, lambda is also used to select the texture level of detail. */ -static void lambda_textured_triangle1( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2, - GLfloat s[MAX_WIDTH], - GLfloat t[MAX_WIDTH], - GLfloat u[MAX_WIDTH] ) +static void lambda_textured_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) { #define INTERP_Z 1 #define INTERP_FOG 1 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE #define INTERP_RGB 1 #define INTERP_ALPHA 1 -#define INTERP_LAMBDA 1 #define INTERP_TEX 1 +#define INTERP_LAMBDA 1 #define SETUP_CODE \ const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; \ - const GLint baseLevel = obj->BaseLevel; \ - const struct gl_texture_image *texImage = obj->Image[baseLevel]; \ - const GLfloat twidth = (GLfloat) texImage->Width; \ - const GLfloat theight = (GLfloat) texImage->Height; \ - const GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT); \ - GLint r, g, b, a; \ - if (flat_shade) { \ - r = v2->color[RCOMP]; \ - g = v2->color[GCOMP]; \ - b = v2->color[BCOMP]; \ - a = v2->color[ACOMP]; \ - } - -#define INNER_LOOP( LEFT, RIGHT, Y ) \ - { \ - GLint i; \ - const GLint n = RIGHT-LEFT; \ - GLdepth zspan[MAX_WIDTH]; \ - GLfloat fogspan[MAX_WIDTH]; \ - GLchan rgba[MAX_WIDTH][4]; \ - GLfloat lambda[MAX_WIDTH]; \ - if (n>0) { \ - if (flat_shade) { \ - for (i=0;iImage[obj->BaseLevel];\ + const GLboolean flatShade = (ctx->Light.ShadeModel==GL_FLAT); \ + GLfixed rFlat, gFlat, bFlat, aFlat; \ + GLfixed srFlat, sgFlat, sbFlat; \ + if (flatShade) { \ + rFlat = IntToFixed(v2->color[RCOMP]); \ + gFlat = IntToFixed(v2->color[GCOMP]); \ + bFlat = IntToFixed(v2->color[BCOMP]); \ + aFlat = IntToFixed(v2->color[ACOMP]); \ + srFlat = IntToFixed(v2->specular[RCOMP]); \ + sgFlat = IntToFixed(v2->specular[GCOMP]); \ + sbFlat = IntToFixed(v2->specular[BCOMP]); \ + } \ + span.texWidth[0] = (GLfloat) texImage->Width; \ + span.texHeight[0] = (GLfloat) texImage->Height; \ + (void) fixedToDepthShift; + +#define RENDER_SPAN( span ) \ + if (flatShade) { \ + span.red = rFlat; span.redStep = 0; \ + span.green = gFlat; span.greenStep = 0; \ + span.blue = bFlat; span.blueStep = 0; \ + span.alpha = aFlat; span.alphaStep = 0; \ + span.specRed = srFlat; span.specRedStep = 0; \ + span.specGreen = sgFlat; span.specGreenStep = 0; \ + span.specBlue = sbFlat; span.specBlueStep = 0; \ + } \ + rasterize_span(ctx, &span); #include "s_tritemp.h" } @@ -1893,18 +2027,15 @@ static void lambda_textured_triangle1( GLcontext *ctx, /* * Render a smooth-shaded, textured, RGBA triangle with separate specular * interpolation. - * Interpolate S,T,U with perspective correction and compute lambda for + * Interpolate S,T,R with perspective correction and compute lambda for * each fragment. Lambda is used to determine whether to use the * minification or magnification filter. If minification and using * mipmaps, lambda is also used to select the texture level of detail. */ -static void lambda_textured_spec_triangle1( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2, - GLfloat s[MAX_WIDTH], - GLfloat t[MAX_WIDTH], - GLfloat u[MAX_WIDTH] ) +static void lambda_textured_spec_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) { #define INTERP_Z 1 #define INTERP_FOG 1 @@ -1917,93 +2048,34 @@ static void lambda_textured_spec_triangle1( GLcontext *ctx, #define SETUP_CODE \ const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; \ - const GLint baseLevel = obj->BaseLevel; \ - const struct gl_texture_image *texImage = obj->Image[baseLevel]; \ - const GLfloat twidth = (GLfloat) texImage->Width; \ - const GLfloat theight = (GLfloat) texImage->Height; \ - const GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT); \ - GLint r, g, b, a, sr, sg, sb; \ - if (flat_shade) { \ - r = v2->color[RCOMP]; \ - g = v2->color[GCOMP]; \ - b = v2->color[BCOMP]; \ - a = v2->color[ACOMP]; \ - sr = v2->specular[RCOMP]; \ - sg = v2->specular[GCOMP]; \ - sb = v2->specular[BCOMP]; \ - } - -#define INNER_LOOP( LEFT, RIGHT, Y ) \ - { \ - GLint i; \ - const GLint n = RIGHT-LEFT; \ - GLdepth zspan[MAX_WIDTH]; \ - GLfloat fogspan[MAX_WIDTH]; \ - GLchan spec[MAX_WIDTH][4]; \ - GLchan rgba[MAX_WIDTH][4]; \ - GLfloat lambda[MAX_WIDTH]; \ - if (n>0) { \ - if (flat_shade) { \ - for (i=0;iImage[obj->BaseLevel];\ + const GLboolean flatShade = (ctx->Light.ShadeModel == GL_FLAT); \ + GLfixed rFlat, gFlat, bFlat, aFlat; \ + GLfixed srFlat, sgFlat, sbFlat; \ + if (flatShade) { \ + rFlat = IntToFixed(v2->color[RCOMP]); \ + gFlat = IntToFixed(v2->color[GCOMP]); \ + bFlat = IntToFixed(v2->color[BCOMP]); \ + aFlat = IntToFixed(v2->color[ACOMP]); \ + srFlat = IntToFixed(v2->specular[RCOMP]); \ + sgFlat = IntToFixed(v2->specular[GCOMP]); \ + sbFlat = IntToFixed(v2->specular[BCOMP]); \ + } \ + span.texWidth[0] = (GLfloat) texImage->Width; \ + span.texHeight[0] = (GLfloat) texImage->Height; \ + (void) fixedToDepthShift; + +#define RENDER_SPAN( span ) \ + if (flatShade) { \ + span.red = rFlat; span.redStep = 0; \ + span.green = gFlat; span.greenStep = 0; \ + span.blue = bFlat; span.blueStep = 0; \ + span.alpha = aFlat; span.alphaStep = 0; \ + span.specRed = srFlat; span.specRedStep = 0; \ + span.specGreen = sgFlat; span.specGreenStep = 0; \ + span.specBlue = sbFlat; span.specBlueStep = 0; \ + } \ + rasterize_span(ctx, &span); #include "s_tritemp.h" } @@ -2011,182 +2083,69 @@ static void lambda_textured_spec_triangle1( GLcontext *ctx, /* * This is the big one! - * Interpolate Z, RGB, Alpha, and two sets of texture coordinates. + * Interpolate Z, RGB, Alpha, specular, fog, and N sets of texture coordinates + * with lambda (LOD). * Yup, it's slow. */ static void -lambda_multitextured_triangle1( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2, - GLfloat s[MAX_TEXTURE_UNITS][MAX_WIDTH], - GLfloat t[MAX_TEXTURE_UNITS][MAX_WIDTH], - GLfloat u[MAX_TEXTURE_UNITS][MAX_WIDTH]) +lambda_multitextured_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) { + #define INTERP_Z 1 #define INTERP_FOG 1 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE #define INTERP_RGB 1 #define INTERP_ALPHA 1 +#define INTERP_SPEC 1 #define INTERP_MULTITEX 1 -#define INTERP_MULTILAMBDA 1 +#define INTERP_LAMBDA 1 #define SETUP_CODE \ - GLchan rgba[MAX_WIDTH][4]; \ - const GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT); \ - GLfloat twidth[MAX_TEXTURE_UNITS], theight[MAX_TEXTURE_UNITS]; \ - GLint r, g, b, a; \ - if (flat_shade) { \ - r = v2->color[0]; \ - g = v2->color[1]; \ - b = v2->color[2]; \ - a = v2->color[3]; \ + const GLboolean flatShade = (ctx->Light.ShadeModel == GL_FLAT); \ + GLfixed rFlat, gFlat, bFlat, aFlat; \ + GLfixed srFlat, sgFlat, sbFlat; \ + GLuint u; \ + if (flatShade) { \ + rFlat = IntToFixed(v2->color[RCOMP]); \ + gFlat = IntToFixed(v2->color[GCOMP]); \ + bFlat = IntToFixed(v2->color[BCOMP]); \ + aFlat = IntToFixed(v2->color[ACOMP]); \ + srFlat = IntToFixed(v2->specular[RCOMP]); \ + sgFlat = IntToFixed(v2->specular[GCOMP]); \ + sbFlat = IntToFixed(v2->specular[BCOMP]); \ } \ - { \ - GLuint unit; \ - for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { \ - if (ctx->Texture.Unit[unit]._ReallyEnabled) { \ - const struct gl_texture_object *obj = ctx->Texture.Unit[unit]._Current; \ - const GLint baseLevel = obj->BaseLevel; \ - const struct gl_texture_image *texImage = obj->Image[baseLevel];\ - twidth[unit] = (GLfloat) texImage->Width; \ - theight[unit] = (GLfloat) texImage->Height; \ - } \ - } \ - } - -#define INNER_LOOP( LEFT, RIGHT, Y ) \ - { \ - GLint i; \ - const GLint n = RIGHT-LEFT; \ - GLdepth zspan[MAX_WIDTH]; \ - GLfloat fogspan[MAX_WIDTH]; \ - GLfloat lambda[MAX_TEXTURE_UNITS][MAX_WIDTH]; \ - if (n > 0) { \ - if (flat_shade) { \ - for (i=0;iConst.MaxTextureUnits; unit++) {\ - if (ctx->Texture.Unit[unit]._ReallyEnabled) { \ - GLdouble invQ = 1.0 / vv[unit]; \ - s[unit][i] = ss[unit] * invQ; \ - t[unit][i] = tt[unit] * invQ; \ - u[unit][i] = uu[unit] * invQ; \ - COMPUTE_MULTILAMBDA(lambda[unit][i], invQ, unit); \ - ss[unit] += dsdx[unit]; \ - tt[unit] += dtdx[unit]; \ - uu[unit] += dudx[unit]; \ - vv[unit] += dvdx[unit]; \ - } \ - } \ - } \ - } \ - else { /* smooth shade */ \ - for (i=0;iConst.MaxTextureUnits; unit++) {\ - if (ctx->Texture.Unit[unit]._ReallyEnabled) { \ - GLdouble invQ = 1.0 / vv[unit]; \ - s[unit][i] = ss[unit] * invQ; \ - t[unit][i] = tt[unit] * invQ; \ - u[unit][i] = uu[unit] * invQ; \ - COMPUTE_MULTILAMBDA(lambda[unit][i], invQ, unit); \ - ss[unit] += dsdx[unit]; \ - tt[unit] += dtdx[unit]; \ - uu[unit] += dudx[unit]; \ - vv[unit] += dvdx[unit]; \ - } \ - } \ - } \ - } \ - _mesa_write_multitexture_span(ctx, n, LEFT, Y, zspan, fogspan, \ - (const GLfloat (*)[MAX_WIDTH]) s,\ - (const GLfloat (*)[MAX_WIDTH]) t,\ - (const GLfloat (*)[MAX_WIDTH]) u,\ - (GLfloat (*)[MAX_WIDTH]) lambda, \ - rgba, NULL, GL_POLYGON ); \ + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \ + if (ctx->Texture.Unit[u]._ReallyEnabled) { \ + const struct gl_texture_object *texObj; \ + const struct gl_texture_image *texImage; \ + texObj = ctx->Texture.Unit[u]._Current; \ + texImage = texObj->Image[texObj->BaseLevel]; \ + span.texWidth[u] = (GLfloat) texImage->Width; \ + span.texHeight[u] = (GLfloat) texImage->Height; \ } \ - } + } \ + (void) fixedToDepthShift; + +#define RENDER_SPAN( span ) \ + if (flatShade) { \ + span.red = rFlat; span.redStep = 0; \ + span.green = gFlat; span.greenStep = 0; \ + span.blue = bFlat; span.blueStep = 0; \ + span.alpha = aFlat; span.alphaStep = 0; \ + span.specRed = srFlat; span.specRedStep = 0; \ + span.specGreen = sgFlat; span.specGreenStep = 0; \ + span.specBlue = sbFlat; span.specBlueStep = 0; \ + } \ + rasterize_span(ctx, &span); #include "s_tritemp.h" -} - - -/* - * These wrappers are needed to deal with the 32KB / stack frame limit - * on Mac / PowerPC systems. - */ - -static void general_textured_spec_triangle(GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) -{ - GLdepth zspan[MAX_WIDTH]; - GLfloat fogspan[MAX_WIDTH]; - GLchan rgba[MAX_WIDTH][4], spec[MAX_WIDTH][4]; - general_textured_spec_triangle1(ctx,v0,v1,v2,zspan,fogspan,rgba,spec); -} - -static void lambda_textured_triangle( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) -{ - GLfloat s[MAX_WIDTH], t[MAX_WIDTH], u[MAX_WIDTH]; - lambda_textured_triangle1(ctx,v0,v1,v2,s,t,u); -} - -static void lambda_textured_spec_triangle( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) -{ - GLfloat s[MAX_WIDTH]; - GLfloat t[MAX_WIDTH]; - GLfloat u[MAX_WIDTH]; - lambda_textured_spec_triangle1(ctx,v0,v1,v2,s,t,u); -} - - -static void lambda_multitextured_triangle( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) -{ - - GLfloat s[MAX_TEXTURE_UNITS][MAX_WIDTH]; - GLfloat t[MAX_TEXTURE_UNITS][MAX_WIDTH]; - DEFMARRAY(GLfloat,u,MAX_TEXTURE_UNITS,MAX_WIDTH); - CHECKARRAY(u,return); - - lambda_multitextured_triangle1(ctx,v0,v1,v2,s,t,u); - UNDEFARRAY(u); } - static void occlusion_zless_triangle( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1, @@ -2199,19 +2158,18 @@ static void occlusion_zless_triangle( GLcontext *ctx, #define DO_OCCLUSION_TEST #define INTERP_Z 1 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE -#define INNER_LOOP( LEFT, RIGHT, Y ) \ - { \ - GLint i; \ - const GLint len = RIGHT-LEFT; \ - for (i=0;iOcclusionResult = GL_TRUE; \ - return; \ - } \ - ffz += fdzdx; \ - } \ + +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.count; i++) { \ + GLdepth z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + ctx->OcclusionResult = GL_TRUE; \ + return; \ + } \ + span.z += span.zStep; \ } + #include "s_tritemp.h" } @@ -2335,14 +2293,14 @@ _swrast_choose_triangle( GLcontext *ctx ) && ctx->Texture.Unit[0].EnvMode != GL_COMBINE_EXT) { if (ctx->Hint.PerspectiveCorrection==GL_FASTEST) { if (minFilter == GL_NEAREST - && format == GL_RGB + && format == MESA_FORMAT_RGB && (envMode == GL_REPLACE || envMode == GL_DECAL) - && ((swrast->_RasterMask == DEPTH_BIT + && ((swrast->_RasterMask == (DEPTH_BIT | TEXTURE_BIT) && ctx->Depth.Func == GL_LESS && ctx->Depth.Mask == GL_TRUE) - || swrast->_RasterMask == 0) + || swrast->_RasterMask == TEXTURE_BIT) && ctx->Polygon.StippleFlag == GL_FALSE) { - if (swrast->_RasterMask==DEPTH_BIT) { + if (swrast->_RasterMask == (DEPTH_BIT | TEXTURE_BIT)) { USE(simple_z_textured_triangle); } else { diff --git a/src/mesa/swrast/s_trispan.h b/src/mesa/swrast/s_trispan.h new file mode 100644 index 0000000000..cd577f51ca --- /dev/null +++ b/src/mesa/swrast/s_trispan.h @@ -0,0 +1,79 @@ +/* $Id: s_trispan.h,v 1.1 2001/05/14 16:23:04 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 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"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef S_TRISPAN_H +#define S_TRISPAN_H + + +/* + * The triangle_span structure is used by the triangle template code in + * s_tritemp.h. It describes how colors, Z, texcoords, etc are to be + * interpolated across each scanline of triangle. + * With this structure it's easy to hand-off span rasterization to a + * subroutine instead of doing it all inline like we used to do. + * It also cleans up the local variable namespace a great deal. + * + * It would be interesting to experiment with multiprocessor rasterization + * with this structure. The triangle rasterizer could simply emit a + * stream of these structures which would be consumed by one or more + * span-processing threads which could run in parallel. + */ + + +#define SPAN_RGBA 0x01 +#define SPAN_SPEC 0x02 +#define SPAN_INDEX 0x04 +#define SPAN_Z 0x08 +#define SPAN_FOG 0x10 +#define SPAN_TEXTURE 0x20 +#define SPAN_INT_TEXTURE 0x40 +#define SPAN_LAMBDA 0x80 + + +struct triangle_span { + GLint x, y; + GLuint count; + GLuint activeMask; /* OR of the SPAN_* flags */ + GLfixed red, redStep; + GLfixed green, greenStep; + GLfixed blue, blueStep; + GLfixed alpha, alphaStep; + GLfixed specRed, specRedStep; + GLfixed specGreen, specGreenStep; + GLfixed specBlue, specBlueStep; + GLfixed index, indexStep; + GLfixed z, zStep; + GLfloat fog, fogStep; + GLfloat tex[MAX_TEXTURE_UNITS][4], texStep[MAX_TEXTURE_UNITS][4]; + GLfixed intTex[2], intTexStep[2]; + /* Needed for texture lambda (LOD) computation */ + GLfloat rho[MAX_TEXTURE_UNITS]; + GLfloat texWidth[MAX_TEXTURE_UNITS], texHeight[MAX_TEXTURE_UNITS]; +}; + + +#endif /* S_TRISPAN_H */ diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h index 3bdb1537a0..09e1223506 100644 --- a/src/mesa/swrast/s_tritemp.h +++ b/src/mesa/swrast/s_tritemp.h @@ -1,4 +1,4 @@ -/* $Id: s_tritemp.h,v 1.15 2001/05/03 22:13:32 brianp Exp $ */ +/* $Id: s_tritemp.h,v 1.16 2001/05/14 16:23:04 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -43,9 +43,7 @@ * INTERP_TEX - if defined, interpolate set 0 float STRQ texcoords * NOTE: OpenGL STRQ = Mesa STUV (R was taken for red) * INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords - * INTERP_LAMBDA - if defined, the lambda value is computed at every - * pixel, to apply MIPMAPPING, and min/maxification - * INTERP_MULTILAMBDA - like above but for multitexturing, i.e. + * INTERP_LAMBDA - if defined, compute lambda value (for mipmapping) * a lambda value for every texture unit * * When one can directly address pixels in the color buffer the following @@ -64,20 +62,13 @@ * SETUP_CODE - code which is to be executed once per triangle * * The following macro MUST be defined: - * INNER_LOOP(LEFT,RIGHT,Y) - code to write a span of pixels. - * Something like: - * - * for (x=LEFT; x_backface_sign; GLboolean tiny; + struct triangle_span span; + +#ifdef INTERP_Z + (void) fixedToDepthShift; +#endif + /* find the order of the 3 vertices along the Y axis */ { GLfloat y0 = v0->win[1]; @@ -253,58 +250,47 @@ { GLint ltor; /* true if scanning left-to-right */ #ifdef INTERP_Z - GLfloat dzdx, dzdy; GLfixed fdzdx; + GLfloat dzdx, dzdy; #endif #ifdef INTERP_FOG - GLfloat dfogdx, dfogdy; + GLfloat dfogdy; #endif #ifdef INTERP_RGB - GLfloat drdx, drdy; GLfixed fdrdx; - GLfloat dgdx, dgdy; GLfixed fdgdx; - GLfloat dbdx, dbdy; GLfixed fdbdx; -#endif -#ifdef INTERP_SPEC - GLfloat dsrdx, dsrdy; GLfixed fdsrdx; - GLfloat dsgdx, dsgdy; GLfixed fdsgdx; - GLfloat dsbdx, dsbdy; GLfixed fdsbdx; + GLfloat drdx, drdy; + GLfloat dgdx, dgdy; + GLfloat dbdx, dbdy; #endif #ifdef INTERP_ALPHA - GLfloat dadx, dady; GLfixed fdadx; + GLfloat dadx, dady; +#endif +#ifdef INTERP_SPEC + GLfloat dsrdx, dsrdy; + GLfloat dsgdx, dsgdy; + GLfloat dsbdx, dsbdy; #endif #ifdef INTERP_INDEX - GLfloat didx, didy; GLfixed fdidx; + GLfloat didx, didy; #endif #ifdef INTERP_INT_TEX - GLfloat dsdx, dsdy; GLfixed fdsdx; - GLfloat dtdx, dtdy; GLfixed fdtdx; -#endif -#ifdef INTERP_TEX GLfloat dsdx, dsdy; GLfloat dtdx, dtdy; - GLfloat dudx, dudy; - GLfloat dvdx, dvdy; +#endif +#ifdef INTERP_TEX + GLfloat dsdy; + GLfloat dtdy; + GLfloat dudy; + GLfloat dvdy; #endif #ifdef INTERP_MULTITEX - GLfloat dsdx[MAX_TEXTURE_UNITS], dsdy[MAX_TEXTURE_UNITS]; - GLfloat dtdx[MAX_TEXTURE_UNITS], dtdy[MAX_TEXTURE_UNITS]; - GLfloat dudx[MAX_TEXTURE_UNITS], dudy[MAX_TEXTURE_UNITS]; - GLfloat dvdx[MAX_TEXTURE_UNITS], dvdy[MAX_TEXTURE_UNITS]; + GLfloat dsdy[MAX_TEXTURE_UNITS]; + GLfloat dtdy[MAX_TEXTURE_UNITS]; + GLfloat dudy[MAX_TEXTURE_UNITS]; + GLfloat dvdy[MAX_TEXTURE_UNITS]; #endif -#ifdef INTERP_LAMBDA -#ifndef INTERP_TEX +#if defined(INTERP_LAMBDA) && !defined(INTERP_TEX) && !defined(INTERP_MULTITEX) #error "Mipmapping without texturing doesn't make sense." #endif - GLfloat lambda_nominator; -#endif /* INTERP_LAMBDA */ - -#ifdef INTERP_MULTILAMBDA -#ifndef INTERP_MULTITEX -#error "Multi-Mipmapping without multi-texturing doesn't make sense." -#endif - GLfloat lambda_nominator[MAX_TEXTURE_UNITS]; -#endif /* INTERP_MULTILAMBDA */ - /* * Execute user-supplied setup code @@ -315,8 +301,11 @@ ltor = (oneOverArea < 0.0F); + span.activeMask = 0; + /* compute d?/dx and d?/dy derivatives */ #ifdef INTERP_Z + span.activeMask |= SPAN_Z; { GLfloat eMaj_dz, eBot_dz; eMaj_dz = vMax->win[2] - vMin->win[2]; @@ -331,28 +320,30 @@ dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx); } if (depthBits <= 16) - fdzdx = SignedFloatToFixed(dzdx); + span.zStep = SignedFloatToFixed(dzdx); else - fdzdx = (GLint) dzdx; + span.zStep = (GLint) dzdx; } #endif #ifdef INTERP_FOG + span.activeMask |= SPAN_FOG; { const GLfloat eMaj_dfog = vMax->fog - vMin->fog; const GLfloat eBot_dfog = vMid->fog - vMin->fog; - dfogdx = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog); + span.fogStep = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog); dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx); } #endif #ifdef INTERP_RGB + span.activeMask |= SPAN_RGBA; if (tiny) { /* This is kind of a hack to eliminate RGB color over/underflow * problems when rendering very tiny triangles. We're not doing * anything with alpha or specular color at this time. */ - drdx = drdy = 0.0; fdrdx = 0; - dgdx = dgdy = 0.0; fdgdx = 0; - dbdx = dbdy = 0.0; fdbdx = 0; + drdx = drdy = 0.0; span.redStep = 0; + dgdx = dgdy = 0.0; span.greenStep = 0; + dbdx = dbdy = 0.0; span.blueStep = 0; } else { GLfloat eMaj_dr, eBot_dr; @@ -361,27 +352,38 @@ eMaj_dr = (GLint) vMax->color[0] - (GLint) vMin->color[0]; eBot_dr = (GLint) vMid->color[0] - (GLint) vMin->color[0]; drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr); - fdrdx = SignedFloatToFixed(drdx); + span.redStep = SignedFloatToFixed(drdx); drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx); eMaj_dg = (GLint) vMax->color[1] - (GLint) vMin->color[1]; eBot_dg = (GLint) vMid->color[1] - (GLint) vMin->color[1]; dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg); - fdgdx = SignedFloatToFixed(dgdx); + span.greenStep = SignedFloatToFixed(dgdx); dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx); eMaj_db = (GLint) vMax->color[2] - (GLint) vMin->color[2]; eBot_db = (GLint) vMid->color[2] - (GLint) vMin->color[2]; dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db); - fdbdx = SignedFloatToFixed(dbdx); + span.blueStep = SignedFloatToFixed(dbdx); dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx); } #endif +#ifdef INTERP_ALPHA + { + GLfloat eMaj_da, eBot_da; + eMaj_da = (GLint) vMax->color[3] - (GLint) vMin->color[3]; + eBot_da = (GLint) vMid->color[3] - (GLint) vMin->color[3]; + dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); + span.alphaStep = SignedFloatToFixed(dadx); + dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); + } +#endif #ifdef INTERP_SPEC + span.activeMask |= SPAN_SPEC; { GLfloat eMaj_dsr, eBot_dsr; eMaj_dsr = (GLint) vMax->specular[0] - (GLint) vMin->specular[0]; eBot_dsr = (GLint) vMid->specular[0] - (GLint) vMin->specular[0]; dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr); - fdsrdx = SignedFloatToFixed(dsrdx); + span.specRedStep = SignedFloatToFixed(dsrdx); dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx); } { @@ -389,7 +391,7 @@ eMaj_dsg = (GLint) vMax->specular[1] - (GLint) vMin->specular[1]; eBot_dsg = (GLint) vMid->specular[1] - (GLint) vMin->specular[1]; dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg); - fdsgdx = SignedFloatToFixed(dsgdx); + span.specGreenStep = SignedFloatToFixed(dsgdx); dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx); } { @@ -397,37 +399,29 @@ eMaj_dsb = (GLint) vMax->specular[2] - (GLint) vMin->specular[2]; eBot_dsb = (GLint) vMid->specular[2] - (GLint) vMin->specular[2]; dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb); - fdsbdx = SignedFloatToFixed(dsbdx); + span.specBlueStep = SignedFloatToFixed(dsbdx); dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx); } #endif -#ifdef INTERP_ALPHA - { - GLfloat eMaj_da, eBot_da; - eMaj_da = (GLint) vMax->color[3] - (GLint) vMin->color[3]; - eBot_da = (GLint) vMid->color[3] - (GLint) vMin->color[3]; - dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); - fdadx = SignedFloatToFixed(dadx); - dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); - } -#endif #ifdef INTERP_INDEX + span.activeMask |= SPAN_INDEX; { GLfloat eMaj_di, eBot_di; eMaj_di = (GLint) vMax->index - (GLint) vMin->index; eBot_di = (GLint) vMid->index - (GLint) vMin->index; didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di); - fdidx = SignedFloatToFixed(didx); + span.indexStep = SignedFloatToFixed(didx); didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx); } #endif #ifdef INTERP_INT_TEX + span.activeMask |= SPAN_INT_TEXTURE; { GLfloat eMaj_ds, eBot_ds; eMaj_ds = (vMax->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE; eBot_ds = (vMid->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE; dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); - fdsdx = SignedFloatToFixed(dsdx); + span.intTexStep[0] = SignedFloatToFixed(dsdx); dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); } { @@ -435,12 +429,14 @@ eMaj_dt = (vMax->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE; eBot_dt = (vMid->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE; dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); - fdtdx = SignedFloatToFixed(dtdx); + span.intTexStep[1] = SignedFloatToFixed(dtdx); dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); } #endif + #ifdef INTERP_TEX + span.activeMask |= SPAN_TEXTURE; { GLfloat wMax = vMax->win[3]; GLfloat wMin = vMin->win[3]; @@ -452,26 +448,47 @@ eMaj_ds = vMax->texcoord[0][0] * wMax - vMin->texcoord[0][0] * wMin; eBot_ds = vMid->texcoord[0][0] * wMid - vMin->texcoord[0][0] * wMin; - dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); + span.texStep[0][0] = oneOverArea * (eMaj_ds * eBot.dy + - eMaj.dy * eBot_ds); dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); eMaj_dt = vMax->texcoord[0][1] * wMax - vMin->texcoord[0][1] * wMin; eBot_dt = vMid->texcoord[0][1] * wMid - vMin->texcoord[0][1] * wMin; - dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); + span.texStep[0][1] = oneOverArea * (eMaj_dt * eBot.dy + - eMaj.dy * eBot_dt); dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); eMaj_du = vMax->texcoord[0][2] * wMax - vMin->texcoord[0][2] * wMin; eBot_du = vMid->texcoord[0][2] * wMid - vMin->texcoord[0][2] * wMin; - dudx = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du); + span.texStep[0][2] = oneOverArea * (eMaj_du * eBot.dy + - eMaj.dy * eBot_du); dudy = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx); eMaj_dv = vMax->texcoord[0][3] * wMax - vMin->texcoord[0][3] * wMin; eBot_dv = vMid->texcoord[0][3] * wMid - vMin->texcoord[0][3] * wMin; - dvdx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv); + span.texStep[0][3] = oneOverArea * (eMaj_dv * eBot.dy + - eMaj.dy * eBot_dv); dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx); } +# ifdef INTERP_LAMBDA + { + GLfloat dudx = span.texStep[0][0] * span.texWidth[0]; + GLfloat dudy = dsdy * span.texWidth[0]; + GLfloat dvdx = span.texStep[0][1] * span.texHeight[0]; + GLfloat dvdy = dtdy * span.texHeight[0]; + GLfloat r1 = dudx * dudx + dudy * dudy; + GLfloat r2 = dvdx * dvdx + dvdy * dvdy; + span.rho[0] = r1 + r2; /* was rho2 = MAX2(r1,r2) */ + span.activeMask |= SPAN_LAMBDA; + } +# endif #endif + #ifdef INTERP_MULTITEX + span.activeMask |= SPAN_TEXTURE; +# ifdef INTERP_LAMBDA + span.activeMask |= SPAN_LAMBDA; +# endif { GLfloat wMax = vMax->win[3]; GLfloat wMin = vMin->win[3]; @@ -487,29 +504,44 @@ - vMin->texcoord[u][0] * wMin; eBot_ds = vMid->texcoord[u][0] * wMid - vMin->texcoord[u][0] * wMin; - dsdx[u] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); + span.texStep[u][0] = oneOverArea * (eMaj_ds * eBot.dy + - eMaj.dy * eBot_ds); dsdy[u] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); eMaj_dt = vMax->texcoord[u][1] * wMax - vMin->texcoord[u][1] * wMin; eBot_dt = vMid->texcoord[u][1] * wMid - vMin->texcoord[u][1] * wMin; - dtdx[u] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); + span.texStep[u][1] = oneOverArea * (eMaj_dt * eBot.dy + - eMaj.dy * eBot_dt); dtdy[u] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); eMaj_du = vMax->texcoord[u][2] * wMax - vMin->texcoord[u][2] * wMin; eBot_du = vMid->texcoord[u][2] * wMid - vMin->texcoord[u][2] * wMin; - dudx[u] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du); + span.texStep[u][2] = oneOverArea * (eMaj_du * eBot.dy + - eMaj.dy * eBot_du); dudy[u] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx); eMaj_dv = vMax->texcoord[u][3] * wMax - vMin->texcoord[u][3] * wMin; eBot_dv = vMid->texcoord[u][3] * wMid - vMin->texcoord[u][3] * wMin; - dvdx[u] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv); + span.texStep[u][3] = oneOverArea * (eMaj_dv * eBot.dy + - eMaj.dy * eBot_dv); dvdy[u] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx); +# ifdef INTERP_LAMBDA + { + GLfloat dudx = span.texStep[u][0] * span.texWidth[u]; + GLfloat dudy = dsdy[u] * span.texWidth[u]; + GLfloat dvdx = span.texStep[u][1] * span.texHeight[u]; + GLfloat dvdy = dtdy[u] * span.texHeight[u]; + GLfloat r1 = dudx * dudx + dudy * dudy; + GLfloat r2 = dvdx * dvdx + dvdy * dvdy; + span.rho[u] = r1 + r2; /* was rho2 = MAX2(r1,r2) */ + } +# endif } } } @@ -565,41 +597,40 @@ { int subTriangle; GLfixed fx; - GLfixed fxLeftEdge=0, fxRightEdge=0, fdxLeftEdge=0, fdxRightEdge=0; + GLfixed fxLeftEdge, fxRightEdge, fdxLeftEdge, fdxRightEdge; GLfixed fdxOuter; int idxOuter; float dxOuter; - GLfixed fError=0, fdError=0; + GLfixed fError, fdError; float adjx, adjy; GLfixed fy; - int iy=0; #ifdef PIXEL_ADDRESS - PIXEL_TYPE *pRow=NULL; - int dPRowOuter=0, dPRowInner=0; /* offset in bytes */ + PIXEL_TYPE *pRow; + int dPRowOuter, dPRowInner; /* offset in bytes */ #endif #ifdef INTERP_Z # ifdef DEPTH_TYPE - DEPTH_TYPE *zRow=NULL; - int dZRowOuter=0, dZRowInner=0; /* offset in bytes */ + DEPTH_TYPE *zRow; + int dZRowOuter, dZRowInner; /* offset in bytes */ # endif - GLfixed fz=0, fdzOuter=0, fdzInner; + GLfixed fz, fdzOuter, fdzInner; #endif #ifdef INTERP_FOG GLfloat fogLeft, dfogOuter, dfogInner; #endif #ifdef INTERP_RGB - GLfixed fr=0, fdrOuter=0, fdrInner; - GLfixed fg=0, fdgOuter=0, fdgInner; - GLfixed fb=0, fdbOuter=0, fdbInner; + GLfixed fr, fdrOuter, fdrInner; + GLfixed fg, fdgOuter, fdgInner; + GLfixed fb, fdbOuter, fdbInner; +#endif +#ifdef INTERP_ALPHA + GLfixed fa=0, fdaOuter=0, fdaInner; #endif #ifdef INTERP_SPEC GLfixed fsr=0, fdsrOuter=0, fdsrInner; GLfixed fsg=0, fdsgOuter=0, fdsgInner; GLfixed fsb=0, fdsbOuter=0, fdsbInner; #endif -#ifdef INTERP_ALPHA - GLfixed fa=0, fdaOuter=0, fdaInner; -#endif #ifdef INTERP_INDEX GLfixed fi=0, fdiOuter=0, fdiInner; #endif @@ -680,7 +711,7 @@ (void) dxOuter; fy = eLeft->fsy; - iy = FixedToInt(fy); + span.y = FixedToInt(fy); adjx = (float)(fx - eLeft->fx0); /* SCALED! */ adjy = eLeft->adjy; /* SCALED! */ @@ -692,7 +723,7 @@ #ifdef PIXEL_ADDRESS { - pRow = PIXEL_ADDRESS( FixedToInt(fxLeftEdge), iy ); + pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(FixedToInt(fxLeftEdge), span.y); dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE); /* negative because Y=0 at bottom and increases upward */ } @@ -722,19 +753,21 @@ } else { /* interpolate depth values exactly */ - fz = (GLint) (z0 + dzdx*FixedToFloat(adjx) + dzdy*FixedToFloat(adjy)); + fz = (GLint) (z0 + dzdx * FixedToFloat(adjx) + + dzdy * FixedToFloat(adjy)); fdzOuter = (GLint) (dzdy + dxOuter * dzdx); } # ifdef DEPTH_TYPE - zRow = (DEPTH_TYPE *) _mesa_zbuffer_address(ctx, FixedToInt(fxLeftEdge), iy); + zRow = (DEPTH_TYPE *) + _mesa_zbuffer_address(ctx, FixedToInt(fxLeftEdge), span.y); dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE); # endif } #endif #ifdef INTERP_FOG - fogLeft = vLower->fog + (dfogdx * adjx + dfogdy * adjy) + fogLeft = vLower->fog + (span.fogStep * adjx + dfogdy * adjy) * (1.0F/FIXED_SCALE); - dfogOuter = dfogdy + dxOuter * dfogdx; + dfogOuter = dfogdy + dxOuter * span.fogStep; #endif #ifdef INTERP_RGB fr = (GLfixed)(IntToFixed(vLower->color[0]) @@ -749,6 +782,11 @@ + dbdx * adjx + dbdy * adjy) + FIXED_HALF; fdbOuter = SignedFloatToFixed(dbdy + dxOuter * dbdx); #endif +#ifdef INTERP_ALPHA + fa = (GLfixed)(IntToFixed(vLower->color[3]) + + dadx * adjx + dady * adjy) + FIXED_HALF; + fdaOuter = SignedFloatToFixed(dady + dxOuter * dadx); +#endif #ifdef INTERP_SPEC fsr = (GLfixed)(IntToFixed(vLower->specular[0]) + dsrdx * adjx + dsrdy * adjy) + FIXED_HALF; @@ -762,11 +800,6 @@ + dsbdx * adjx + dsbdy * adjy) + FIXED_HALF; fdsbOuter = SignedFloatToFixed(dsbdy + dxOuter * dsbdx); #endif -#ifdef INTERP_ALPHA - fa = (GLfixed)(IntToFixed(vLower->color[3]) - + dadx * adjx + dady * adjy) + FIXED_HALF; - fdaOuter = SignedFloatToFixed(dady + dxOuter * dadx); -#endif #ifdef INTERP_INDEX fi = (GLfixed)(vLower->index * FIXED_SCALE + didx * adjx + didy * adjy) + FIXED_HALF; @@ -776,11 +809,13 @@ { GLfloat s0, t0; s0 = vLower->texcoord[0][0] * S_SCALE; - fs = (GLfixed)(s0 * FIXED_SCALE + dsdx * adjx + dsdy * adjy) + FIXED_HALF; + fs = (GLfixed)(s0 * FIXED_SCALE + dsdx * adjx + + dsdy * adjy) + FIXED_HALF; fdsOuter = SignedFloatToFixed(dsdy + dxOuter * dsdx); t0 = vLower->texcoord[0][1] * T_SCALE; - ft = (GLfixed)(t0 * FIXED_SCALE + dtdx * adjx + dtdy * adjy) + FIXED_HALF; + ft = (GLfixed)(t0 * FIXED_SCALE + dtdx * adjx + + dtdy * adjy) + FIXED_HALF; fdtOuter = SignedFloatToFixed(dtdy + dxOuter * dtdx); } #endif @@ -789,17 +824,21 @@ GLfloat invW = vLower->win[3]; GLfloat s0, t0, u0, v0; s0 = vLower->texcoord[0][0] * invW; - sLeft = s0 + (dsdx * adjx + dsdy * adjy) * (1.0F/FIXED_SCALE); - dsOuter = dsdy + dxOuter * dsdx; + sLeft = s0 + (span.texStep[0][0] * adjx + dsdy * adjy) + * (1.0F/FIXED_SCALE); + dsOuter = dsdy + dxOuter * span.texStep[0][0]; t0 = vLower->texcoord[0][1] * invW; - tLeft = t0 + (dtdx * adjx + dtdy * adjy) * (1.0F/FIXED_SCALE); - dtOuter = dtdy + dxOuter * dtdx; + tLeft = t0 + (span.texStep[0][1] * adjx + dtdy * adjy) + * (1.0F/FIXED_SCALE); + dtOuter = dtdy + dxOuter * span.texStep[0][1]; u0 = vLower->texcoord[0][2] * invW; - uLeft = u0 + (dudx * adjx + dudy * adjy) * (1.0F/FIXED_SCALE); - duOuter = dudy + dxOuter * dudx; + uLeft = u0 + (span.texStep[0][2] * adjx + dudy * adjy) + * (1.0F/FIXED_SCALE); + duOuter = dudy + dxOuter * span.texStep[0][2]; v0 = vLower->texcoord[0][3] * invW; - vLeft = v0 + (dvdx * adjx + dvdy * adjy) * (1.0F/FIXED_SCALE); - dvOuter = dvdy + dxOuter * dvdx; + vLeft = v0 + (span.texStep[0][3] * adjx + dvdy * adjy) + * (1.0F/FIXED_SCALE); + dvOuter = dvdy + dxOuter * span.texStep[0][3]; } #endif #ifdef INTERP_MULTITEX @@ -810,17 +849,21 @@ GLfloat invW = vLower->win[3]; GLfloat s0, t0, u0, v0; s0 = vLower->texcoord[u][0] * invW; - sLeft[u] = s0 + (dsdx[u] * adjx + dsdy[u] * adjy) * (1.0F/FIXED_SCALE); - dsOuter[u] = dsdy[u] + dxOuter * dsdx[u]; + sLeft[u] = s0 + (span.texStep[u][0] * adjx + dsdy[u] + * adjy) * (1.0F/FIXED_SCALE); + dsOuter[u] = dsdy[u] + dxOuter * span.texStep[u][0]; t0 = vLower->texcoord[u][1] * invW; - tLeft[u] = t0 + (dtdx[u] * adjx + dtdy[u] * adjy) * (1.0F/FIXED_SCALE); - dtOuter[u] = dtdy[u] + dxOuter * dtdx[u]; + tLeft[u] = t0 + (span.texStep[u][1] * adjx + dtdy[u] + * adjy) * (1.0F/FIXED_SCALE); + dtOuter[u] = dtdy[u] + dxOuter * span.texStep[u][1]; u0 = vLower->texcoord[u][2] * invW; - uLeft[u] = u0 + (dudx[u] * adjx + dudy[u] * adjy) * (1.0F/FIXED_SCALE); - duOuter[u] = dudy[u] + dxOuter * dudx[u]; + uLeft[u] = u0 + (span.texStep[u][2] * adjx + dudy[u] + * adjy) * (1.0F/FIXED_SCALE); + duOuter[u] = dudy[u] + dxOuter * span.texStep[u][2]; v0 = vLower->texcoord[u][3] * invW; - vLeft[u] = v0 + (dvdx[u] * adjx + dvdy[u] * adjy) * (1.0F/FIXED_SCALE); - dvOuter[u] = dvdy[u] + dxOuter * dvdx[u]; + vLeft[u] = v0 + (span.texStep[u][3] * adjx + dvdy[u] + * adjy) * (1.0F/FIXED_SCALE); + dvOuter[u] = dvdy[u] + dxOuter * span.texStep[u][3]; } } } @@ -847,93 +890,104 @@ # ifdef DEPTH_TYPE dZRowInner = dZRowOuter + sizeof(DEPTH_TYPE); # endif - fdzInner = fdzOuter + fdzdx; + fdzInner = fdzOuter + span.zStep; #endif #ifdef INTERP_FOG - dfogInner = dfogOuter + dfogdx; + dfogInner = dfogOuter + span.fogStep; #endif #ifdef INTERP_RGB - fdrInner = fdrOuter + fdrdx; - fdgInner = fdgOuter + fdgdx; - fdbInner = fdbOuter + fdbdx; -#endif -#ifdef INTERP_SPEC - fdsrInner = fdsrOuter + fdsrdx; - fdsgInner = fdsgOuter + fdsgdx; - fdsbInner = fdsbOuter + fdsbdx; + fdrInner = fdrOuter + span.redStep; + fdgInner = fdgOuter + span.greenStep; + fdbInner = fdbOuter + span.blueStep; #endif #ifdef INTERP_ALPHA - fdaInner = fdaOuter + fdadx; + fdaInner = fdaOuter + span.alphaStep; +#endif +#ifdef INTERP_SPEC + fdsrInner = fdsrOuter + span.specRedStep; + fdsgInner = fdsgOuter + span.specGreenStep; + fdsbInner = fdsbOuter + span.specBlueStep; #endif #ifdef INTERP_INDEX - fdiInner = fdiOuter + fdidx; + fdiInner = fdiOuter + span.indexStep; #endif #ifdef INTERP_INT_TEX - fdsInner = fdsOuter + fdsdx; - fdtInner = fdtOuter + fdtdx; + fdsInner = fdsOuter + span.intTexStep[0]; + fdtInner = fdtOuter + span.intTexStep[1]; #endif #ifdef INTERP_TEX - dsInner = dsOuter + dsdx; - dtInner = dtOuter + dtdx; - duInner = duOuter + dudx; - dvInner = dvOuter + dvdx; + dsInner = dsOuter + span.texStep[0][0]; + dtInner = dtOuter + span.texStep[0][1]; + duInner = duOuter + span.texStep[0][2]; + dvInner = dvOuter + span.texStep[0][3]; #endif #ifdef INTERP_MULTITEX { GLuint u; for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { if (ctx->Texture.Unit[u]._ReallyEnabled) { - dsInner[u] = dsOuter[u] + dsdx[u]; - dtInner[u] = dtOuter[u] + dtdx[u]; - duInner[u] = duOuter[u] + dudx[u]; - dvInner[u] = dvOuter[u] + dvdx[u]; + dsInner[u] = dsOuter[u] + span.texStep[u][0]; + dtInner[u] = dtOuter[u] + span.texStep[u][1]; + duInner[u] = duOuter[u] + span.texStep[u][2]; + dvInner[u] = dvOuter[u] + span.texStep[u][3]; } } } #endif - while (lines>0) { + while (lines > 0) { /* initialize the span interpolants to the leftmost value */ /* ff = fixed-pt fragment */ - GLint left = FixedToInt(fxLeftEdge); - GLint right = FixedToInt(fxRightEdge); + const GLint right = FixedToInt(fxRightEdge); + span.x = FixedToInt(fxLeftEdge); + if (right <= span.x) + span.count = 0; + else + span.count = right - span.x; + #ifdef INTERP_Z - GLfixed ffz = fz; + span.z = fz; #endif #ifdef INTERP_FOG - GLfloat ffog = fogLeft; + span.fog = fogLeft; #endif #ifdef INTERP_RGB - GLfixed ffr = fr, ffg = fg, ffb = fb; -#endif -#ifdef INTERP_SPEC - GLfixed ffsr = fsr, ffsg = fsg, ffsb = fsb; + span.red = fr; + span.green = fg; + span.blue = fb; #endif #ifdef INTERP_ALPHA - GLfixed ffa = fa; + span.alpha = fa; +#endif +#ifdef INTERP_SPEC + span.specRed = fsr; + span.specGreen = fsg; + span.specBlue = fsb; #endif #ifdef INTERP_INDEX - GLfixed ffi = fi; + span.index = fi; #endif #ifdef INTERP_INT_TEX - GLfixed ffs = fs, fft = ft; + span.intTex[0] = fs; + span.intTex[1] = ft; #endif + #ifdef INTERP_TEX - GLfloat ss = sLeft, tt = tLeft, uu = uLeft, vv = vLeft; + span.tex[0][0] = sLeft; + span.tex[0][1] = tLeft; + span.tex[0][2] = uLeft; + span.tex[0][3] = vLeft; #endif + #ifdef INTERP_MULTITEX - GLfloat ss[MAX_TEXTURE_UNITS]; - GLfloat tt[MAX_TEXTURE_UNITS]; - GLfloat uu[MAX_TEXTURE_UNITS]; - GLfloat vv[MAX_TEXTURE_UNITS]; { GLuint u; for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { if (ctx->Texture.Unit[u]._ReallyEnabled) { - ss[u] = sLeft[u]; - tt[u] = tLeft[u]; - uu[u] = uLeft[u]; - vv[u] = vLeft[u]; + span.tex[u][0] = sLeft[u]; + span.tex[u][1] = tLeft[u]; + span.tex[u][2] = uLeft[u]; + span.tex[u][3] = vLeft[u]; } } } @@ -942,100 +996,70 @@ #ifdef INTERP_RGB { /* need this to accomodate round-off errors */ - GLfixed ffrend = ffr+(right-left-1)*fdrdx; - GLfixed ffgend = ffg+(right-left-1)*fdgdx; - GLfixed ffbend = ffb+(right-left-1)*fdbdx; - if (ffrend<0) ffr -= ffrend; - if (ffgend<0) ffg -= ffgend; - if (ffbend<0) ffb -= ffbend; - if (ffr<0) ffr = 0; - if (ffg<0) ffg = 0; - if (ffb<0) ffb = 0; + const GLint len = right - span.x - 1; + GLfixed ffrend = span.red + len * span.redStep; + GLfixed ffgend = span.green + len * span.greenStep; + GLfixed ffbend = span.blue + len * span.blueStep; + if (ffrend < 0) { + span.red -= ffrend; + if (span.red < 0) + span.red = 0; + } + if (ffgend < 0) { + span.green -= ffgend; + if (span.green < 0) + span.green = 0; + } + if (ffbend < 0) { + span.blue -= ffbend; + if (span.blue < 0) + span.blue = 0; + } } #endif -#ifdef INTERP_SPEC +#ifdef INTERP_ALPHA { - /* need this to accomodate round-off errors */ - GLfixed ffsrend = ffsr+(right-left-1)*fdsrdx; - GLfixed ffsgend = ffsg+(right-left-1)*fdsgdx; - GLfixed ffsbend = ffsb+(right-left-1)*fdsbdx; - if (ffsrend<0) ffsr -= ffsrend; - if (ffsgend<0) ffsg -= ffsgend; - if (ffsbend<0) ffsb -= ffsbend; - if (ffsr<0) ffsr = 0; - if (ffsg<0) ffsg = 0; - if (ffsb<0) ffsb = 0; + const GLint len = right - span.x - 1; + GLfixed ffaend = span.alpha + len * span.alphaStep; + if (ffaend < 0) { + span.alpha -= ffaend; + if (span.alpha < 0) + span.alpha = 0; + } } #endif -#ifdef INTERP_ALPHA +#ifdef INTERP_SPEC { - GLfixed ffaend = ffa+(right-left-1)*fdadx; - if (ffaend<0) ffa -= ffaend; - if (ffa<0) ffa = 0; + /* need this to accomodate round-off errors */ + const GLint len = right - span.x - 1; + GLfixed ffsrend = span.specRed + len * span.specRedStep; + GLfixed ffsgend = span.specGreen + len * span.specGreenStep; + GLfixed ffsbend = span.specBlue + len * span.specBlueStep; + if (ffsrend < 0) { + span.specRed -= ffsrend; + if (span.specRed < 0) + span.specRed = 0; + } + if (ffsgend < 0) { + span.specGreen -= ffsgend; + if (span.specGreen < 0) + span.specGreen = 0; + } + if (ffsbend < 0) { + span.specBlue -= ffsbend; + if (span.specBlue < 0) + span.specBlue = 0; + } } #endif #ifdef INTERP_INDEX - if (ffi<0) ffi = 0; -#endif - -#ifdef INTERP_LAMBDA -/* - * The lambda value is: - * log_2(sqrt(f(n))) = 1/2*log_2(f(n)), where f(n) is a function - * defined by - * f(n):= dudx * dudx + dudy * dudy + dvdx * dvdx + dvdy * dvdy; - * and each of this terms is resp. - * dudx = dsdx * invQ(n) * tex_width; - * dudy = dsdy * invQ(n) * tex_width; - * dvdx = dtdx * invQ(n) * tex_height; - * dvdy = dtdy * invQ(n) * tex_height; - * Therefore the function lambda can be represented (by factoring out) as: - * f(n) = lambda_nominator * invQ(n) * invQ(n), - * which saves some computation time. - */ - { - GLfloat dudx = dsdx /* * invQ*/ * twidth; - GLfloat dudy = dsdy /* * invQ*/ * twidth; - GLfloat dvdx = dtdx /* * invQ*/ * theight; - GLfloat dvdy = dtdy /* * invQ*/ * theight; - GLfloat r1 = dudx * dudx + dudy * dudy; - GLfloat r2 = dvdx * dvdx + dvdy * dvdy; - GLfloat rho2 = r1 + r2; /* was: rho2 = MAX2(r1,r2); */ - lambda_nominator = rho2; - } - - /* set DEST to log_(base 2) of sqrt(rho) */ - /* 1.442695 = 1/log(2) */ -#define COMPUTE_LAMBDA(DEST, X) \ - DEST = log( lambda_nominator * (X)*(X) ) * 1.442695F * 0.5F -#endif - -#ifdef INTERP_MULTILAMBDA -/* - * Read the comment for INTERP_LAMBDA, but apply to each texture unit - */ - { - GLuint unit; - for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ctx->Texture.Unit[unit]._ReallyEnabled) { - GLfloat dudx = dsdx[unit] /* * invQ*/ * twidth[unit]; - GLfloat dudy = dsdy[unit] /* * invQ*/ * twidth[unit]; - GLfloat dvdx = dtdx[unit] /* * invQ*/ * theight[unit]; - GLfloat dvdy = dtdy[unit] /* * invQ*/ * theight[unit]; - GLfloat r1 = dudx * dudx + dudy * dudy; - GLfloat r2 = dvdx * dvdx + dvdy * dvdy; - GLfloat rho2 = r1 + r2; /* used to be: rho2 = MAX2(r1,r2); */ - lambda_nominator[unit] = rho2; - } - } - } - /* set DEST to log_(base 2) of sqrt(rho) */ -#define COMPUTE_MULTILAMBDA(DEST, X, unit) \ - DEST = log( lambda_nominator[unit] * (X)*(X) ) * 1.442695F * 0.5F + if (span.index < 0) span.index = 0; #endif - - INNER_LOOP( left, right, iy ); + /* This is where we actually generate fragments */ + if (span.count > 0) { + RENDER_SPAN( span ); + } /* * Advance to the next scan line. Compute the @@ -1043,7 +1067,7 @@ * pixel-center x coordinate so that it stays * on or inside the major edge. */ - iy++; + span.y++; lines--; fxLeftEdge += fdxLeftEdge; @@ -1054,11 +1078,11 @@ if (fError >= 0) { fError -= FIXED_ONE; #ifdef PIXEL_ADDRESS - pRow = (PIXEL_TYPE *) ((GLubyte*)pRow + dPRowOuter); + pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter); #endif #ifdef INTERP_Z # ifdef DEPTH_TYPE - zRow = (DEPTH_TYPE *) ((GLubyte*)zRow + dZRowOuter); + zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowOuter); # endif fz += fdzOuter; #endif @@ -1066,19 +1090,24 @@ fogLeft += dfogOuter; #endif #ifdef INTERP_RGB - fr += fdrOuter; fg += fdgOuter; fb += fdbOuter; -#endif -#ifdef INTERP_SPEC - fsr += fdsrOuter; fsg += fdsgOuter; fsb += fdsbOuter; + fr += fdrOuter; + fg += fdgOuter; + fb += fdbOuter; #endif #ifdef INTERP_ALPHA fa += fdaOuter; #endif +#ifdef INTERP_SPEC + fsr += fdsrOuter; + fsg += fdsgOuter; + fsb += fdsbOuter; +#endif #ifdef INTERP_INDEX fi += fdiOuter; #endif #ifdef INTERP_INT_TEX - fs += fdsOuter; ft += fdtOuter; + fs += fdsOuter; + ft += fdtOuter; #endif #ifdef INTERP_TEX sLeft += dsOuter; @@ -1102,11 +1131,11 @@ } else { #ifdef PIXEL_ADDRESS - pRow = (PIXEL_TYPE *) ((GLubyte*)pRow + dPRowInner); + pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowInner); #endif #ifdef INTERP_Z # ifdef DEPTH_TYPE - zRow = (DEPTH_TYPE *) ((GLubyte*)zRow + dZRowInner); + zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowInner); # endif fz += fdzInner; #endif @@ -1114,19 +1143,24 @@ fogLeft += dfogInner; #endif #ifdef INTERP_RGB - fr += fdrInner; fg += fdgInner; fb += fdbInner; -#endif -#ifdef INTERP_SPEC - fsr += fdsrInner; fsg += fdsgInner; fsb += fdsbInner; + fr += fdrInner; + fg += fdgInner; + fb += fdbInner; #endif #ifdef INTERP_ALPHA fa += fdaInner; #endif +#ifdef INTERP_SPEC + fsr += fdsrInner; + fsg += fdsgInner; + fsb += fdsbInner; +#endif #ifdef INTERP_INDEX fi += fdiInner; #endif #ifdef INTERP_INT_TEX - fs += fdsInner; ft += fdtInner; + fs += fdsInner; + ft += fdtInner; #endif #ifdef INTERP_TEX sLeft += dsInner; @@ -1157,7 +1191,7 @@ } #undef SETUP_CODE -#undef INNER_LOOP +#undef RENDER_SPAN #undef PIXEL_TYPE #undef BYTES_PER_ROW @@ -1166,16 +1200,13 @@ #undef INTERP_Z #undef INTERP_FOG #undef INTERP_RGB -#undef INTERP_SPEC #undef INTERP_ALPHA +#undef INTERP_SPEC #undef INTERP_INDEX #undef INTERP_INT_TEX #undef INTERP_TEX #undef INTERP_MULTITEX #undef INTERP_LAMBDA -#undef COMPUTE_LAMBDA -#undef INTERP_MULTILAMBDA -#undef COMPUTE_MULTILAMBDA #undef S_SCALE #undef T_SCALE -- cgit v1.2.3