summaryrefslogtreecommitdiff
path: root/src/mesa/swrast
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2001-05-14 16:23:04 +0000
committerBrian Paul <brian.paul@tungstengraphics.com>2001-05-14 16:23:04 +0000
commit9bf68ad963ba92b5d1e725f965979042495a5313 (patch)
tree3fd4665ac70a6c4a08734e60850a44cc1a60bda2 /src/mesa/swrast
parent9cf779e7ac5509aa2d8706b882e9a6b43837cebd (diff)
New triangle rasterization code. Store per-span initial/step values in the
new triangle_span struct. Much cleaner code and possibilities for future optimizations.
Diffstat (limited to 'src/mesa/swrast')
-rw-r--r--src/mesa/swrast/s_triangle.c1930
-rw-r--r--src/mesa/swrast/s_trispan.h79
-rw-r--r--src/mesa/swrast/s_tritemp.h567
3 files changed, 1322 insertions, 1254 deletions
diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c
index 82c690502b..29805a537a 100644
--- a/src/mesa/swrast/s_triangle.c
+++ b/src/mesa/swrast/s_triangle.c
@@ -1,4 +1,4 @@
-/* $Id: s_triangle.c,v 1.25 2001/05/03 22:13:32 brianp Exp $ */
+/* $Id: s_triangle.c,v 1.26 2001/05/14 16:23:04 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -47,6 +47,9 @@
#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,
@@ -78,23 +81,18 @@ static void flat_ci_triangle( GLcontext *ctx,
#define INTERP_Z 1
#define INTERP_FOG 1
-#define INNER_LOOP( LEFT, RIGHT, Y ) \
- { \
- const GLint n = RIGHT-LEFT; \
- GLint i; \
- GLdepth zspan[MAX_WIDTH]; \
- GLfloat fogspan[MAX_WIDTH]; \
- if (n>0) { \
- for (i=0;i<n;i++) { \
- zspan[i] = FixedToDepth(ffz); \
- ffz += fdzdx; \
- fogspan[i] = ffog; \
- ffog += dfogdx; \
- } \
- _mesa_write_monoindex_span( ctx, n, LEFT, Y, zspan, \
- fogspan, v0->index, 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;i<n;i++) { \
- zspan[i] = FixedToDepth(ffz); \
- ffz += fdzdx; \
- index[i] = FixedToInt(ffi); \
- ffi += fdidx; \
- fogspan[i] = ffog; \
- ffog += dfogdx; \
- } \
- _mesa_write_index_span( ctx, n, LEFT, Y, zspan, fogspan, \
- index, GL_POLYGON ); \
- } \
- }
+#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, GL_POLYGON);
#include "s_tritemp.h"
}
@@ -151,24 +144,18 @@ static void flat_rgba_triangle( GLcontext *ctx,
#define INTERP_FOG 1
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#define INNER_LOOP( LEFT, RIGHT, Y ) \
- { \
- const GLint n = RIGHT-LEFT; \
- GLint i; \
- GLdepth zspan[MAX_WIDTH]; \
- GLfloat fogspan[MAX_WIDTH]; \
- if (n>0) { \
- for (i=0;i<n;i++) { \
- zspan[i] = FixedToDepth(ffz); \
- ffz += fdzdx; \
- fogspan[i] = ffog; \
- ffog += dfogdx; \
- } \
- _mesa_write_monocolor_span( ctx, n, LEFT, Y, zspan, \
- fogspan, v2->color, \
- 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;i<n;i++) { \
- zspan[i] = FixedToDepth(ffz); \
- rgba[i][RCOMP] = FixedToInt(ffr); \
- rgba[i][GCOMP] = FixedToInt(ffg); \
- rgba[i][BCOMP] = FixedToInt(ffb); \
- rgba[i][ACOMP] = FixedToInt(ffa); \
- fogspan[i] = ffog;; \
- ffz += fdzdx; \
- ffr += fdrdx; \
- ffg += fdgdx; \
- ffb += fdbdx; \
- ffa += fdadx; \
- ffog += dfogdx; \
- } \
- _mesa_write_rgba_span( ctx, n, LEFT, Y, \
- (CONST GLdepth *) zspan, \
- fogspan, \
- rgba, GL_POLYGON ); \
- } \
- }
+#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] = 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; \
+ 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, GL_POLYGON);
#include "s_tritemp.h"
@@ -243,44 +224,40 @@ static void simple_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; \
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;i<n;i++) { \
- GLint s = FixedToInt(ffs) & smask; \
- GLint t = FixedToInt(fft) & tmask; \
- GLint pos = (t << twidth_log2) + s; \
- pos = pos + pos + pos; /* multiply by 3 */ \
- rgb[i][RCOMP] = texture[pos]; \
- rgb[i][GCOMP] = texture[pos+1]; \
- rgb[i][BCOMP] = texture[pos+2]; \
- ffs += fdsdx; \
- fft += fdtdx; \
- } \
- (*swrast->Driver.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;i<n;i++) { \
- GLdepth z = FixedToDepth(ffz); \
- if (z < zRow[i]) { \
- GLint s = FixedToInt(ffs) & smask; \
- GLint t = FixedToInt(fft) & tmask; \
- GLint pos = (t << twidth_log2) + s; \
- pos = pos + pos + pos; /* multiply by 3 */ \
- rgb[i][RCOMP] = texture[pos]; \
- rgb[i][GCOMP] = texture[pos+1]; \
- rgb[i][BCOMP] = texture[pos+2]; \
- zRow[i] = z; \
- mask[i] = 1; \
- } \
- else { \
- mask[i] = 0; \
- } \
- ffz += fdzdx; \
- ffs += fdsdx; \
- fft += fdtdx; \
- } \
- (*swrast->Driver.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,181 +431,252 @@ static void affine_textured_triangle( GLcontext *ctx,
#define NEAREST_RGBA_REPLACE *(GLint *)dest = *(GLint *)tex00
-#define SPAN1(DO_TEX,COMP) \
- for (i=0;i<n;i++) { \
- GLint s = FixedToInt(ffs) & smask; \
- GLint t = FixedToInt(fft) & tmask; \
- GLint pos = (t << twidth_log2) + s; \
- const GLchan *tex00 = texture + COMP * pos; \
- zspan[i] = FixedToDepth(ffz); \
- fogspan[i] = ffog;; \
- DO_TEX; \
- ffog += dfogdx; \
- ffz += fdzdx; \
- ffr += fdrdx; \
- ffg += fdgdx; \
- ffb += fdbdx; \
- ffa += fdadx; \
- ffs += fdsdx; \
- fft += fdtdx; \
- dest += 4; \
+#define SPAN1(DO_TEX,COMP) \
+ for (i = 0; i < span->count; 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;i<n;i++) { \
- GLint s = FixedToInt(ffs) & smask; \
- GLint t = FixedToInt(fft) & tmask; \
- GLint sf = ffs & FIXED_FRAC_MASK; \
- GLint tf = fft & FIXED_FRAC_MASK; \
- GLint si = FIXED_FRAC_MASK - sf; \
- GLint ti = FIXED_FRAC_MASK - tf; \
- GLint pos = (t << twidth_log2) + s; \
- const GLchan *tex00 = texture + COMP * pos; \
- const GLchan *tex10 = tex00 + tbytesline; \
- const GLchan *tex01 = tex00 + COMP; \
- const GLchan *tex11 = tex10 + COMP; \
- if (t == tmask) { \
- tex10 -= tsize; \
- tex11 -= tsize; \
- } \
- if (s == smask) { \
- tex01 -= tbytesline; \
- tex11 -= tbytesline; \
- } \
- zspan[i] = FixedToDepth(ffz); \
- fogspan[i] = ffog; \
- DO_TEX; \
- ffog += dfogdx; \
- ffz += fdzdx; \
- ffr += fdrdx; \
- ffg += fdgdx; \
- ffb += fdbdx; \
- ffa += fdadx; \
- ffs += fdsdx; \
- fft += fdtdx; \
- dest += 4; \
+#define SPAN2(DO_TEX,COMP) \
+ for (i = 0; i < span->count; 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
* by interpolated Q/W comes out right.
@@ -681,7 +687,6 @@ static void affine_textured_triangle( GLcontext *ctx,
* This function written by Klaus Niederkrueger <klaus@math.leidenuniv.nl>
* 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<j) { \
- 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; \
dest += 4; \
i++; \
} \
@@ -1395,7 +1401,7 @@ static void near_persp_textured_triangle(GLcontext *ctx,
} \
_mesa_write_rgba_span( ctx, n, LEFT, Y, zspan, \
fogspan, rgba, GL_POLYGON); \
- ffr = ffg = ffb = ffa = 0; \
+ span.red = span.green = span.blue = span.alpha = 0; \
} \
} \
@@ -1413,6 +1419,7 @@ static void near_persp_textured_triangle(GLcontext *ctx,
#endif
+#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
@@ -1421,7 +1428,6 @@ static void near_persp_textured_triangle(GLcontext *ctx,
* This function written by Klaus Niederkrueger <klaus@math.leidenuniv.nl>
* 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;i<n;i++) { \
- GLfloat invQ = 1.0f / vv; \
- GLfixed ffs = (int)(SS * invQ); \
- GLfixed fft = (int)(TT * invQ); \
- GLint s = FixedToInt(ffs) & smask; \
- GLint t = FixedToInt(fft) & tmask; \
- GLint sf = ffs & FIXED_FRAC_MASK; \
- GLint tf = fft & FIXED_FRAC_MASK; \
- GLint si = FIXED_FRAC_MASK - sf; \
- GLint ti = FIXED_FRAC_MASK - tf; \
- GLint pos = COMP * ((t << twidth_log2) + s); \
- GLchan *tex00 = texture + pos; \
- GLchan *tex10 = tex00 + tbytesline; \
- GLchan *tex01 = tex00 + COMP; \
- GLchan *tex11 = tex10 + COMP; \
- if (t == tmask) { \
- tex10 -= tsize; \
- tex11 -= tsize; \
- } \
- if (s == smask) { \
- tex01 -= tbytesline; \
- tex11 -= tbytesline; \
- } \
- zspan[i] = FixedToDepth(ffz); \
- fogspan[i] = ffog; \
- DO_TEX; \
- ffog += dfogdx; \
- ffz += fdzdx; \
- ffr += fdrdx; \
- ffg += fdgdx; \
- ffb += fdbdx; \
- ffa += fdadx; \
- SS += dSdx; \
- TT += dTdx; \
- vv += dvdx; \
- dest += 4; \
+#define SPAN(DO_TEX,COMP) \
+ for (i=0;i<n;i++) { \
+ GLfloat invQ = 1.0f / vv; \
+ GLfixed span.intTex[0] = (int)(SS * invQ); \
+ GLfixed span.intTex[1] = (int)(TT * invQ); \
+ GLint s = FixedToInt(span.intTex[0]) & smask; \
+ GLint t = FixedToInt(span.intTex[1]) & 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 = COMP * ((t << twidth_log2) + s); \
+ GLchan *tex00 = texture + pos; \
+ GLchan *tex10 = tex00 + tbytesline; \
+ GLchan *tex01 = tex00 + COMP; \
+ GLchan *tex11 = tex10 + COMP; \
+ if (t == tmask) { \
+ tex10 -= tsize; \
+ tex11 -= tsize; \
+ } \
+ if (s == smask) { \
+ tex01 -= tbytesline; \
+ tex11 -= 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; \
+ SS += dSdx; \
+ TT += dTdx; \
+ vv += dvdx; \
+ dest += 4; \
}
#define INNER_LOOP( LEFT, RIGHT, Y ) \
@@ -1582,7 +1589,6 @@ static void lin_persp_textured_triangle( GLcontext *ctx,
_mesa_write_rgba_span( ctx, n, LEFT, Y, zspan, \
fogspan, \
rgba, GL_POLYGON ); \
- ffr = ffg = ffb = ffa = 0; \
} \
}
@@ -1593,10 +1599,252 @@ static void lin_persp_textured_triangle( GLcontext *ctx,
/*
+ * 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].
+ */
+static void
+rasterize_span(GLcontext *ctx, const struct triangle_span *span)
+{
+ GLchan rgba[MAX_WIDTH][4];
+ GLchan spec[MAX_WIDTH][4];
+ GLuint index[MAX_WIDTH];
+ GLuint z[MAX_WIDTH];
+ GLfloat fog[MAX_WIDTH];
+ GLfloat sTex[MAX_WIDTH], tTex[MAX_WIDTH], rTex[MAX_WIDTH];
+ GLfloat lambda[MAX_WIDTH];
+ GLfloat msTex[MAX_TEXTURE_UNITS][MAX_WIDTH];
+ GLfloat mtTex[MAX_TEXTURE_UNITS][MAX_WIDTH];
+ GLfloat mrTex[MAX_TEXTURE_UNITS][MAX_WIDTH];
+ GLfloat mLambda[MAX_TEXTURE_UNITS][MAX_WIDTH];
+
+ if (span->activeMask & 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;i<n;i++) { \
- GLdouble invQ = vv ? (1.0 / vv) : 1.0; \
- zspan[i] = FixedToDepth(ffz); \
- fogspan[i] = ffog; \
- rgba[i][RCOMP] = r; \
- rgba[i][GCOMP] = g; \
- rgba[i][BCOMP] = b; \
- rgba[i][ACOMP] = a; \
- s[i] = ss*invQ; \
- t[i] = tt*invQ; \
- u[i] = uu*invQ; \
- ffog += dfogdx; \
- ffz += fdzdx; \
- ss += dsdx; \
- tt += dtdx; \
- uu += dudx; \
- vv += dvdx; \
- } \
- } \
- else { \
- for (i=0;i<n;i++) { \
- GLdouble invQ = vv ? (1.0 / vv) : 1.0; \
- zspan[i] = FixedToDepth(ffz); \
- rgba[i][RCOMP] = FixedToInt(ffr); \
- rgba[i][GCOMP] = FixedToInt(ffg); \
- rgba[i][BCOMP] = FixedToInt(ffb); \
- rgba[i][ACOMP] = FixedToInt(ffa); \
- fogspan[i] = ffog; \
- s[i] = ss*invQ; \
- t[i] = tt*invQ; \
- u[i] = uu*invQ; \
- ffog += dfogdx; \
- ffz += fdzdx; \
- ffr += fdrdx; \
- ffg += fdgdx; \
- ffb += fdbdx; \
- ffa += fdadx; \
- ss += dsdx; \
- tt += dtdx; \
- uu += dudx; \
- vv += dvdx; \
- } \
- } \
- _mesa_write_texture_span( ctx, n, LEFT, Y, zspan, \
- fogspan, s, t, u, NULL, \
- rgba, NULL, GL_POLYGON ); \
- } \
- }
+
+#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; \
+ 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;i<n;i++) { \
- GLdouble invQ = vv ? (1.0 / vv) : 1.0; \
- zspan[i] = FixedToDepth(ffz); \
- fogspan[i] = ffog; \
- rgba[i][RCOMP] = r; \
- rgba[i][GCOMP] = g; \
- rgba[i][BCOMP] = b; \
- rgba[i][ACOMP] = a; \
- spec[i][RCOMP] = sr; \
- spec[i][GCOMP] = sg; \
- spec[i][BCOMP] = sb; \
- s[i] = ss*invQ; \
- t[i] = tt*invQ; \
- u[i] = uu*invQ; \
- ffog += dfogdx; \
- ffz += fdzdx; \
- ss += dsdx; \
- tt += dtdx; \
- uu += dudx; \
- vv += dvdx; \
- } \
- } \
- else { \
- for (i=0;i<n;i++) { \
- GLdouble invQ = vv ? (1.0 / vv) : 1.0; \
- zspan[i] = FixedToDepth(ffz); \
- fogspan[i] = ffog; \
- rgba[i][RCOMP] = FixedToInt(ffr); \
- rgba[i][GCOMP] = FixedToInt(ffg); \
- rgba[i][BCOMP] = FixedToInt(ffb); \
- rgba[i][ACOMP] = FixedToInt(ffa); \
- spec[i][RCOMP] = FixedToInt(ffsr); \
- spec[i][GCOMP] = FixedToInt(ffsg); \
- spec[i][BCOMP] = FixedToInt(ffsb); \
- s[i] = ss*invQ; \
- t[i] = tt*invQ; \
- u[i] = uu*invQ; \
- ffog += dfogdx; \
- ffz += fdzdx; \
- ffr += fdrdx; \
- ffg += fdgdx; \
- ffb += fdbdx; \
- ffa += fdadx; \
- ffsr += fdsrdx; \
- ffsg += fdsgdx; \
- ffsb += fdsbdx; \
- ss += dsdx; \
- tt += dtdx; \
- uu += dudx; \
- vv += dvdx; \
- } \
- } \
- _mesa_write_texture_span( ctx, n, LEFT, Y, zspan, \
- fogspan, \
- s, t, u, NULL, rgba, \
- (CONST GLchan (*)[4]) spec, \
- GL_POLYGON ); \
- } \
- }
+
+#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 = 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;i<n;i++) { \
- GLdouble invQ = vv ? (1.0 / vv) : 1.0; \
- zspan[i] = FixedToDepth(ffz); \
- fogspan[i] = ffog; \
- rgba[i][RCOMP] = r; \
- rgba[i][GCOMP] = g; \
- rgba[i][BCOMP] = b; \
- rgba[i][ACOMP] = a; \
- s[i] = ss*invQ; \
- t[i] = tt*invQ; \
- u[i] = uu*invQ; \
- COMPUTE_LAMBDA(lambda[i], invQ); \
- ffz += fdzdx; \
- ffog += dfogdx; \
- ss += dsdx; \
- tt += dtdx; \
- uu += dudx; \
- vv += dvdx; \
- } \
- } \
- else { \
- for (i=0;i<n;i++) { \
- GLdouble invQ = vv ? (1.0 / vv) : 1.0; \
- zspan[i] = FixedToDepth(ffz); \
- fogspan[i] = ffog; \
- rgba[i][RCOMP] = FixedToInt(ffr); \
- rgba[i][GCOMP] = FixedToInt(ffg); \
- rgba[i][BCOMP] = FixedToInt(ffb); \
- rgba[i][ACOMP] = FixedToInt(ffa); \
- s[i] = ss*invQ; \
- t[i] = tt*invQ; \
- u[i] = uu*invQ; \
- COMPUTE_LAMBDA(lambda[i], invQ); \
- ffz += fdzdx; \
- ffog += dfogdx; \
- ffr += fdrdx; \
- ffg += fdgdx; \
- ffb += fdbdx; \
- ffa += fdadx; \
- ss += dsdx; \
- tt += dtdx; \
- uu += dudx; \
- vv += dvdx; \
- } \
- } \
- _mesa_write_texture_span( ctx, n, LEFT, Y, zspan, fogspan, \
- s, t, u, lambda, \
- rgba, NULL, GL_POLYGON ); \
- } \
- }
+ 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"
}
@@ -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;i<n;i++) { \
- GLdouble invQ = vv ? (1.0 / vv) : 1.0; \
- zspan[i] = FixedToDepth(ffz); \
- fogspan[i] = ffog; \
- rgba[i][RCOMP] = r; \
- rgba[i][GCOMP] = g; \
- rgba[i][BCOMP] = b; \
- rgba[i][ACOMP] = a; \
- spec[i][RCOMP] = sr; \
- spec[i][GCOMP] = sg; \
- spec[i][BCOMP] = sb; \
- s[i] = ss*invQ; \
- t[i] = tt*invQ; \
- u[i] = uu*invQ; \
- COMPUTE_LAMBDA(lambda[i], invQ); \
- ffog += dfogdx; \
- ffz += fdzdx; \
- ss += dsdx; \
- tt += dtdx; \
- uu += dudx; \
- vv += dvdx; \
- } \
- } \
- else { \
- for (i=0;i<n;i++) { \
- GLdouble invQ = vv ? (1.0 / vv) : 1.0; \
- zspan[i] = FixedToDepth(ffz); \
- fogspan[i] = ffog; \
- rgba[i][RCOMP] = FixedToInt(ffr); \
- rgba[i][GCOMP] = FixedToInt(ffg); \
- rgba[i][BCOMP] = FixedToInt(ffb); \
- rgba[i][ACOMP] = FixedToInt(ffa); \
- spec[i][RCOMP] = FixedToInt(ffsr); \
- spec[i][GCOMP] = FixedToInt(ffsg); \
- spec[i][BCOMP] = FixedToInt(ffsb); \
- s[i] = ss*invQ; \
- t[i] = tt*invQ; \
- u[i] = uu*invQ; \
- COMPUTE_LAMBDA(lambda[i], invQ); \
- ffog += dfogdx; \
- ffz += fdzdx; \
- ffr += fdrdx; \
- ffg += fdgdx; \
- ffb += fdbdx; \
- ffa += fdadx; \
- ffsr += fdsrdx; \
- ffsg += fdsgdx; \
- ffsb += fdsbdx; \
- ss += dsdx; \
- tt += dtdx; \
- uu += dudx; \
- vv += dvdx; \
- } \
- } \
- _mesa_write_texture_span( ctx, n, LEFT, Y, zspan, \
- fogspan, s, t, u, lambda, \
- rgba, (CONST GLchan (*)[4]) spec, \
- GL_POLYGON ); \
- } \
- }
+ 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"
}
@@ -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;i<n;i++) { \
- GLuint unit; \
- zspan[i] = FixedToDepth(ffz); \
- fogspan[i] = ffog; \
- ffog += dfogdx; \
- ffz += fdzdx; \
- rgba[i][RCOMP] = r; \
- rgba[i][GCOMP] = g; \
- rgba[i][BCOMP] = b; \
- rgba[i][ACOMP] = a; \
- for (unit=0; unit < ctx->Const.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;i<n;i++) { \
- GLuint unit; \
- zspan[i] = FixedToDepth(ffz); \
- fogspan[i] = ffog; \
- ffz += fdzdx; \
- ffog += dfogdx; \
- rgba[i][RCOMP] = FixedToInt(ffr); \
- rgba[i][GCOMP] = FixedToInt(ffg); \
- rgba[i][BCOMP] = FixedToInt(ffb); \
- rgba[i][ACOMP] = FixedToInt(ffa); \
- ffr += fdrdx; \
- ffg += fdgdx; \
- ffb += fdbdx; \
- ffa += fdadx; \
- for (unit=0; unit < ctx->Const.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;i<len;i++) { \
- GLdepth z = FixedToDepth(ffz); \
- if (z < zRow[i]) { \
- ctx->OcclusionResult = 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<RIGHT;x++) {
- * put_pixel(x,Y);
- * // increment fixed point interpolants
- * }
+ * RENDER_SPAN(span) - code to write a span of pixels.
*
* This code was designed for the origin to be in the lower-left corner.
*
* Inspired by triangle rasterizer code written by Allen Akin. Thanks Allen!
*/
-
/*void triangle( GLcontext *ctx, SWvertex *v0, SWvertex *v1, SWvertex *v2 )*/
{
typedef struct {
@@ -104,6 +95,12 @@
float bf = SWRAST_CONTEXT(ctx)->_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