X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fswrast%2Fs_triangle.c;h=ab262beabc1c49cb8cda363a4bbb21cf6ea8563a;hb=8ef874f1a543c693cfef9c935bed05903800fbfe;hp=98e09d47372ce42a870881d39e4eda7a3830641f;hpb=96385fa15569e25cd0977e678c0ff3bdab6ef316;p=mesa.git diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c index 98e09d47372..ab262beabc1 100644 --- a/src/mesa/swrast/s_triangle.c +++ b/src/mesa/swrast/s_triangle.c @@ -1,10 +1,8 @@ -/* $Id: s_triangle.c,v 1.34 2001/07/14 17:53:04 brianp Exp $ */ - /* * Mesa 3-D graphics library - * Version: 3.5 + * Version: 6.1 * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -34,9 +32,8 @@ #include "glheader.h" #include "context.h" #include "colormac.h" +#include "imports.h" #include "macros.h" -#include "mem.h" -#include "mmath.h" #include "texformat.h" #include "teximage.h" #include "texstate.h" @@ -47,14 +44,16 @@ #include "s_feedback.h" #include "s_span.h" #include "s_triangle.h" -#include "s_trispan.h" - -GLboolean _mesa_cull_triangle( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) +/* + * Just used for feedback mode. + */ +GLboolean +_swrast_culltriangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) { GLfloat ex = v1->win[0] - v0->win[0]; GLfloat ey = v1->win[1] - v0->win[1]; @@ -62,7 +61,7 @@ GLboolean _mesa_cull_triangle( GLcontext *ctx, GLfloat fy = v2->win[1] - v0->win[1]; GLfloat c = ex*fy-ey*fx; - if (c * SWRAST_CONTEXT(ctx)->_backface_sign > 0) + if (c * SWRAST_CONTEXT(ctx)->_BackfaceSign > 0) return 0; return 1; @@ -73,141 +72,72 @@ GLboolean _mesa_cull_triangle( GLcontext *ctx, /* * Render a flat-shaded color index triangle. */ -static void flat_ci_triangle( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) -{ +#define NAME flat_ci_triangle #define INTERP_Z 1 #define INTERP_FOG 1 - -#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, NULL, GL_POLYGON ); - +#define SETUP_CODE \ + span.interpMask |= SPAN_INDEX; \ + span.index = FloatToFixed(v2->index);\ + span.indexStep = 0; +#define RENDER_SPAN( span ) _swrast_write_index_span(ctx, &span); #include "s_tritemp.h" -} /* * Render a smooth-shaded color index triangle. */ -static void smooth_ci_triangle( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) -{ +#define NAME smooth_ci_triangle #define INTERP_Z 1 #define INTERP_FOG 1 #define INTERP_INDEX 1 - -#define RENDER_SPAN( span ) \ - GLdepth zSpan[MAX_WIDTH]; \ - GLfloat fogSpan[MAX_WIDTH]; \ - GLuint indexSpan[MAX_WIDTH]; \ - GLuint i; \ - for (i = 0; i < span.count; i++) { \ - zSpan[i] = FixedToDepth(span.z); \ - span.z += span.zStep; \ - indexSpan[i] = FixedToInt(span.index); \ - span.index += span.indexStep; \ - fogSpan[i] = span.fog; \ - span.fog += span.fogStep; \ - } \ - _mesa_write_index_span(ctx, span.count, span.x, span.y, \ - zSpan, fogSpan, indexSpan, NULL, GL_POLYGON); - +#define RENDER_SPAN( span ) _swrast_write_index_span(ctx, &span); #include "s_tritemp.h" -} /* * Render a flat-shaded RGBA triangle. */ -static void flat_rgba_triangle( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) -{ +#define NAME flat_rgba_triangle #define INTERP_Z 1 #define INTERP_FOG 1 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE - -#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, NULL, GL_POLYGON ); - +#define SETUP_CODE \ + ASSERT(ctx->Texture._EnabledCoordUnits == 0);\ + ASSERT(ctx->Light.ShadeModel==GL_FLAT); \ + span.interpMask |= SPAN_RGBA; \ + span.red = ChanToFixed(v2->color[0]); \ + span.green = ChanToFixed(v2->color[1]); \ + span.blue = ChanToFixed(v2->color[2]); \ + span.alpha = ChanToFixed(v2->color[3]); \ + span.redStep = 0; \ + span.greenStep = 0; \ + span.blueStep = 0; \ + span.alphaStep = 0; +#define RENDER_SPAN( span ) _swrast_write_rgba_span(ctx, &span); #include "s_tritemp.h" - ASSERT(!ctx->Texture._ReallyEnabled); /* texturing must be off */ - ASSERT(ctx->Light.ShadeModel==GL_FLAT); -} - /* * Render a smooth-shaded RGBA triangle. */ -static void smooth_rgba_triangle( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) -{ - +#define NAME smooth_rgba_triangle #define INTERP_Z 1 #define INTERP_FOG 1 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE #define INTERP_RGB 1 #define INTERP_ALPHA 1 - -#define RENDER_SPAN( span ) \ - GLdepth zSpan[MAX_WIDTH]; \ - GLchan rgbaSpan[MAX_WIDTH][4]; \ - GLfloat fogSpan[MAX_WIDTH]; \ - GLuint i; \ - for (i = 0; i < span.count; i++) { \ - rgbaSpan[i][RCOMP] = FixedToChan(span.red); \ - rgbaSpan[i][GCOMP] = FixedToChan(span.green); \ - rgbaSpan[i][BCOMP] = FixedToChan(span.blue); \ - rgbaSpan[i][ACOMP] = FixedToChan(span.alpha); \ - span.red += span.redStep; \ - span.green += span.greenStep; \ - span.blue += span.blueStep; \ - span.alpha += span.alphaStep; \ - zSpan[i] = FixedToDepth(span.z); \ - span.z += span.zStep; \ - fogSpan[i] = span.fog; \ - span.fog += span.fogStep; \ - } \ - _mesa_write_rgba_span(ctx, span.count, span.x, span.y, \ - (CONST GLdepth *) zSpan, \ - fogSpan, rgbaSpan, NULL, GL_POLYGON); - +#define SETUP_CODE \ + { \ + /* texturing must be off */ \ + ASSERT(ctx->Texture._EnabledCoordUnits == 0); \ + ASSERT(ctx->Light.ShadeModel==GL_SMOOTH); \ + } +#define RENDER_SPAN( span ) _swrast_write_rgba_span(ctx, &span); #include "s_tritemp.h" - ASSERT(!ctx->Texture._ReallyEnabled); /* texturing must be off */ - ASSERT(ctx->Light.ShadeModel==GL_SMOOTH); -} /* @@ -216,11 +146,7 @@ static void smooth_rgba_triangle( GLcontext *ctx, * * No fog. */ -static void simple_textured_triangle( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) -{ +#define NAME simple_textured_triangle #define INTERP_INT_TEX 1 #define S_SCALE twidth #define T_SCALE theight @@ -228,39 +154,38 @@ static void simple_textured_triangle( GLcontext *ctx, #define SETUP_CODE \ SWcontext *swrast = SWRAST_CONTEXT(ctx); \ struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; \ - GLint b = obj->BaseLevel; \ - 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; \ - const GLint smask = obj->Image[b]->Width - 1; \ - const GLint tmask = obj->Image[b]->Height - 1; \ + const GLint b = obj->BaseLevel; \ + const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width; \ + const GLfloat theight = (GLfloat) obj->Image[0][b]->Height; \ + const GLint twidth_log2 = obj->Image[0][b]->WidthLog2; \ + const GLchan *texture = (const GLchan *) obj->Image[0][b]->Data; \ + const GLint smask = obj->Image[0][b]->Width - 1; \ + const GLint tmask = obj->Image[0][b]->Height - 1; \ if (!texture) { \ /* this shouldn't happen */ \ return; \ } #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++) { \ + for (i = 0; i < span.end; 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.array->rgb[i][RCOMP] = texture[pos]; \ + span.array->rgb[i][GCOMP] = texture[pos+1]; \ + span.array->rgb[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 ); - + (*swrast->Driver.WriteRGBSpan)(ctx, span.end, span.x, span.y, \ + (CONST GLchan (*)[3]) span.array->rgb,\ + NULL ); #include "s_tritemp.h" -} + /* @@ -270,11 +195,7 @@ static void simple_textured_triangle( GLcontext *ctx, * * No fog. */ -static void simple_z_textured_triangle( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) -{ +#define NAME simple_z_textured_triangle #define INTERP_Z 1 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE #define INTERP_INT_TEX 1 @@ -284,49 +205,47 @@ static void simple_z_textured_triangle( GLcontext *ctx, #define SETUP_CODE \ SWcontext *swrast = SWRAST_CONTEXT(ctx); \ struct gl_texture_object *obj = ctx->Texture.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 GLchan *texture = (const GLchan *) obj->Image[b]->Data; \ - GLint smask = obj->Image[b]->Width - 1; \ - GLint tmask = obj->Image[b]->Height - 1; \ + const GLint b = obj->BaseLevel; \ + const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width; \ + const GLfloat theight = (GLfloat) obj->Image[0][b]->Height; \ + const GLint twidth_log2 = obj->Image[0][b]->WidthLog2; \ + const GLchan *texture = (const GLchan *) obj->Image[0][b]->Data; \ + const GLint smask = obj->Image[0][b]->Width - 1; \ + const GLint tmask = obj->Image[0][b]->Height - 1; \ if (!texture) { \ /* this shouldn't happen */ \ return; \ } #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++) { \ + for (i = 0; i < span.end; 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]; \ + span.array->rgb[i][RCOMP] = texture[pos]; \ + span.array->rgb[i][GCOMP] = texture[pos+1]; \ + span.array->rgb[i][BCOMP] = texture[pos+2]; \ zRow[i] = z; \ - mask[i] = 1; \ + span.array->mask[i] = 1; \ } \ else { \ - mask[i] = 0; \ + span.array->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 ); - + (*swrast->Driver.WriteRGBSpan)(ctx, span.end, span.x, span.y, \ + (CONST GLchan (*)[3]) span.array->rgb,\ + span.array->mask ); #include "s_tritemp.h" -} + #if CHAN_TYPE != GL_FLOAT @@ -339,16 +258,20 @@ struct affine_info GLint smask, tmask; GLint twidth_log2; const GLchan *texture; - GLchan er, eg, eb, ea; + GLfixed er, eg, eb, ea; GLint tbytesline, tsize; - GLint fixedToDepthShift; }; -static void -affine_span(GLcontext *ctx, struct triangle_span *span, + +/* This function can handle GL_NEAREST or GL_LINEAR sampling of 2D RGB or RGBA + * textures with GL_REPLACE, GL_MODULATE, GL_BLEND, GL_DECAL or GL_ADD + * texture env modes. + */ +static INLINE void +affine_span(GLcontext *ctx, struct sw_span *span, struct affine_info *info) { - GLint tr, tg, tb, ta; + GLchan sample[4]; /* the filtered texture sample */ /* Instead of defining a function for each mode, a test is done * between the outer and inner loops. This is to reduce code size @@ -356,94 +279,92 @@ affine_span(GLcontext *ctx, struct triangle_span *span, * 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]; \ - ta = CHAN_MAX +#define NEAREST_RGB \ + sample[RCOMP] = tex00[RCOMP]; \ + sample[GCOMP] = tex00[GCOMP]; \ + sample[BCOMP] = tex00[BCOMP]; \ + sample[ACOMP] = CHAN_MAX #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 = CHAN_MAX - -#define NEAREST_RGBA \ - tr = tex00[RCOMP]; \ - tg = tex00[GCOMP]; \ - tb = tex00[BCOMP]; \ - ta = tex00[ACOMP] + sample[RCOMP] = (ti * (si * tex00[0] + sf * tex01[0]) + \ + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * FIXED_SHIFT; \ + sample[GCOMP] = (ti * (si * tex00[1] + sf * tex01[1]) + \ + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * FIXED_SHIFT; \ + sample[BCOMP] = (ti * (si * tex00[2] + sf * tex01[2]) + \ + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * FIXED_SHIFT; \ + sample[ACOMP] = CHAN_MAX + +#define NEAREST_RGBA COPY_CHAN4(sample, tex00) #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] = 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) + sample[RCOMP] = (ti * (si * tex00[0] + sf * tex01[0]) + \ + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * FIXED_SHIFT;\ + sample[GCOMP] = (ti * (si * tex00[1] + sf * tex01[1]) + \ + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * FIXED_SHIFT;\ + sample[BCOMP] = (ti * (si * tex00[2] + sf * tex01[2]) + \ + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * FIXED_SHIFT;\ + sample[ACOMP] = (ti * (si * tex00[3] + sf * tex01[3]) + \ + tf * (si * tex10[3] + sf * tex11[3])) >> 2 * FIXED_SHIFT + +#define MODULATE \ + dest[RCOMP] = span->red * (sample[RCOMP] + 1u) >> (FIXED_SHIFT + 8); \ + dest[GCOMP] = span->green * (sample[GCOMP] + 1u) >> (FIXED_SHIFT + 8); \ + dest[BCOMP] = span->blue * (sample[BCOMP] + 1u) >> (FIXED_SHIFT + 8); \ + dest[ACOMP] = span->alpha * (sample[ACOMP] + 1u) >> (FIXED_SHIFT + 8) #define DECAL \ - dest[RCOMP] = ((CHAN_MAX - ta) * span->red \ - + ((ta + 1) * tr << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \ - dest[GCOMP] = ((CHAN_MAX - ta) * span->green \ - + ((ta + 1) * tg << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \ - dest[BCOMP] = ((CHAN_MAX - ta) * span->blue \ - + ((ta + 1) * tb << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \ - dest[ACOMP] = FixedToInt(span->alpha) + dest[RCOMP] = ((CHAN_MAX - sample[ACOMP]) * span->red + \ + ((sample[ACOMP] + 1) * sample[RCOMP] << FIXED_SHIFT)) \ + >> (FIXED_SHIFT + 8); \ + dest[GCOMP] = ((CHAN_MAX - sample[ACOMP]) * span->green + \ + ((sample[ACOMP] + 1) * sample[GCOMP] << FIXED_SHIFT)) \ + >> (FIXED_SHIFT + 8); \ + dest[BCOMP] = ((CHAN_MAX - sample[ACOMP]) * span->blue + \ + ((sample[ACOMP] + 1) * sample[BCOMP] << FIXED_SHIFT)) \ + >> (FIXED_SHIFT + 8); \ + dest[ACOMP] = FixedToInt(span->alpha) #define BLEND \ - dest[RCOMP] = ((CHAN_MAX - tr) * span->red \ - + (tr + 1) * info->er) >> (FIXED_SHIFT + 8); \ - dest[GCOMP] = ((CHAN_MAX - tg) * span->green \ - + (tg + 1) * info->eg) >> (FIXED_SHIFT + 8); \ - dest[BCOMP] = ((CHAN_MAX - 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 + dest[RCOMP] = ((CHAN_MAX - sample[RCOMP]) * span->red \ + + (sample[RCOMP] + 1) * info->er) >> (FIXED_SHIFT + 8); \ + dest[GCOMP] = ((CHAN_MAX - sample[GCOMP]) * span->green \ + + (sample[GCOMP] + 1) * info->eg) >> (FIXED_SHIFT + 8); \ + dest[BCOMP] = ((CHAN_MAX - sample[BCOMP]) * span->blue \ + + (sample[BCOMP] + 1) * info->eb) >> (FIXED_SHIFT + 8); \ + dest[ACOMP] = span->alpha * (sample[ACOMP] + 1) >> (FIXED_SHIFT + 8) + +#define REPLACE COPY_CHAN4(dest, sample) #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) + { \ + GLint rSum = FixedToInt(span->red) + (GLint) sample[RCOMP]; \ + GLint gSum = FixedToInt(span->green) + (GLint) sample[GCOMP]; \ + GLint bSum = FixedToInt(span->blue) + (GLint) sample[BCOMP]; \ + dest[RCOMP] = MIN2(rSum, CHAN_MAX); \ + dest[GCOMP] = MIN2(gSum, CHAN_MAX); \ + dest[BCOMP] = MIN2(bSum, CHAN_MAX); \ + dest[ACOMP] = span->alpha * (sample[ACOMP] + 1) >> (FIXED_SHIFT + 8); \ + } /* shortcuts */ -#define NEAREST_RGB_REPLACE NEAREST_RGB;REPLACE +#define NEAREST_RGB_REPLACE \ + NEAREST_RGB; \ + dest[0] = sample[0]; \ + dest[1] = sample[1]; \ + dest[2] = sample[2]; \ + dest[3] = FixedToInt(span->alpha); -#define NEAREST_RGBA_REPLACE *(GLint *)dest = *(GLint *)tex00 +#define NEAREST_RGBA_REPLACE COPY_CHAN4(dest, tex00) #define SPAN_NEAREST(DO_TEX,COMP) \ - for (i = 0; i < span->count; i++) { \ + for (i = 0; i < span->end; i++) { \ /* Isn't it necessary to use FixedFloor below?? */ \ 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; \ @@ -454,7 +375,7 @@ affine_span(GLcontext *ctx, struct triangle_span *span, } #define SPAN_LINEAR(DO_TEX,COMP) \ - for (i = 0; i < span->count; i++) { \ + for (i = 0; i < span->end; i++) { \ /* Isn't it necessary to use FixedFloor below?? */ \ GLint s = FixedToInt(span->intTex[0]) & info->smask; \ GLint t = FixedToInt(span->intTex[1]) & info->tmask; \ @@ -477,11 +398,7 @@ affine_span(GLcontext *ctx, struct triangle_span *span, 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; \ @@ -491,14 +408,9 @@ affine_span(GLcontext *ctx, struct triangle_span *span, dest += 4; \ } -#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; + GLchan *dest = span->array->rgba[0]; span->intTex[0] -= FIXED_HALF; span->intTex[1] -= FIXED_HALF; @@ -521,7 +433,8 @@ affine_span(GLcontext *ctx, struct triangle_span *span, SPAN_NEAREST(NEAREST_RGB;ADD,3); break; default: - abort(); + _mesa_problem(ctx, "bad tex env mode in SPAN_LINEAR"); + return; } break; case GL_RGBA: @@ -542,7 +455,8 @@ affine_span(GLcontext *ctx, struct triangle_span *span, SPAN_NEAREST(NEAREST_RGBA_REPLACE,4); break; default: - abort(); + _mesa_problem(ctx, "bad tex env mode (2) in SPAN_LINEAR"); + return; } break; } @@ -568,7 +482,8 @@ affine_span(GLcontext *ctx, struct triangle_span *span, SPAN_LINEAR(LINEAR_RGB;ADD,3); break; default: - abort(); + _mesa_problem(ctx, "bad tex env mode (3) in SPAN_LINEAR"); + return; } break; case GL_RGBA: @@ -589,17 +504,19 @@ affine_span(GLcontext *ctx, struct triangle_span *span, SPAN_LINEAR(LINEAR_RGBA;REPLACE,4); break; default: - abort(); - } break; + _mesa_problem(ctx, "bad tex env mode (4) in SPAN_LINEAR"); + return; + } + break; } break; } - _mesa_write_rgba_span(ctx, span->count, span->x, span->y, - zspan, fogspan, rgba, NULL, GL_POLYGON); + span->interpMask &= ~SPAN_RGBA; + ASSERT(span->arrayMask & SPAN_RGBA); + _swrast_write_rgba_span(ctx, span); #undef SPAN_NEAREST #undef SPAN_LINEAR -#undef FixedToDepth } @@ -607,11 +524,7 @@ affine_span(GLcontext *ctx, struct triangle_span *span, /* * 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 NAME affine_textured_triangle #define INTERP_Z 1 #define INTERP_FOG 1 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE @@ -625,24 +538,24 @@ static void affine_textured_triangle( GLcontext *ctx, 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; \ + const GLint b = obj->BaseLevel; \ + const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width; \ + const GLfloat theight = (GLfloat) obj->Image[0][b]->Height; \ + info.texture = (const GLchan *) obj->Image[0][b]->Data; \ + info.twidth_log2 = obj->Image[0][b]->WidthLog2; \ + info.smask = obj->Image[0][b]->Width - 1; \ + info.tmask = obj->Image[0][b]->Height - 1; \ + info.format = obj->Image[0][b]->Format; \ info.filter = obj->MinFilter; \ info.envmode = unit->EnvMode; \ + span.arrayMask |= SPAN_RGBA; \ \ 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]); \ + info.er = FloatToFixed(unit->EnvColor[RCOMP] * CHAN_MAXF); \ + info.eg = FloatToFixed(unit->EnvColor[GCOMP] * CHAN_MAXF); \ + info.eb = FloatToFixed(unit->EnvColor[BCOMP] * CHAN_MAXF); \ + info.ea = FloatToFixed(unit->EnvColor[ACOMP] * CHAN_MAXF); \ } \ if (!info.texture) { \ /* this shouldn't happen */ \ @@ -653,36 +566,27 @@ static void affine_textured_triangle( GLcontext *ctx, case GL_ALPHA: \ case GL_LUMINANCE: \ case GL_INTENSITY: \ - info.tbytesline = obj->Image[b]->Width; \ + info.tbytesline = obj->Image[0][b]->Width; \ break; \ case GL_LUMINANCE_ALPHA: \ - info.tbytesline = obj->Image[b]->Width * 2; \ + info.tbytesline = obj->Image[0][b]->Width * 2; \ break; \ case GL_RGB: \ - info.tbytesline = obj->Image[b]->Width * 3; \ + info.tbytesline = obj->Image[0][b]->Width * 3; \ break; \ case GL_RGBA: \ - info.tbytesline = obj->Image[b]->Width * 4; \ + info.tbytesline = obj->Image[0][b]->Width * 4; \ break; \ default: \ _mesa_problem(NULL, "Bad texture format in affine_texture_triangle");\ return; \ } \ - info.tsize = obj->Image[b]->Height * info.tbytesline; + info.tsize = obj->Image[0][b]->Height * info.tbytesline; -#define RENDER_SPAN( span ) \ - if (ctx->Light.ShadeModel == GL_FLAT) { \ - span.red = IntToFixed(v2->color[RCOMP]); \ - span.green = IntToFixed(v2->color[GCOMP]); \ - span.blue = IntToFixed(v2->color[BCOMP]); \ - span.alpha = IntToFixed(v2->color[ACOMP]); \ - } \ - affine_span(ctx, &span, &info); +#define RENDER_SPAN( span ) affine_span(ctx, &span, &info); #include "s_tritemp.h" -} - struct persp_info @@ -693,17 +597,16 @@ struct persp_info GLint smask, tmask; GLint twidth_log2; const GLchan *texture; - GLchan er, eg, eb, ea; + GLfixed er, eg, eb, ea; /* texture env color */ GLint tbytesline, tsize; - GLint fixedToDepthShift; }; -static void -fast_persp_span(GLcontext *ctx, struct triangle_span *span, +static INLINE void +fast_persp_span(GLcontext *ctx, struct sw_span *span, struct persp_info *info) { - GLint tr, tg, tb, ta; + GLchan sample[4]; /* the filtered texture sample */ /* Instead of defining a function for each mode, a test is done * between the outer and inner loops. This is to reduce code size @@ -711,20 +614,16 @@ fast_persp_span(GLcontext *ctx, struct triangle_span *span, * unused variables (for instance tf,sf,ti,si in case of GL_NEAREST). */ #define SPAN_NEAREST(DO_TEX,COMP) \ - for (i = 0; i < span->count; i++) { \ + for (i = 0; i < span->end; i++) { \ GLdouble invQ = tex_coord[2] ? \ (1.0 / tex_coord[2]) : 1.0; \ - GLfloat s_tmp = tex_coord[0] * invQ; \ - GLfloat t_tmp = tex_coord[1] * invQ; \ + GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); \ + GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); \ GLint s = IFLOOR(s_tmp) & info->smask; \ GLint t = IFLOOR(t_tmp) & 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; \ @@ -736,13 +635,13 @@ fast_persp_span(GLcontext *ctx, struct triangle_span *span, } #define SPAN_LINEAR(DO_TEX,COMP) \ - for (i = 0; i < span->count; i++) { \ + for (i = 0; i < span->end; i++) { \ GLdouble invQ = tex_coord[2] ? \ (1.0 / tex_coord[2]) : 1.0; \ - GLfloat s_tmp = tex_coord[0] * invQ - 0.5F; \ - GLfloat t_tmp = tex_coord[1] * invQ - 0.5F; \ - GLfixed s_fix = FloatToFixed(s_tmp); \ - GLfixed t_fix = FloatToFixed(t_tmp); \ + GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); \ + GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); \ + GLfixed s_fix = FloatToFixed(s_tmp) - FIXED_HALF; \ + GLfixed t_fix = FloatToFixed(t_tmp) - FIXED_HALF; \ GLint s = FixedToInt(FixedFloor(s_fix)) & info->smask; \ GLint t = FixedToInt(FixedFloor(t_fix)) & info->tmask; \ GLfixed sf = s_fix & FIXED_FRAC_MASK; \ @@ -764,11 +663,7 @@ fast_persp_span(GLcontext *ctx, struct triangle_span *span, 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; \ @@ -779,23 +674,17 @@ fast_persp_span(GLcontext *ctx, struct triangle_span *span, dest += 4; \ } -#define FixedToDepth(F) ((F) >> fixedToDepthShift) - GLuint i; - GLdepth zspan[MAX_WIDTH]; GLfloat tex_coord[3], tex_step[3]; - GLfloat fogspan[MAX_WIDTH]; - GLchan rgba[MAX_WIDTH][4]; - GLchan *dest = rgba[0]; - const GLint fixedToDepthShift = info->fixedToDepthShift; - - tex_coord[0] = span->tex[0][0] * (info->smask + 1), - tex_step[0] = span->texStep[0][0] * (info->smask + 1); - tex_coord[1] = span->tex[0][1] * (info->tmask + 1), - tex_step[1] = span->texStep[0][1] * (info->tmask + 1); + GLchan *dest = span->array->rgba[0]; + + tex_coord[0] = span->tex[0][0] * (info->smask + 1); + tex_step[0] = span->texStepX[0][0] * (info->smask + 1); + tex_coord[1] = span->tex[0][1] * (info->tmask + 1); + tex_step[1] = span->texStepX[0][1] * (info->tmask + 1); /* span->tex[0][2] only if 3D-texturing, here only 2D */ - tex_coord[2] = span->tex[0][3], - tex_step[2] = span->texStep[0][3]; + tex_coord[2] = span->tex[0][3]; + tex_step[2] = span->texStepX[0][3]; switch (info->filter) { case GL_NEAREST: @@ -816,7 +705,8 @@ fast_persp_span(GLcontext *ctx, struct triangle_span *span, SPAN_NEAREST(NEAREST_RGB;ADD,3); break; default: - abort(); + _mesa_problem(ctx, "bad tex env mode (5) in SPAN_LINEAR"); + return; } break; case GL_RGBA: @@ -837,7 +727,8 @@ fast_persp_span(GLcontext *ctx, struct triangle_span *span, SPAN_NEAREST(NEAREST_RGBA_REPLACE,4); break; default: - abort(); + _mesa_problem(ctx, "bad tex env mode (6) in SPAN_LINEAR"); + return; } break; } @@ -861,7 +752,8 @@ fast_persp_span(GLcontext *ctx, struct triangle_span *span, SPAN_LINEAR(LINEAR_RGB;ADD,3); break; default: - abort(); + _mesa_problem(ctx, "bad tex env mode (7) in SPAN_LINEAR"); + return; } break; case GL_RGBA: @@ -882,25 +774,19 @@ fast_persp_span(GLcontext *ctx, struct triangle_span *span, SPAN_LINEAR(LINEAR_RGBA;REPLACE,4); break; default: - abort(); + _mesa_problem(ctx, "bad tex env mode (8) in SPAN_LINEAR"); + return; } break; } break; } - /* This does not seem to be necessary, but I don't know !! */ - /* span->tex[0][0] = tex_coord[0] / (info->smask + 1), - span->tex[0][1] = tex_coord[1] / (info->tmask + 1),*/ - /* span->tex[0][2] only if 3D-texturing, here only 2D */ - /* span->tex[0][3] = tex_coord[2]; */ - _mesa_write_rgba_span(ctx, span->count, span->x, span->y, - zspan, fogspan, rgba, NULL, GL_POLYGON); - + ASSERT(span->arrayMask & SPAN_RGBA); + _swrast_write_rgba_span(ctx, span); #undef SPAN_NEAREST #undef SPAN_LINEAR -#undef FixedToDepth } @@ -910,12 +796,9 @@ fast_persp_span(GLcontext *ctx, struct triangle_span *span, * by interpolated Q/W comes out right. * */ -static void persp_textured_triangle( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) -{ +#define NAME persp_textured_triangle #define INTERP_Z 1 +#define INTERP_W 1 #define INTERP_FOG 1 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE #define INTERP_RGB 1 @@ -924,24 +807,23 @@ static void persp_textured_triangle( GLcontext *ctx, #define SETUP_CODE \ struct persp_info info; \ - struct gl_texture_unit *unit = ctx->Texture.Unit+0; \ - struct gl_texture_object *obj = unit->Current2D; \ - GLint b = obj->BaseLevel; \ - 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; \ + const struct gl_texture_unit *unit = ctx->Texture.Unit+0; \ + const struct gl_texture_object *obj = unit->Current2D; \ + const GLint b = obj->BaseLevel; \ + info.texture = (const GLchan *) obj->Image[0][b]->Data; \ + info.twidth_log2 = obj->Image[0][b]->WidthLog2; \ + info.smask = obj->Image[0][b]->Width - 1; \ + info.tmask = obj->Image[0][b]->Height - 1; \ + info.format = obj->Image[0][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]); \ + info.er = FloatToFixed(unit->EnvColor[RCOMP] * CHAN_MAXF); \ + info.eg = FloatToFixed(unit->EnvColor[GCOMP] * CHAN_MAXF); \ + info.eb = FloatToFixed(unit->EnvColor[BCOMP] * CHAN_MAXF); \ + info.ea = FloatToFixed(unit->EnvColor[ACOMP] * CHAN_MAXF); \ } \ if (!info.texture) { \ /* this shouldn't happen */ \ @@ -952,325 +834,33 @@ static void persp_textured_triangle( GLcontext *ctx, case GL_ALPHA: \ case GL_LUMINANCE: \ case GL_INTENSITY: \ - info.tbytesline = obj->Image[b]->Width; \ + info.tbytesline = obj->Image[0][b]->Width; \ break; \ case GL_LUMINANCE_ALPHA: \ - info.tbytesline = obj->Image[b]->Width * 2; \ + info.tbytesline = obj->Image[0][b]->Width * 2; \ break; \ case GL_RGB: \ - info.tbytesline = obj->Image[b]->Width * 3; \ + info.tbytesline = obj->Image[0][b]->Width * 3; \ break; \ case GL_RGBA: \ - info.tbytesline = obj->Image[b]->Width * 4; \ + info.tbytesline = obj->Image[0][b]->Width * 4; \ break; \ default: \ _mesa_problem(NULL, "Bad texture format in persp_textured_triangle");\ return; \ } \ - info.tsize = obj->Image[b]->Height * info.tbytesline; + info.tsize = obj->Image[0][b]->Height * info.tbytesline; -#define RENDER_SPAN( span ) \ - if (ctx->Light.ShadeModel == GL_FLAT) { \ - span.red = IntToFixed(v2->color[RCOMP]); \ - span.green = IntToFixed(v2->color[GCOMP]); \ - span.blue = IntToFixed(v2->color[BCOMP]); \ - span.alpha = IntToFixed(v2->color[ACOMP]); \ - } \ +#define RENDER_SPAN( span ) \ + span.interpMask &= ~SPAN_RGBA; \ + span.arrayMask |= SPAN_RGBA; \ fast_persp_span(ctx, &span, &info); #include "s_tritemp.h" -} - #endif /* CHAN_BITS != GL_FLOAT */ - -/* - * Generate arrays of fragment colors, z, fog, texcoords, etc from a - * triangle span object. Then call the span/fragment processsing - * functions in s_span.[ch]. This is used by a bunch of the textured - * triangle functions. - */ -static void -rasterize_span(GLcontext *ctx, const struct triangle_span *span) -{ - DEFMARRAY(GLchan, rgba, MAX_WIDTH, 4); - DEFMARRAY(GLchan, spec, MAX_WIDTH, 4); - DEFARRAY(GLuint, index, MAX_WIDTH); - DEFARRAY(GLuint, z, MAX_WIDTH); - DEFARRAY(GLfloat, fog, MAX_WIDTH); - DEFARRAY(GLfloat, sTex, MAX_WIDTH); - DEFARRAY(GLfloat, tTex, MAX_WIDTH); - DEFARRAY(GLfloat, rTex, MAX_WIDTH); - DEFARRAY(GLfloat, lambda, MAX_WIDTH); - DEFMARRAY(GLfloat, msTex, MAX_TEXTURE_UNITS, MAX_WIDTH); - DEFMARRAY(GLfloat, mtTex, MAX_TEXTURE_UNITS, MAX_WIDTH); - DEFMARRAY(GLfloat, mrTex, MAX_TEXTURE_UNITS, MAX_WIDTH); - DEFMARRAY(GLfloat, mLambda, MAX_TEXTURE_UNITS, MAX_WIDTH); - - CHECKARRAY(rgba, return); - CHECKARRAY(spec, return); - CHECKARRAY(index, return); - CHECKARRAY(z, return); - CHECKARRAY(fog, return); - CHECKARRAY(sTex, return); - CHECKARRAY(tTex, return); - CHECKARRAY(rTex, return); - CHECKARRAY(lambda, return); - CHECKARRAY(msTex, return); - CHECKARRAY(mtTex, return); - CHECKARRAY(mrTex, return); - CHECKARRAY(mLambda, return); - - if (span->activeMask & SPAN_RGBA) { -#if CHAN_TYPE == GL_FLOAT - GLfloat r = span->red; - GLfloat g = span->green; - GLfloat b = span->blue; - GLfloat a = span->alpha; -#else - GLfixed r = span->red; - GLfixed g = span->green; - GLfixed b = span->blue; - GLfixed a = span->alpha; -#endif - GLuint i; - for (i = 0; i < span->count; i++) { - rgba[i][RCOMP] = FixedToChan(r); - rgba[i][GCOMP] = FixedToChan(g); - rgba[i][BCOMP] = FixedToChan(b); - rgba[i][ACOMP] = FixedToChan(a); - r += span->redStep; - g += span->greenStep; - b += span->blueStep; - a += span->alphaStep; - } - } - if (span->activeMask & SPAN_SPEC) { -#if CHAN_TYPE == GL_FLOAT - GLfloat r = span->specRed; - GLfloat g = span->specGreen; - GLfloat b = span->specBlue; -#else - GLfixed r = span->specRed; - GLfixed g = span->specGreen; - GLfixed b = span->specBlue; -#endif - GLuint i; - for (i = 0; i < span->count; i++) { - spec[i][RCOMP] = FixedToChan(r); - spec[i][GCOMP] = FixedToChan(g); - spec[i][BCOMP] = FixedToChan(b); - r += span->specRedStep; - g += span->specGreenStep; - b += span->specBlueStep; - } - } - if (span->activeMask & SPAN_INDEX) { - 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, - NULL, GL_POLYGON ); - } - else { - _mesa_write_multitexture_span(ctx, span->count, span->x, span->y, - z, fogPtr, - (const GLfloat (*)[MAX_WIDTH]) msTex, - (const GLfloat (*)[MAX_WIDTH]) mtTex, - (const GLfloat (*)[MAX_WIDTH]) mrTex, - (GLfloat (*)[MAX_WIDTH]) mLambda, - rgba, NULL, NULL, GL_POLYGON); - } - } - else { - /* single texture */ - if (span->activeMask & SPAN_SPEC) { - _mesa_write_texture_span(ctx, span->count, span->x, span->y, - z, fogPtr, sTex, tTex, rTex, lambda, - rgba, (CONST GLchan (*)[4]) spec, - NULL, GL_POLYGON); - } - else { - _mesa_write_texture_span(ctx, span->count, span->x, span->y, - z, fogPtr, sTex, tTex, rTex, lambda, - rgba, NULL, NULL, GL_POLYGON); - } - } - } - else { - _mesa_problem(ctx, "rasterize_span() should only be used for texturing"); - } - - UNDEFARRAY(rgba); - UNDEFARRAY(spec); - UNDEFARRAY(index); - UNDEFARRAY(z); - UNDEFARRAY(fog); - UNDEFARRAY(sTex); - UNDEFARRAY(tTex); - UNDEFARRAY(rTex); - UNDEFARRAY(lambda); - UNDEFARRAY(msTex); - UNDEFARRAY(mtTex); - UNDEFARRAY(mrTex); - UNDEFARRAY(mLambda); -} - @@ -1278,351 +868,80 @@ rasterize_span(GLcontext *ctx, const struct triangle_span *span) * Render a smooth-shaded, textured, RGBA triangle. * Interpolate S,T,R with perspective correction, w/out mipmapping. */ -static void general_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_TEX 1 - -#define SETUP_CODE \ - const struct gl_texture_object *obj = ctx->Texture.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; \ - DEFARRAY(GLfloat, sSpan, MAX_WIDTH); /* mac 32k limitation */ \ - DEFARRAY(GLfloat, tSpan, MAX_WIDTH); /* mac 32k limitation */ \ - DEFARRAY(GLfloat, uSpan, MAX_WIDTH); /* mac 32k limitation */ \ - CHECKARRAY(sSpan, return); /* mac 32k limitation */ \ - CHECKARRAY(tSpan, return); /* mac 32k limitation */ \ - CHECKARRAY(uSpan, return); /* mac 32k limitation */ \ - if (flatShade) { \ - rFlat = ChanToFixed(v2->color[RCOMP]); \ - gFlat = ChanToFixed(v2->color[GCOMP]); \ - bFlat = ChanToFixed(v2->color[BCOMP]); \ - aFlat = ChanToFixed(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]; \ - 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] = FixedToChan(span.red); \ - rgbaSpan[i][GCOMP] = FixedToChan(span.green); \ - rgbaSpan[i][BCOMP] = FixedToChan(span.blue); \ - rgbaSpan[i][ACOMP] = FixedToChan(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, NULL, GL_POLYGON ); - -#define CLEANUP_CODE \ - UNDEFARRAY(sSpan); /* mac 32k limitation */ \ - UNDEFARRAY(tSpan); \ - UNDEFARRAY(uSpan); - -#include "s_tritemp.h" -} - - -/* - * Render a smooth-shaded, textured, RGBA triangle with separate specular - * color interpolation. - * Interpolate texcoords with perspective correction, w/out mipmapping. - */ -static void general_textured_spec_triangle( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) -{ +#define NAME general_textured_triangle #define INTERP_Z 1 +#define INTERP_W 1 #define INTERP_FOG 1 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE #define INTERP_RGB 1 #define INTERP_SPEC 1 #define INTERP_ALPHA 1 #define INTERP_TEX 1 - -#define SETUP_CODE \ - const struct gl_texture_object *obj = ctx->Texture.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 = ChanToFixed(v2->color[RCOMP]); \ - gFlat = ChanToFixed(v2->color[GCOMP]); \ - bFlat = ChanToFixed(v2->color[BCOMP]); \ - aFlat = ChanToFixed(v2->color[ACOMP]); \ - srFlat = ChanToFixed(v2->specular[RCOMP]); \ - sgFlat = ChanToFixed(v2->specular[GCOMP]); \ - sbFlat = ChanToFixed(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" -} - - -/* - * Render a smooth-shaded, textured, RGBA triangle. - * 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_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_TEX 1 -#define INTERP_LAMBDA 1 - -#define SETUP_CODE \ - const struct gl_texture_object *obj = ctx->Texture.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 = ChanToFixed(v2->color[RCOMP]); \ - gFlat = ChanToFixed(v2->color[GCOMP]); \ - bFlat = ChanToFixed(v2->color[BCOMP]); \ - aFlat = ChanToFixed(v2->color[ACOMP]); \ - srFlat = ChanToFixed(v2->specular[RCOMP]); \ - sgFlat = ChanToFixed(v2->specular[GCOMP]); \ - sbFlat = ChanToFixed(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); - +#define RENDER_SPAN( span ) _swrast_write_texture_span(ctx, &span); #include "s_tritemp.h" -} - -/* - * Render a smooth-shaded, textured, RGBA triangle with separate specular - * interpolation. - * 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_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_SPEC 1 -#define INTERP_ALPHA 1 -#define INTERP_TEX 1 -#define INTERP_LAMBDA 1 - -#define SETUP_CODE \ - const struct gl_texture_object *obj = ctx->Texture.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 = ChanToFixed(v2->color[RCOMP]); \ - gFlat = ChanToFixed(v2->color[GCOMP]); \ - bFlat = ChanToFixed(v2->color[BCOMP]); \ - aFlat = ChanToFixed(v2->color[ACOMP]); \ - srFlat = ChanToFixed(v2->specular[RCOMP]); \ - sgFlat = ChanToFixed(v2->specular[GCOMP]); \ - sbFlat = ChanToFixed(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" -} /* * This is the big one! - * Interpolate Z, RGB, Alpha, specular, fog, and N sets of texture coordinates - * with lambda (LOD). + * Interpolate Z, RGB, Alpha, specular, fog, and N sets of texture coordinates. * Yup, it's slow. */ -static void -lambda_multitextured_triangle( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) -{ - +#define NAME multitextured_triangle #define INTERP_Z 1 +#define INTERP_W 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_LAMBDA 1 - -#define SETUP_CODE \ - const GLboolean flatShade = (ctx->Light.ShadeModel == GL_FLAT); \ - GLfixed rFlat, gFlat, bFlat, aFlat; \ - GLfixed srFlat, sgFlat, sbFlat; \ - GLuint u; \ - if (flatShade) { \ - rFlat = ChanToFixed(v2->color[RCOMP]); \ - gFlat = ChanToFixed(v2->color[GCOMP]); \ - bFlat = ChanToFixed(v2->color[BCOMP]); \ - aFlat = ChanToFixed(v2->color[ACOMP]); \ - srFlat = ChanToFixed(v2->specular[RCOMP]); \ - sgFlat = ChanToFixed(v2->specular[GCOMP]); \ - sbFlat = ChanToFixed(v2->specular[BCOMP]); \ - } \ - 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); - +#define RENDER_SPAN( span ) _swrast_write_texture_span(ctx, &span); #include "s_tritemp.h" -} -static void occlusion_zless_triangle( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) -{ - if (ctx->OcclusionResult) { - return; - } - +/* + * Special tri function for occlusion testing + */ +#define NAME occlusion_zless_triangle #define DO_OCCLUSION_TEST #define INTERP_Z 1 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE - +#define SETUP_CODE \ + if (ctx->OcclusionResult && !ctx->Occlusion.Active) { \ + return; \ + } #define RENDER_SPAN( span ) \ GLuint i; \ - for (i = 0; i < span.count; i++) { \ + for (i = 0; i < span.end; i++) { \ GLdepth z = FixedToDepth(span.z); \ if (z < zRow[i]) { \ ctx->OcclusionResult = GL_TRUE; \ - return; \ + ctx->Occlusion.PassedCounter++; \ } \ span.z += span.zStep; \ } - #include "s_tritemp.h" -} -static void nodraw_triangle( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2 ) + + +static void +nodraw_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) { (void) (ctx && v0 && v1 && v2); } + +/* + * This is used when separate specular color is enabled, but not + * texturing. We add the specular color to the primary color, + * draw the triangle, then restore the original primary color. + * Inefficient, but seldom needed. + */ void _swrast_add_spec_terms_triangle( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1, @@ -1631,14 +950,40 @@ void _swrast_add_spec_terms_triangle( GLcontext *ctx, SWvertex *ncv0 = (SWvertex *)v0; /* drop const qualifier */ SWvertex *ncv1 = (SWvertex *)v1; SWvertex *ncv2 = (SWvertex *)v2; +#if CHAN_TYPE == GL_FLOAT + GLfloat rSum, gSum, bSum; +#else + GLint rSum, gSum, bSum; +#endif GLchan c[3][4]; + /* save original colors */ COPY_CHAN4( c[0], ncv0->color ); COPY_CHAN4( c[1], ncv1->color ); COPY_CHAN4( c[2], ncv2->color ); - ACC_3V( ncv0->color, ncv0->specular ); - ACC_3V( ncv1->color, ncv1->specular ); - ACC_3V( ncv2->color, ncv2->specular ); + /* sum v0 */ + rSum = ncv0->color[0] + ncv0->specular[0]; + gSum = ncv0->color[1] + ncv0->specular[1]; + bSum = ncv0->color[2] + ncv0->specular[2]; + ncv0->color[0] = MIN2(rSum, CHAN_MAX); + ncv0->color[1] = MIN2(gSum, CHAN_MAX); + ncv0->color[2] = MIN2(bSum, CHAN_MAX); + /* sum v1 */ + rSum = ncv1->color[0] + ncv1->specular[0]; + gSum = ncv1->color[1] + ncv1->specular[1]; + bSum = ncv1->color[2] + ncv1->specular[2]; + ncv1->color[0] = MIN2(rSum, CHAN_MAX); + ncv1->color[1] = MIN2(gSum, CHAN_MAX); + ncv1->color[2] = MIN2(bSum, CHAN_MAX); + /* sum v2 */ + rSum = ncv2->color[0] + ncv2->specular[0]; + gSum = ncv2->color[1] + ncv2->specular[1]; + bSum = ncv2->color[2] + ncv2->specular[2]; + ncv2->color[0] = MIN2(rSum, CHAN_MAX); + ncv2->color[1] = MIN2(gSum, CHAN_MAX); + ncv2->color[2] = MIN2(bSum, CHAN_MAX); + /* draw */ SWRAST_CONTEXT(ctx)->SpecTriangle( ctx, ncv0, ncv1, ncv2 ); + /* restore original colors */ COPY_CHAN4( ncv0->color, c[0] ); COPY_CHAN4( ncv1->color, c[1] ); COPY_CHAN4( ncv2->color, c[2] ); @@ -1649,13 +994,13 @@ void _swrast_add_spec_terms_triangle( GLcontext *ctx, #ifdef DEBUG /* record the current triangle function name */ -static const char *triFuncName = NULL; +const char *_mesa_triFuncName = NULL; -#define USE(triFunc) \ -do { \ - triFuncName = #triFunc; \ - /*printf("%s\n", triFuncName);*/ \ - swrast->Triangle = triFunc; \ +#define USE(triFunc) \ +do { \ + _mesa_triFuncName = #triFunc; \ + /*printf("%s\n", _mesa_triFuncName);*/ \ + swrast->Triangle = triFunc; \ } while (0) #else @@ -1689,12 +1034,13 @@ _swrast_choose_triangle( GLcontext *ctx ) if (ctx->RenderMode==GL_RENDER) { if (ctx->Polygon.SmoothFlag) { - _mesa_set_aa_triangle_function(ctx); + _swrast_set_aa_triangle_function(ctx); ASSERT(swrast->Triangle); return; } - if (ctx->Depth.OcclusionTest && + /* special case for occlusion testing */ + if ((ctx->Depth.OcclusionTest || ctx->Occlusion.Active) && ctx->Depth.Test && ctx->Depth.Mask == GL_FALSE && ctx->Depth.Func == GL_LESS && @@ -1711,24 +1057,28 @@ _swrast_choose_triangle( GLcontext *ctx ) } } - if (ctx->Texture._ReallyEnabled) { + if (ctx->Texture._EnabledCoordUnits || ctx->FragmentProgram.Enabled) { /* Ugh, we do a _lot_ of tests to pick the best textured tri func */ const struct gl_texture_object *texObj2D; const struct gl_texture_image *texImg; GLenum minFilter, magFilter, envMode; GLint format; texObj2D = ctx->Texture.Unit[0].Current2D; - texImg = texObj2D ? texObj2D->Image[texObj2D->BaseLevel] : NULL; + texImg = texObj2D ? texObj2D->Image[0][texObj2D->BaseLevel] : NULL; format = texImg ? texImg->TexFormat->MesaFormat : -1; minFilter = texObj2D ? texObj2D->MinFilter : (GLenum) 0; magFilter = texObj2D ? texObj2D->MagFilter : (GLenum) 0; envMode = ctx->Texture.Unit[0].EnvMode; - /* First see if we can used an optimized 2-D texture function */ - if (ctx->Texture._ReallyEnabled==TEXTURE0_2D + /* First see if we can use an optimized 2-D texture function */ + if (ctx->Texture._EnabledCoordUnits == 1 + && !ctx->FragmentProgram.Enabled + && ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT && texObj2D->WrapS==GL_REPEAT && texObj2D->WrapT==GL_REPEAT + && texObj2D->_IsPowerOfTwo && texImg->Border==0 + && texImg->Width == texImg->RowStride && (format == MESA_FORMAT_RGB || format == MESA_FORMAT_RGBA) && minFilter == magFilter && ctx->Light.Model.ColorControl == GL_SINGLE_COLOR @@ -1750,7 +1100,7 @@ _swrast_choose_triangle( GLcontext *ctx ) } } else { -#if CHAN_TYPE == GL_FLOAT +#if (CHAN_BITS == 16 || CHAN_BITS == 32) USE(general_textured_triangle); #else USE(affine_textured_triangle); @@ -1758,7 +1108,7 @@ _swrast_choose_triangle( GLcontext *ctx ) } } else { -#if CHAN_TYPE == GL_FLOAT +#if (CHAN_BITS == 16 || CHAN_BITS == 32) USE(general_textured_triangle); #else USE(persp_textured_triangle); @@ -1766,38 +1116,17 @@ _swrast_choose_triangle( GLcontext *ctx ) } } else { - /* More complicated textures (mipmap, multi-tex, sep specular) */ - GLboolean needLambda; - /* if mag filter != min filter we need to compute lambda */ - const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; - if (obj && obj->MinFilter != obj->MagFilter) - needLambda = GL_TRUE; - else - needLambda = GL_FALSE; - if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) { - USE(lambda_multitextured_triangle); - } - else if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { - /* separate specular color interpolation */ - if (needLambda) { - USE(lambda_textured_spec_triangle); - } - else { - USE(general_textured_spec_triangle); - } + /* general case textured triangles */ + if (ctx->Texture._EnabledCoordUnits > 1) { + USE(multitextured_triangle); } else { - if (needLambda) { - USE(lambda_textured_triangle); - } - else { - USE(general_textured_triangle); - } + USE(general_textured_triangle); } } } else { - ASSERT(!ctx->Texture._ReallyEnabled); + ASSERT(!ctx->Texture._EnabledCoordUnits); if (ctx->Light.ShadeModel==GL_SMOOTH) { /* smooth shaded, no texturing, stippled or some raster ops */ if (rgbmode) { @@ -1819,10 +1148,10 @@ _swrast_choose_triangle( GLcontext *ctx ) } } else if (ctx->RenderMode==GL_FEEDBACK) { - USE(_mesa_feedback_triangle); + USE(_swrast_feedback_triangle); } else { /* GL_SELECT mode */ - USE(_mesa_select_triangle); + USE(_swrast_select_triangle); } }