-/* $Id: s_triangle.c,v 1.39 2001/09/19 22:21:13 brianp Exp $ */
-
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 6.5.3
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
#include "glheader.h"
#include "context.h"
#include "colormac.h"
+#include "imports.h"
#include "macros.h"
-#include "mem.h"
-#include "mmath.h"
#include "texformat.h"
-#include "teximage.h"
-#include "texstate.h"
#include "s_aatriangle.h"
#include "s_context.h"
-#include "s_depth.h"
#include "s_feedback.h"
#include "s_span.h"
#include "s_triangle.h"
-#include "s_trispan.h"
-
-GLboolean _mesa_cull_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
+/*
+ * Just used for feedback mode.
+ */
+GLboolean
+_swrast_culltriangle( GLcontext *ctx,
+ const SWvertex *v0,
+ const SWvertex *v1,
+ const SWvertex *v2 )
{
GLfloat ex = v1->win[0] - v0->win[0];
GLfloat ey = v1->win[1] - v0->win[1];
GLfloat fy = v2->win[1] - v0->win[1];
GLfloat c = ex*fy-ey*fx;
- if (c * SWRAST_CONTEXT(ctx)->_backface_sign > 0)
+ if (c * SWRAST_CONTEXT(ctx)->_BackfaceSign > 0)
return 0;
return 1;
/*
- * Render a flat-shaded color index triangle.
- */
-static void flat_ci_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
-{
-#define INTERP_Z 1
-#define INTERP_FOG 1
-
-#define RENDER_SPAN( span ) \
- GLdepth zSpan[MAX_WIDTH]; \
- GLfloat fogSpan[MAX_WIDTH]; \
- GLuint i; \
- for (i = 0; i < span.count; i++) { \
- zSpan[i] = FixedToDepth(span.z); \
- span.z += span.zStep; \
- fogSpan[i] = span.fog; \
- span.fog += span.fogStep; \
- } \
- _mesa_write_monoindex_span(ctx, span.count, span.x, span.y, \
- zSpan, fogSpan, v0->index, NULL, GL_POLYGON );
-
-#include "s_tritemp.h"
-}
-
-
-
-/*
- * Render a smooth-shaded color index triangle.
+ * Render a smooth or flat-shaded color index triangle.
*/
-static void smooth_ci_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
-{
+#define NAME ci_triangle
#define INTERP_Z 1
#define INTERP_FOG 1
#define INTERP_INDEX 1
-
-#define RENDER_SPAN( span ) \
- GLdepth zSpan[MAX_WIDTH]; \
- GLfloat fogSpan[MAX_WIDTH]; \
- GLuint indexSpan[MAX_WIDTH]; \
- GLuint i; \
- for (i = 0; i < span.count; i++) { \
- zSpan[i] = FixedToDepth(span.z); \
- span.z += span.zStep; \
- indexSpan[i] = FixedToInt(span.index); \
- span.index += span.indexStep; \
- fogSpan[i] = span.fog; \
- span.fog += span.fogStep; \
- } \
- _mesa_write_index_span(ctx, span.count, span.x, span.y, \
- zSpan, fogSpan, indexSpan, NULL, GL_POLYGON);
-
+#define RENDER_SPAN( span ) _swrast_write_index_span(ctx, &span);
#include "s_tritemp.h"
-}
/*
* Render a flat-shaded RGBA triangle.
*/
-static void flat_rgba_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
-{
+#define NAME flat_rgba_triangle
#define INTERP_Z 1
#define INTERP_FOG 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-
-#define RENDER_SPAN( span ) \
- GLdepth zSpan[MAX_WIDTH]; \
- GLfloat fogSpan[MAX_WIDTH]; \
- GLuint i; \
- for (i = 0; i < span.count; i++) { \
- zSpan[i] = FixedToDepth(span.z); \
- span.z += span.zStep; \
- fogSpan[i] = span.fog; \
- span.fog += span.fogStep; \
- } \
- _mesa_write_monocolor_span(ctx, span.count, span.x, span.y, zSpan, \
- fogSpan, v2->color, NULL, GL_POLYGON );
-
+#define SETUP_CODE \
+ ASSERT(ctx->Texture._EnabledCoordUnits == 0);\
+ ASSERT(ctx->Light.ShadeModel==GL_FLAT); \
+ span.interpMask |= SPAN_RGBA; \
+ span.red = ChanToFixed(v2->color[0]); \
+ span.green = ChanToFixed(v2->color[1]); \
+ span.blue = ChanToFixed(v2->color[2]); \
+ span.alpha = ChanToFixed(v2->color[3]); \
+ span.redStep = 0; \
+ span.greenStep = 0; \
+ span.blueStep = 0; \
+ span.alphaStep = 0;
+#define RENDER_SPAN( span ) _swrast_write_rgba_span(ctx, &span);
#include "s_tritemp.h"
- ASSERT(!ctx->Texture._ReallyEnabled); /* texturing must be off */
- ASSERT(ctx->Light.ShadeModel==GL_FLAT);
-}
-
/*
* Render a smooth-shaded RGBA triangle.
*/
-static void smooth_rgba_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
-{
-
+#define NAME smooth_rgba_triangle
#define INTERP_Z 1
#define INTERP_FOG 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
#define INTERP_RGB 1
#define INTERP_ALPHA 1
-
-#define RENDER_SPAN( span ) \
- GLdepth zSpan[MAX_WIDTH]; \
- GLchan rgbaSpan[MAX_WIDTH][4]; \
- GLfloat fogSpan[MAX_WIDTH]; \
- GLuint i; \
- for (i = 0; i < span.count; i++) { \
- rgbaSpan[i][RCOMP] = FixedToChan(span.red); \
- rgbaSpan[i][GCOMP] = FixedToChan(span.green); \
- rgbaSpan[i][BCOMP] = FixedToChan(span.blue); \
- rgbaSpan[i][ACOMP] = FixedToChan(span.alpha); \
- span.red += span.redStep; \
- span.green += span.greenStep; \
- span.blue += span.blueStep; \
- span.alpha += span.alphaStep; \
- zSpan[i] = FixedToDepth(span.z); \
- span.z += span.zStep; \
- fogSpan[i] = span.fog; \
- span.fog += span.fogStep; \
- } \
- _mesa_write_rgba_span(ctx, span.count, span.x, span.y, \
- (CONST GLdepth *) zSpan, \
- fogSpan, rgbaSpan, NULL, GL_POLYGON);
-
+#define SETUP_CODE \
+ { \
+ /* texturing must be off */ \
+ ASSERT(ctx->Texture._EnabledCoordUnits == 0); \
+ ASSERT(ctx->Light.ShadeModel==GL_SMOOTH); \
+ }
+#define RENDER_SPAN( span ) _swrast_write_rgba_span(ctx, &span);
#include "s_tritemp.h"
- ASSERT(!ctx->Texture._ReallyEnabled); /* texturing must be off */
- ASSERT(ctx->Light.ShadeModel==GL_SMOOTH);
-}
/*
* Render an RGB, GL_DECAL, textured triangle.
* Interpolate S,T only w/out mipmapping or perspective correction.
*
- * No fog.
+ * No fog. No depth testing.
*/
-static void simple_textured_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
-{
+#define NAME simple_textured_triangle
#define INTERP_INT_TEX 1
#define S_SCALE twidth
#define T_SCALE theight
#define SETUP_CODE \
- SWcontext *swrast = SWRAST_CONTEXT(ctx); \
+ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];\
struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; \
- GLint b = obj->BaseLevel; \
- const GLfloat twidth = (GLfloat) obj->Image[b]->Width; \
- const GLfloat theight = (GLfloat) obj->Image[b]->Height; \
- const GLint twidth_log2 = obj->Image[b]->WidthLog2; \
- const GLchan *texture = (const GLchan *) obj->Image[b]->Data; \
- const GLint smask = obj->Image[b]->Width - 1; \
- const GLint tmask = obj->Image[b]->Height - 1; \
+ const GLint b = obj->BaseLevel; \
+ const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width; \
+ const GLfloat theight = (GLfloat) obj->Image[0][b]->Height; \
+ const GLint twidth_log2 = obj->Image[0][b]->WidthLog2; \
+ const GLchan *texture = (const GLchan *) obj->Image[0][b]->Data; \
+ const GLint smask = obj->Image[0][b]->Width - 1; \
+ const GLint tmask = obj->Image[0][b]->Height - 1; \
if (!texture) { \
/* this shouldn't happen */ \
return; \
}
-#define RENDER_SPAN( span ) \
- GLchan rgbSpan[MAX_WIDTH][3]; \
+#define RENDER_SPAN( span ) \
GLuint i; \
+ GLchan rgb[MAX_WIDTH][3]; \
span.intTex[0] -= FIXED_HALF; /* off-by-one error? */ \
span.intTex[1] -= FIXED_HALF; \
- for (i = 0; i < span.count; i++) { \
+ for (i = 0; i < span.end; i++) { \
GLint s = FixedToInt(span.intTex[0]) & smask; \
GLint t = FixedToInt(span.intTex[1]) & tmask; \
GLint pos = (t << twidth_log2) + s; \
pos = pos + pos + pos; /* multiply by 3 */ \
- rgbSpan[i][RCOMP] = texture[pos]; \
- rgbSpan[i][GCOMP] = texture[pos+1]; \
- rgbSpan[i][BCOMP] = texture[pos+2]; \
+ rgb[i][RCOMP] = texture[pos]; \
+ rgb[i][GCOMP] = texture[pos+1]; \
+ rgb[i][BCOMP] = texture[pos+2]; \
span.intTex[0] += span.intTexStep[0]; \
span.intTex[1] += span.intTexStep[1]; \
} \
- (*swrast->Driver.WriteRGBSpan)(ctx, span.count, span.x, span.y, \
- (CONST GLchan (*)[3]) rgbSpan, NULL );
+ rb->PutRowRGB(ctx, rb, span.end, span.x, span.y, rgb, NULL);
#include "s_tritemp.h"
-}
+
/*
* Render an RGB, GL_DECAL, textured triangle.
* Interpolate S,T, GL_LESS depth test, w/out mipmapping or
* perspective correction.
+ * Depth buffer bits must be <= sizeof(DEFAULT_SOFTWARE_DEPTH_TYPE)
*
* No fog.
*/
-static void simple_z_textured_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
-{
+#define NAME simple_z_textured_triangle
#define INTERP_Z 1
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
#define INTERP_INT_TEX 1
#define T_SCALE theight
#define SETUP_CODE \
- SWcontext *swrast = SWRAST_CONTEXT(ctx); \
+ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];\
struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; \
- GLint b = obj->BaseLevel; \
- GLfloat twidth = (GLfloat) obj->Image[b]->Width; \
- GLfloat theight = (GLfloat) obj->Image[b]->Height; \
- GLint twidth_log2 = obj->Image[b]->WidthLog2; \
- const GLchan *texture = (const GLchan *) obj->Image[b]->Data; \
- GLint smask = obj->Image[b]->Width - 1; \
- GLint tmask = obj->Image[b]->Height - 1; \
+ const GLint b = obj->BaseLevel; \
+ const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width; \
+ const GLfloat theight = (GLfloat) obj->Image[0][b]->Height; \
+ const GLint twidth_log2 = obj->Image[0][b]->WidthLog2; \
+ const GLchan *texture = (const GLchan *) obj->Image[0][b]->Data; \
+ const GLint smask = obj->Image[0][b]->Width - 1; \
+ const GLint tmask = obj->Image[0][b]->Height - 1; \
if (!texture) { \
/* this shouldn't happen */ \
return; \
}
#define RENDER_SPAN( span ) \
- GLchan rgbSpan[MAX_WIDTH][3]; \
- GLubyte mask[MAX_WIDTH]; \
GLuint i; \
+ GLchan rgb[MAX_WIDTH][3]; \
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); \
+ for (i = 0; i < span.end; i++) { \
+ const GLuint 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]; \
+ rgb[i][RCOMP] = texture[pos]; \
+ rgb[i][GCOMP] = texture[pos+1]; \
+ rgb[i][BCOMP] = texture[pos+2]; \
zRow[i] = z; \
- mask[i] = 1; \
+ span.array->mask[i] = 1; \
} \
else { \
- mask[i] = 0; \
+ span.array->mask[i] = 0; \
} \
span.intTex[0] += span.intTexStep[0]; \
span.intTex[1] += span.intTexStep[1]; \
span.z += span.zStep; \
} \
- (*swrast->Driver.WriteRGBSpan)(ctx, span.count, span.x, span.y, \
- (CONST GLchan (*)[3]) rgbSpan, mask );
+ rb->PutRowRGB(ctx, rb, span.end, span.x, span.y, rgb, span.array->mask);
#include "s_tritemp.h"
-}
+
#if CHAN_TYPE != GL_FLOAT
GLint smask, tmask;
GLint twidth_log2;
const GLchan *texture;
- GLchan er, eg, eb, ea;
+ GLfixed er, eg, eb, ea;
GLint tbytesline, tsize;
- GLint fixedToDepthShift;
};
+static INLINE GLint
+ilerp(GLint t, GLint a, GLint b)
+{
+ return a + ((t * (b - a)) >> FIXED_SHIFT);
+}
+
+static INLINE GLint
+ilerp_2d(GLint ia, GLint ib, GLint v00, GLint v10, GLint v01, GLint v11)
+{
+ const GLint temp0 = ilerp(ia, v00, v10);
+ const GLint temp1 = ilerp(ia, v01, v11);
+ return ilerp(ib, temp0, temp1);
+}
+
+
/* This function can handle GL_NEAREST or GL_LINEAR sampling of 2D RGB or RGBA
* textures with GL_REPLACE, GL_MODULATE, GL_BLEND, GL_DECAL or GL_ADD
* texture env modes.
*/
-static void
-affine_span(GLcontext *ctx, struct triangle_span *span,
+static INLINE void
+affine_span(GLcontext *ctx, SWspan *span,
struct affine_info *info)
{
GLchan sample[4]; /* the filtered texture sample */
sample[ACOMP] = CHAN_MAX
#define LINEAR_RGB \
- sample[RCOMP] = (ti * (si * tex00[0] + sf * tex01[0]) + \
- tf * (si * tex10[0] + sf * tex11[0])) >> 2 * FIXED_SHIFT; \
- sample[GCOMP] = (ti * (si * tex00[1] + sf * tex01[1]) + \
- tf * (si * tex10[1] + sf * tex11[1])) >> 2 * FIXED_SHIFT; \
- sample[BCOMP] = (ti * (si * tex00[2] + sf * tex01[2]) + \
- tf * (si * tex10[2] + sf * tex11[2])) >> 2 * FIXED_SHIFT; \
- sample[ACOMP] = CHAN_MAX
+ sample[RCOMP] = ilerp_2d(sf, tf, tex00[0], tex01[0], tex10[0], tex11[0]);\
+ sample[GCOMP] = ilerp_2d(sf, tf, tex00[1], tex01[1], tex10[1], tex11[1]);\
+ sample[BCOMP] = ilerp_2d(sf, tf, tex00[2], tex01[2], tex10[2], tex11[2]);\
+ sample[ACOMP] = CHAN_MAX;
#define NEAREST_RGBA COPY_CHAN4(sample, tex00)
#define LINEAR_RGBA \
- sample[RCOMP] = (ti * (si * tex00[0] + sf * tex01[0]) + \
- tf * (si * tex10[0] + sf * tex11[0])) >> 2 * FIXED_SHIFT;\
- sample[GCOMP] = (ti * (si * tex00[1] + sf * tex01[1]) + \
- tf * (si * tex10[1] + sf * tex11[1])) >> 2 * FIXED_SHIFT;\
- sample[BCOMP] = (ti * (si * tex00[2] + sf * tex01[2]) + \
- tf * (si * tex10[2] + sf * tex11[2])) >> 2 * FIXED_SHIFT;\
- sample[ACOMP] = (ti * (si * tex00[3] + sf * tex01[3]) + \
- tf * (si * tex10[3] + sf * tex11[3])) >> 2 * FIXED_SHIFT
-
-#define MODULATE \
+ sample[RCOMP] = ilerp_2d(sf, tf, tex00[0], tex01[0], tex10[0], tex11[0]);\
+ sample[GCOMP] = ilerp_2d(sf, tf, tex00[1], tex01[1], tex10[1], tex11[1]);\
+ sample[BCOMP] = ilerp_2d(sf, tf, tex00[2], tex01[2], tex10[2], tex11[2]);\
+ sample[ACOMP] = ilerp_2d(sf, tf, tex00[3], tex01[3], tex10[3], tex11[3])
+
+#define MODULATE \
dest[RCOMP] = span->red * (sample[RCOMP] + 1u) >> (FIXED_SHIFT + 8); \
dest[GCOMP] = span->green * (sample[GCOMP] + 1u) >> (FIXED_SHIFT + 8); \
dest[BCOMP] = span->blue * (sample[BCOMP] + 1u) >> (FIXED_SHIFT + 8); \
/* shortcuts */
-#define NEAREST_RGB_REPLACE NEAREST_RGB;REPLACE
+#define NEAREST_RGB_REPLACE \
+ NEAREST_RGB; \
+ dest[0] = sample[0]; \
+ dest[1] = sample[1]; \
+ dest[2] = sample[2]; \
+ dest[3] = FixedToInt(span->alpha);
#define NEAREST_RGBA_REPLACE COPY_CHAN4(dest, tex00)
-#define SPAN_NEAREST(DO_TEX,COMP) \
- for (i = 0; i < span->count; i++) { \
+#define SPAN_NEAREST(DO_TEX, COMPS) \
+ for (i = 0; i < span->end; i++) { \
/* Isn't it necessary to use FixedFloor below?? */ \
GLint s = FixedToInt(span->intTex[0]) & info->smask; \
GLint t = FixedToInt(span->intTex[1]) & info->tmask; \
GLint pos = (t << info->twidth_log2) + s; \
- const GLchan *tex00 = info->texture + COMP * pos; \
- zspan[i] = FixedToDepth(span->z); \
- fogspan[i] = span->fog; \
+ const GLchan *tex00 = info->texture + COMPS * pos; \
DO_TEX; \
- span->fog += span->fogStep; \
- span->z += span->zStep; \
span->red += span->redStep; \
span->green += span->greenStep; \
span->blue += span->blueStep; \
dest += 4; \
}
-#define SPAN_LINEAR(DO_TEX,COMP) \
- for (i = 0; i < span->count; i++) { \
+#define SPAN_LINEAR(DO_TEX, COMPS) \
+ for (i = 0; i < span->end; i++) { \
/* Isn't it necessary to use FixedFloor below?? */ \
- GLint s = FixedToInt(span->intTex[0]) & info->smask; \
- GLint t = FixedToInt(span->intTex[1]) & info->tmask; \
- GLfixed sf = span->intTex[0] & FIXED_FRAC_MASK; \
- GLfixed tf = span->intTex[1] & FIXED_FRAC_MASK; \
- GLfixed si = FIXED_FRAC_MASK - sf; \
- GLfixed ti = FIXED_FRAC_MASK - tf; \
- GLint pos = (t << info->twidth_log2) + s; \
- const GLchan *tex00 = info->texture + COMP * pos; \
+ const GLint s = FixedToInt(span->intTex[0]) & info->smask; \
+ const GLint t = FixedToInt(span->intTex[1]) & info->tmask; \
+ const GLfixed sf = span->intTex[0] & FIXED_FRAC_MASK; \
+ const GLfixed tf = span->intTex[1] & FIXED_FRAC_MASK; \
+ const GLint pos = (t << info->twidth_log2) + s; \
+ const GLchan *tex00 = info->texture + COMPS * pos; \
const GLchan *tex10 = tex00 + info->tbytesline; \
- const GLchan *tex01 = tex00 + COMP; \
- const GLchan *tex11 = tex10 + COMP; \
- (void) ti; \
- (void) si; \
+ const GLchan *tex01 = tex00 + COMPS; \
+ const GLchan *tex11 = tex10 + COMPS; \
if (t == info->tmask) { \
tex10 -= info->tsize; \
tex11 -= info->tsize; \
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; \
dest += 4; \
}
-#define FixedToDepth(F) ((F) >> fixedToDepthShift)
GLuint i;
- GLdepth zspan[MAX_WIDTH];
- GLfloat fogspan[MAX_WIDTH];
- GLchan rgba[MAX_WIDTH][4];
- GLchan *dest = rgba[0];
- const GLint fixedToDepthShift = info->fixedToDepthShift;
+ GLchan *dest = span->array->rgba[0];
span->intTex[0] -= FIXED_HALF;
span->intTex[1] -= FIXED_HALF;
SPAN_NEAREST(NEAREST_RGB;ADD,3);
break;
default:
- abort();
+ _mesa_problem(ctx, "bad tex env mode in SPAN_LINEAR");
+ return;
}
break;
case GL_RGBA:
SPAN_NEAREST(NEAREST_RGBA_REPLACE,4);
break;
default:
- abort();
+ _mesa_problem(ctx, "bad tex env mode (2) in SPAN_LINEAR");
+ return;
}
break;
}
SPAN_LINEAR(LINEAR_RGB;ADD,3);
break;
default:
- abort();
+ _mesa_problem(ctx, "bad tex env mode (3) in SPAN_LINEAR");
+ return;
}
break;
case GL_RGBA:
SPAN_LINEAR(LINEAR_RGBA;REPLACE,4);
break;
default:
- abort();
- } break;
+ _mesa_problem(ctx, "bad tex env mode (4) in SPAN_LINEAR");
+ return;
+ }
+ break;
}
break;
}
- _mesa_write_rgba_span(ctx, span->count, span->x, span->y,
- zspan, fogspan, rgba, NULL, GL_POLYGON);
+ span->interpMask &= ~SPAN_RGBA;
+ ASSERT(span->arrayMask & SPAN_RGBA);
+ _swrast_write_rgba_span(ctx, span);
#undef SPAN_NEAREST
#undef SPAN_LINEAR
-#undef FixedToDepth
}
/*
* Render an RGB/RGBA textured triangle without perspective correction.
*/
-static void affine_textured_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
-{
+#define NAME affine_textured_triangle
#define INTERP_Z 1
#define INTERP_FOG 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define INTERP_INT_TEX 1
struct affine_info info; \
struct gl_texture_unit *unit = ctx->Texture.Unit+0; \
struct gl_texture_object *obj = unit->Current2D; \
- GLint b = obj->BaseLevel; \
- GLfloat twidth = (GLfloat) obj->Image[b]->Width; \
- GLfloat theight = (GLfloat) obj->Image[b]->Height; \
- info.fixedToDepthShift = ctx->Visual.depthBits <= 16 ? FIXED_SHIFT : 0;\
- info.texture = (const GLchan *) obj->Image[b]->Data; \
- info.twidth_log2 = obj->Image[b]->WidthLog2; \
- info.smask = obj->Image[b]->Width - 1; \
- info.tmask = obj->Image[b]->Height - 1; \
- info.format = obj->Image[b]->Format; \
+ const GLint b = obj->BaseLevel; \
+ const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width; \
+ const GLfloat theight = (GLfloat) obj->Image[0][b]->Height; \
+ info.texture = (const GLchan *) obj->Image[0][b]->Data; \
+ info.twidth_log2 = obj->Image[0][b]->WidthLog2; \
+ info.smask = obj->Image[0][b]->Width - 1; \
+ info.tmask = obj->Image[0][b]->Height - 1; \
+ info.format = obj->Image[0][b]->_BaseFormat; \
info.filter = obj->MinFilter; \
info.envmode = unit->EnvMode; \
+ span.arrayMask |= SPAN_RGBA; \
\
if (info.envmode == GL_BLEND) { \
/* potential off-by-one error here? (1.0f -> 2048 -> 0) */ \
- info.er = FloatToFixed(unit->EnvColor[RCOMP]); \
- info.eg = FloatToFixed(unit->EnvColor[GCOMP]); \
- info.eb = FloatToFixed(unit->EnvColor[BCOMP]); \
- info.ea = FloatToFixed(unit->EnvColor[ACOMP]); \
+ info.er = FloatToFixed(unit->EnvColor[RCOMP] * CHAN_MAXF); \
+ info.eg = FloatToFixed(unit->EnvColor[GCOMP] * CHAN_MAXF); \
+ info.eb = FloatToFixed(unit->EnvColor[BCOMP] * CHAN_MAXF); \
+ info.ea = FloatToFixed(unit->EnvColor[ACOMP] * CHAN_MAXF); \
} \
if (!info.texture) { \
/* this shouldn't happen */ \
case GL_ALPHA: \
case GL_LUMINANCE: \
case GL_INTENSITY: \
- info.tbytesline = obj->Image[b]->Width; \
+ info.tbytesline = obj->Image[0][b]->Width; \
break; \
case GL_LUMINANCE_ALPHA: \
- info.tbytesline = obj->Image[b]->Width * 2; \
+ info.tbytesline = obj->Image[0][b]->Width * 2; \
break; \
case GL_RGB: \
- info.tbytesline = obj->Image[b]->Width * 3; \
+ info.tbytesline = obj->Image[0][b]->Width * 3; \
break; \
case GL_RGBA: \
- info.tbytesline = obj->Image[b]->Width * 4; \
+ info.tbytesline = obj->Image[0][b]->Width * 4; \
break; \
default: \
_mesa_problem(NULL, "Bad texture format in affine_texture_triangle");\
return; \
} \
- info.tsize = obj->Image[b]->Height * info.tbytesline;
+ info.tsize = obj->Image[0][b]->Height * info.tbytesline;
#define RENDER_SPAN( span ) affine_span(ctx, &span, &info);
#include "s_tritemp.h"
-}
-
struct persp_info
GLint smask, tmask;
GLint twidth_log2;
const GLchan *texture;
- GLchan er, eg, eb, ea; /* texture env color */
+ GLfixed er, eg, eb, ea; /* texture env color */
GLint tbytesline, tsize;
- GLint fixedToDepthShift;
};
-static void
-fast_persp_span(GLcontext *ctx, struct triangle_span *span,
+static INLINE void
+fast_persp_span(GLcontext *ctx, SWspan *span,
struct persp_info *info)
{
GLchan sample[4]; /* the filtered texture sample */
* unused variables (for instance tf,sf,ti,si in case of GL_NEAREST).
*/
#define SPAN_NEAREST(DO_TEX,COMP) \
- for (i = 0; i < span->count; i++) { \
+ for (i = 0; i < span->end; i++) { \
GLdouble invQ = tex_coord[2] ? \
(1.0 / tex_coord[2]) : 1.0; \
GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); \
GLint t = IFLOOR(t_tmp) & info->tmask; \
GLint pos = (t << info->twidth_log2) + s; \
const GLchan *tex00 = info->texture + COMP * pos; \
- zspan[i] = FixedToDepth(span->z); \
- fogspan[i] = span->fog; \
DO_TEX; \
- span->fog += span->fogStep; \
- span->z += span->zStep; \
span->red += span->redStep; \
span->green += span->greenStep; \
span->blue += span->blueStep; \
}
#define SPAN_LINEAR(DO_TEX,COMP) \
- for (i = 0; i < span->count; i++) { \
+ for (i = 0; i < span->end; i++) { \
GLdouble invQ = tex_coord[2] ? \
(1.0 / tex_coord[2]) : 1.0; \
- GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); \
- GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); \
- GLfixed s_fix = FloatToFixed(s_tmp) - FIXED_HALF; \
- GLfixed t_fix = FloatToFixed(t_tmp) - FIXED_HALF; \
- GLint s = FixedToInt(FixedFloor(s_fix)) & info->smask; \
- GLint t = FixedToInt(FixedFloor(t_fix)) & info->tmask; \
- GLfixed sf = s_fix & FIXED_FRAC_MASK; \
- GLfixed tf = t_fix & FIXED_FRAC_MASK; \
- GLfixed si = FIXED_FRAC_MASK - sf; \
- GLfixed ti = FIXED_FRAC_MASK - tf; \
- GLint pos = (t << info->twidth_log2) + s; \
+ const GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); \
+ const GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); \
+ const GLfixed s_fix = FloatToFixed(s_tmp) - FIXED_HALF; \
+ const GLfixed t_fix = FloatToFixed(t_tmp) - FIXED_HALF; \
+ const GLint s = FixedToInt(FixedFloor(s_fix)) & info->smask; \
+ const GLint t = FixedToInt(FixedFloor(t_fix)) & info->tmask; \
+ const GLfixed sf = s_fix & FIXED_FRAC_MASK; \
+ const GLfixed tf = t_fix & FIXED_FRAC_MASK; \
+ const 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; \
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; \
dest += 4; \
}
-#define FixedToDepth(F) ((F) >> fixedToDepthShift)
-
GLuint i;
- GLdepth zspan[MAX_WIDTH];
GLfloat tex_coord[3], tex_step[3];
- GLfloat fogspan[MAX_WIDTH];
- GLchan rgba[MAX_WIDTH][4];
- GLchan *dest = rgba[0];
- const GLint fixedToDepthShift = info->fixedToDepthShift;
-
- tex_coord[0] = span->tex[0][0] * (info->smask + 1),
- tex_step[0] = span->texStep[0][0] * (info->smask + 1);
- tex_coord[1] = span->tex[0][1] * (info->tmask + 1),
- tex_step[1] = span->texStep[0][1] * (info->tmask + 1);
- /* span->tex[0][2] only if 3D-texturing, here only 2D */
- tex_coord[2] = span->tex[0][3],
- tex_step[2] = span->texStep[0][3];
+ GLchan *dest = span->array->rgba[0];
+
+ const GLuint savedTexEnable = ctx->Texture._EnabledUnits;
+ ctx->Texture._EnabledUnits = 0;
+
+ tex_coord[0] = span->attrStart[FRAG_ATTRIB_TEX0][0] * (info->smask + 1);
+ tex_step[0] = span->attrStepX[FRAG_ATTRIB_TEX0][0] * (info->smask + 1);
+ tex_coord[1] = span->attrStart[FRAG_ATTRIB_TEX0][1] * (info->tmask + 1);
+ tex_step[1] = span->attrStepX[FRAG_ATTRIB_TEX0][1] * (info->tmask + 1);
+ /* span->attrStart[FRAG_ATTRIB_TEX0][2] only if 3D-texturing, here only 2D */
+ tex_coord[2] = span->attrStart[FRAG_ATTRIB_TEX0][3];
+ tex_step[2] = span->attrStepX[FRAG_ATTRIB_TEX0][3];
switch (info->filter) {
case GL_NEAREST:
SPAN_NEAREST(NEAREST_RGB;ADD,3);
break;
default:
- abort();
+ _mesa_problem(ctx, "bad tex env mode (5) in SPAN_LINEAR");
+ return;
}
break;
case GL_RGBA:
SPAN_NEAREST(NEAREST_RGBA_REPLACE,4);
break;
default:
- abort();
+ _mesa_problem(ctx, "bad tex env mode (6) in SPAN_LINEAR");
+ return;
}
break;
}
SPAN_LINEAR(LINEAR_RGB;ADD,3);
break;
default:
- abort();
+ _mesa_problem(ctx, "bad tex env mode (7) in SPAN_LINEAR");
+ return;
}
break;
case GL_RGBA:
SPAN_LINEAR(LINEAR_RGBA;REPLACE,4);
break;
default:
- abort();
+ _mesa_problem(ctx, "bad tex env mode (8) in SPAN_LINEAR");
+ return;
}
break;
}
break;
}
- /* This does not seem to be necessary, but I don't know !! */
- /* span->tex[0][0] = tex_coord[0] / (info->smask + 1),
- span->tex[0][1] = tex_coord[1] / (info->tmask + 1),*/
- /* span->tex[0][2] only if 3D-texturing, here only 2D */
- /* span->tex[0][3] = tex_coord[2]; */
- _mesa_write_rgba_span(ctx, span->count, span->x, span->y,
- zspan, fogspan, rgba, NULL, GL_POLYGON);
-
+ ASSERT(span->arrayMask & SPAN_RGBA);
+ _swrast_write_rgba_span(ctx, span);
#undef SPAN_NEAREST
#undef SPAN_LINEAR
-#undef FixedToDepth
+
+ /* restore state */
+ ctx->Texture._EnabledUnits = savedTexEnable;
}
* by interpolated Q/W comes out right.
*
*/
-static void persp_textured_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
-{
+#define NAME persp_textured_triangle
#define INTERP_Z 1
+#define INTERP_W 1
#define INTERP_FOG 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
#define INTERP_RGB 1
#define INTERP_ALPHA 1
-#define INTERP_TEX 1
+#define INTERP_ATTRIBS 1
#define SETUP_CODE \
struct persp_info info; \
- struct gl_texture_unit *unit = ctx->Texture.Unit+0; \
- struct gl_texture_object *obj = unit->Current2D; \
- GLint b = obj->BaseLevel; \
- info.fixedToDepthShift = ctx->Visual.depthBits <= 16 ? FIXED_SHIFT : 0;\
- info.texture = (const GLchan *) obj->Image[b]->Data; \
- info.twidth_log2 = obj->Image[b]->WidthLog2; \
- info.smask = obj->Image[b]->Width - 1; \
- info.tmask = obj->Image[b]->Height - 1; \
- info.format = obj->Image[b]->Format; \
+ const struct gl_texture_unit *unit = ctx->Texture.Unit+0; \
+ const struct gl_texture_object *obj = unit->Current2D; \
+ const GLint b = obj->BaseLevel; \
+ info.texture = (const GLchan *) obj->Image[0][b]->Data; \
+ info.twidth_log2 = obj->Image[0][b]->WidthLog2; \
+ info.smask = obj->Image[0][b]->Width - 1; \
+ info.tmask = obj->Image[0][b]->Height - 1; \
+ info.format = obj->Image[0][b]->_BaseFormat; \
info.filter = obj->MinFilter; \
info.envmode = unit->EnvMode; \
\
if (info.envmode == GL_BLEND) { \
/* potential off-by-one error here? (1.0f -> 2048 -> 0) */ \
- info.er = FloatToFixed(unit->EnvColor[RCOMP]); \
- info.eg = FloatToFixed(unit->EnvColor[GCOMP]); \
- info.eb = FloatToFixed(unit->EnvColor[BCOMP]); \
- info.ea = FloatToFixed(unit->EnvColor[ACOMP]); \
+ info.er = FloatToFixed(unit->EnvColor[RCOMP] * CHAN_MAXF); \
+ info.eg = FloatToFixed(unit->EnvColor[GCOMP] * CHAN_MAXF); \
+ info.eb = FloatToFixed(unit->EnvColor[BCOMP] * CHAN_MAXF); \
+ info.ea = FloatToFixed(unit->EnvColor[ACOMP] * CHAN_MAXF); \
} \
if (!info.texture) { \
/* this shouldn't happen */ \
case GL_ALPHA: \
case GL_LUMINANCE: \
case GL_INTENSITY: \
- info.tbytesline = obj->Image[b]->Width; \
+ info.tbytesline = obj->Image[0][b]->Width; \
break; \
case GL_LUMINANCE_ALPHA: \
- info.tbytesline = obj->Image[b]->Width * 2; \
+ info.tbytesline = obj->Image[0][b]->Width * 2; \
break; \
case GL_RGB: \
- info.tbytesline = obj->Image[b]->Width * 3; \
+ info.tbytesline = obj->Image[0][b]->Width * 3; \
break; \
case GL_RGBA: \
- info.tbytesline = obj->Image[b]->Width * 4; \
+ info.tbytesline = obj->Image[0][b]->Width * 4; \
break; \
default: \
_mesa_problem(NULL, "Bad texture format in persp_textured_triangle");\
return; \
} \
- info.tsize = obj->Image[b]->Height * info.tbytesline;
+ info.tsize = obj->Image[0][b]->Height * info.tbytesline;
-#define RENDER_SPAN( span ) fast_persp_span(ctx, &span, &info);
+#define RENDER_SPAN( span ) \
+ span.interpMask &= ~SPAN_RGBA; \
+ span.arrayMask |= SPAN_RGBA; \
+ fast_persp_span(ctx, &span, &info);
#include "s_tritemp.h"
-}
-
#endif /* CHAN_BITS != GL_FLOAT */
-
-/*
- * Generate arrays of fragment colors, z, fog, texcoords, etc from a
- * triangle span object. Then call the span/fragment processsing
- * functions in s_span.[ch]. This is used by a bunch of the textured
- * triangle functions.
- */
-static void
-rasterize_span(GLcontext *ctx, const struct triangle_span *span)
-{
- DEFMARRAY(GLchan, rgba, MAX_WIDTH, 4);
- DEFMARRAY(GLchan, spec, MAX_WIDTH, 4);
- DEFARRAY(GLuint, index, MAX_WIDTH);
- DEFARRAY(GLuint, z, MAX_WIDTH);
- DEFARRAY(GLfloat, fog, MAX_WIDTH);
- DEFARRAY(GLfloat, sTex, MAX_WIDTH);
- DEFARRAY(GLfloat, tTex, MAX_WIDTH);
- DEFARRAY(GLfloat, rTex, MAX_WIDTH);
- DEFARRAY(GLfloat, lambda, MAX_WIDTH);
- DEFMARRAY(GLfloat, msTex, MAX_TEXTURE_UNITS, MAX_WIDTH);
- DEFMARRAY(GLfloat, mtTex, MAX_TEXTURE_UNITS, MAX_WIDTH);
- DEFMARRAY(GLfloat, mrTex, MAX_TEXTURE_UNITS, MAX_WIDTH);
- DEFMARRAY(GLfloat, mLambda, MAX_TEXTURE_UNITS, MAX_WIDTH);
-
- CHECKARRAY(rgba, return);
- CHECKARRAY(spec, return);
- CHECKARRAY(index, return);
- CHECKARRAY(z, return);
- CHECKARRAY(fog, return);
- CHECKARRAY(sTex, return);
- CHECKARRAY(tTex, return);
- CHECKARRAY(rTex, return);
- CHECKARRAY(lambda, return);
- CHECKARRAY(msTex, return);
- CHECKARRAY(mtTex, return);
- CHECKARRAY(mrTex, return);
- CHECKARRAY(mLambda, return);
-
- if (span->activeMask & SPAN_RGBA) {
- if (span->activeMask & SPAN_FLAT) {
- GLuint i;
- GLchan color[4];
- color[RCOMP] = FixedToChan(span->red);
- color[GCOMP] = FixedToChan(span->green);
- color[BCOMP] = FixedToChan(span->blue);
- color[ACOMP] = FixedToChan(span->alpha);
- for (i = 0; i < span->count; i++) {
- COPY_CHAN4(rgba[i], color);
- }
- }
- else {
- /* smooth interpolation */
-#if CHAN_TYPE == GL_FLOAT
- GLfloat r = span->red;
- GLfloat g = span->green;
- GLfloat b = span->blue;
- GLfloat a = span->alpha;
-#else
- GLfixed r = span->red;
- GLfixed g = span->green;
- GLfixed b = span->blue;
- GLfixed a = span->alpha;
-#endif
- GLuint i;
- for (i = 0; i < span->count; i++) {
- rgba[i][RCOMP] = FixedToChan(r);
- rgba[i][GCOMP] = FixedToChan(g);
- rgba[i][BCOMP] = FixedToChan(b);
- rgba[i][ACOMP] = FixedToChan(a);
- r += span->redStep;
- g += span->greenStep;
- b += span->blueStep;
- a += span->alphaStep;
- }
- }
- }
-
- if (span->activeMask & SPAN_SPEC) {
- if (span->activeMask & SPAN_FLAT) {
- const GLchan r = FixedToChan(span->specRed);
- const GLchan g = FixedToChan(span->specGreen);
- const GLchan b = FixedToChan(span->specBlue);
- GLuint i;
- for (i = 0; i < span->count; i++) {
- spec[i][RCOMP] = r;
- spec[i][GCOMP] = g;
- spec[i][BCOMP] = b;
- }
- }
- else {
- /* smooth interpolation */
-#if CHAN_TYPE == GL_FLOAT
- GLfloat r = span->specRed;
- GLfloat g = span->specGreen;
- GLfloat b = span->specBlue;
-#else
- GLfixed r = span->specRed;
- GLfixed g = span->specGreen;
- GLfixed b = span->specBlue;
-#endif
- GLuint i;
- for (i = 0; i < span->count; i++) {
- spec[i][RCOMP] = FixedToChan(r);
- spec[i][GCOMP] = FixedToChan(g);
- spec[i][BCOMP] = FixedToChan(b);
- r += span->specRedStep;
- g += span->specGreenStep;
- b += span->specBlueStep;
- }
- }
- }
-
- if (span->activeMask & SPAN_INDEX) {
- if (span->activeMask & SPAN_FLAT) {
- GLuint i;
- const GLint indx = FixedToInt(span->index);
- for (i = 0; i < span->count; i++) {
- index[i] = indx;
- }
- }
- else {
- /* smooth interpolation */
- GLuint i;
- GLfixed ind = span->index;
- for (i = 0; i < span->count; i++) {
- index[i] = FixedToInt(ind);
- ind += span->indexStep;
- }
- }
- }
-
- if (span->activeMask & SPAN_Z) {
- if (ctx->Visual.depthBits <= 16) {
- GLuint i;
- GLfixed zval = span->z;
- for (i = 0; i < span->count; i++) {
- z[i] = FixedToInt(zval);
- zval += span->zStep;
- }
- }
- else {
- /* Deep Z buffer, no fixed->int shift */
- GLuint i;
- GLfixed zval = span->z;
- for (i = 0; i < span->count; i++) {
- z[i] = zval;
- zval += span->zStep;
- }
- }
- }
- if (span->activeMask & SPAN_FOG) {
- GLuint i;
- GLfloat f = span->fog;
- for (i = 0; i < span->count; i++) {
- fog[i] = f;
- f += span->fogStep;
- }
- }
- if (span->activeMask & SPAN_TEXTURE) {
- if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) {
- /* multitexture */
- if (span->activeMask & SPAN_LAMBDA) {
- /* with lambda */
- GLuint u;
- for (u = 0; u < MAX_TEXTURE_UNITS; u++) {
- if (ctx->Texture.Unit[u]._ReallyEnabled) {
- GLfloat s = span->tex[u][0];
- GLfloat t = span->tex[u][1];
- GLfloat r = span->tex[u][2];
- GLfloat q = span->tex[u][3];
- GLuint i;
- for (i = 0; i < span->count; i++) {
- const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
- msTex[u][i] = s * invQ;
- mtTex[u][i] = t * invQ;
- mrTex[u][i] = r * invQ;
- mLambda[u][i] = (GLfloat)
- (log(span->rho[u] * invQ * invQ) * 1.442695F * 0.5F);
- s += span->texStep[u][0];
- t += span->texStep[u][1];
- r += span->texStep[u][2];
- q += span->texStep[u][3];
- }
- }
- }
- }
- else {
- /* without lambda */
- GLuint u;
- for (u = 0; u < MAX_TEXTURE_UNITS; u++) {
- if (ctx->Texture.Unit[u]._ReallyEnabled) {
- GLfloat s = span->tex[u][0];
- GLfloat t = span->tex[u][1];
- GLfloat r = span->tex[u][2];
- GLfloat q = span->tex[u][3];
- GLuint i;
- for (i = 0; i < span->count; i++) {
- const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
- msTex[u][i] = s * invQ;
- mtTex[u][i] = t * invQ;
- mrTex[u][i] = r * invQ;
- s += span->texStep[u][0];
- t += span->texStep[u][1];
- r += span->texStep[u][2];
- q += span->texStep[u][3];
- }
- }
- }
- }
- }
- else {
- /* just texture unit 0 */
- if (span->activeMask & SPAN_LAMBDA) {
- /* with lambda */
- GLfloat s = span->tex[0][0];
- GLfloat t = span->tex[0][1];
- GLfloat r = span->tex[0][2];
- GLfloat q = span->tex[0][3];
- GLuint i;
- for (i = 0; i < span->count; i++) {
- const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
- sTex[i] = s * invQ;
- tTex[i] = t * invQ;
- rTex[i] = r * invQ;
- lambda[i] = (GLfloat)
- (log(span->rho[0] * invQ * invQ) * 1.442695F * 0.5F);
- s += span->texStep[0][0];
- t += span->texStep[0][1];
- r += span->texStep[0][2];
- q += span->texStep[0][3];
- }
- }
- else {
- /* without lambda */
- GLfloat s = span->tex[0][0];
- GLfloat t = span->tex[0][1];
- GLfloat r = span->tex[0][2];
- GLfloat q = span->tex[0][3];
- GLuint i;
- for (i = 0; i < span->count; i++) {
- const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
- sTex[i] = s * invQ;
- tTex[i] = t * invQ;
- rTex[i] = r * invQ;
- s += span->texStep[0][0];
- t += span->texStep[0][1];
- r += span->texStep[0][2];
- q += span->texStep[0][3];
- }
- }
- }
- }
- /* XXX keep this? */
- if (span->activeMask & SPAN_INT_TEXTURE) {
- GLint intTexcoord[MAX_WIDTH][2];
- GLfixed s = span->intTex[0];
- GLfixed t = span->intTex[1];
- GLuint i;
- for (i = 0; i < span->count; i++) {
- intTexcoord[i][0] = FixedToInt(s);
- intTexcoord[i][1] = FixedToInt(t);
- s += span->intTexStep[0];
- t += span->intTexStep[1];
- }
- }
-
- /* examine activeMask and call a s_span.c function */
- if (span->activeMask & SPAN_TEXTURE) {
- const GLfloat *fogPtr;
- if (span->activeMask & SPAN_FOG)
- fogPtr = fog;
- else
- fogPtr = NULL;
-
- if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) {
- if (span->activeMask & SPAN_SPEC) {
- _mesa_write_multitexture_span(ctx, span->count, span->x, span->y,
- z, fogPtr,
- (const GLfloat (*)[MAX_WIDTH]) msTex,
- (const GLfloat (*)[MAX_WIDTH]) mtTex,
- (const GLfloat (*)[MAX_WIDTH]) mrTex,
- (GLfloat (*)[MAX_WIDTH]) mLambda,
- rgba, (CONST GLchan (*)[4]) spec,
- NULL, GL_POLYGON );
- }
- else {
- _mesa_write_multitexture_span(ctx, span->count, span->x, span->y,
- z, fogPtr,
- (const GLfloat (*)[MAX_WIDTH]) msTex,
- (const GLfloat (*)[MAX_WIDTH]) mtTex,
- (const GLfloat (*)[MAX_WIDTH]) mrTex,
- (GLfloat (*)[MAX_WIDTH]) mLambda,
- rgba, NULL, NULL, GL_POLYGON);
- }
- }
- else {
- /* single texture */
- if (span->activeMask & SPAN_SPEC) {
- _mesa_write_texture_span(ctx, span->count, span->x, span->y,
- z, fogPtr, sTex, tTex, rTex, lambda,
- rgba, (CONST GLchan (*)[4]) spec,
- NULL, GL_POLYGON);
- }
- else {
- _mesa_write_texture_span(ctx, span->count, span->x, span->y,
- z, fogPtr, sTex, tTex, rTex, lambda,
- rgba, NULL, NULL, GL_POLYGON);
- }
- }
- }
- else {
- _mesa_problem(ctx, "rasterize_span() should only be used for texturing");
- }
-
- UNDEFARRAY(rgba);
- UNDEFARRAY(spec);
- UNDEFARRAY(index);
- UNDEFARRAY(z);
- UNDEFARRAY(fog);
- UNDEFARRAY(sTex);
- UNDEFARRAY(tTex);
- UNDEFARRAY(rTex);
- UNDEFARRAY(lambda);
- UNDEFARRAY(msTex);
- UNDEFARRAY(mtTex);
- UNDEFARRAY(mrTex);
- UNDEFARRAY(mLambda);
-}
-
/*
- * Render a smooth-shaded, textured, RGBA triangle.
- * Interpolate S,T,R with perspective correction, w/out mipmapping.
+ * Render an RGBA triangle with arbitrary attributes.
*/
-static void general_textured_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
-{
+#define NAME general_triangle
#define INTERP_Z 1
+#define INTERP_W 1
#define INTERP_FOG 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define INTERP_TEX 1
-
-#define SETUP_CODE \
- const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; \
- const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];\
- DEFARRAY(GLfloat, sSpan, MAX_WIDTH); /* mac 32k limitation */ \
- DEFARRAY(GLfloat, tSpan, MAX_WIDTH); /* mac 32k limitation */ \
- DEFARRAY(GLfloat, uSpan, MAX_WIDTH); /* mac 32k limitation */ \
- CHECKARRAY(sSpan, return); /* mac 32k limitation */ \
- CHECKARRAY(tSpan, return); /* mac 32k limitation */ \
- CHECKARRAY(uSpan, return); /* mac 32k limitation */ \
- span.texWidth[0] = (GLfloat) texImage->Width; \
- span.texHeight[0] = (GLfloat) texImage->Height; \
- (void) fixedToDepthShift;
-
-#define RENDER_SPAN( span ) \
- GLdepth zSpan[MAX_WIDTH]; \
- GLfloat fogSpan[MAX_WIDTH]; \
- GLchan rgbaSpan[MAX_WIDTH][4]; \
- GLuint i; \
- /* NOTE: we could just call rasterize_span() here instead */ \
- for (i = 0; i < span.count; i++) { \
- GLdouble invQ = span.tex[0][3] ? (1.0 / span.tex[0][3]) : 1.0; \
- zSpan[i] = FixedToDepth(span.z); \
- span.z += span.zStep; \
- fogSpan[i] = span.fog; \
- span.fog += span.fogStep; \
- rgbaSpan[i][RCOMP] = FixedToChan(span.red); \
- rgbaSpan[i][GCOMP] = FixedToChan(span.green); \
- rgbaSpan[i][BCOMP] = FixedToChan(span.blue); \
- rgbaSpan[i][ACOMP] = FixedToChan(span.alpha); \
- span.red += span.redStep; \
- span.green += span.greenStep; \
- span.blue += span.blueStep; \
- span.alpha += span.alphaStep; \
- sSpan[i] = (GLfloat) (span.tex[0][0] * invQ); \
- tSpan[i] = (GLfloat) (span.tex[0][1] * invQ); \
- uSpan[i] = (GLfloat) (span.tex[0][2] * invQ); \
- span.tex[0][0] += span.texStep[0][0]; \
- span.tex[0][1] += span.texStep[0][1]; \
- span.tex[0][2] += span.texStep[0][2]; \
- span.tex[0][3] += span.texStep[0][3]; \
- } \
- _mesa_write_texture_span(ctx, span.count, span.x, span.y, \
- zSpan, fogSpan, sSpan, tSpan, uSpan, \
- NULL, rgbaSpan, NULL, NULL, GL_POLYGON );
-
-#define CLEANUP_CODE \
- UNDEFARRAY(sSpan); /* mac 32k limitation */ \
- UNDEFARRAY(tSpan); \
- UNDEFARRAY(uSpan);
-
-#include "s_tritemp.h"
-}
-
-
-/*
- * Render a smooth-shaded, textured, RGBA triangle with separate specular
- * color interpolation.
- * Interpolate texcoords with perspective correction, w/out mipmapping.
- */
-static void general_textured_spec_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
-{
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
#define INTERP_RGB 1
#define INTERP_SPEC 1
#define INTERP_ALPHA 1
-#define INTERP_TEX 1
-
-#define SETUP_CODE \
- const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; \
- const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];\
- span.texWidth[0] = (GLfloat) texImage->Width; \
- span.texHeight[0] = (GLfloat) texImage->Height; \
- (void) fixedToDepthShift;
-
-#define RENDER_SPAN( span ) rasterize_span(ctx, &span);
-
-#include "s_tritemp.h"
-}
-
-
-/*
- * Render a smooth-shaded, textured, RGBA triangle.
- * Interpolate S,T,R with perspective correction and compute lambda for
- * each fragment. Lambda is used to determine whether to use the
- * minification or magnification filter. If minification and using
- * mipmaps, lambda is also used to select the texture level of detail.
- */
-static void lambda_textured_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
-{
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define INTERP_TEX 1
-#define INTERP_LAMBDA 1
-
-#define SETUP_CODE \
- const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; \
- const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];\
- span.texWidth[0] = (GLfloat) texImage->Width; \
- span.texHeight[0] = (GLfloat) texImage->Height; \
- (void) fixedToDepthShift;
-
-#define RENDER_SPAN( span ) rasterize_span(ctx, &span);
-
+#define INTERP_ATTRIBS 1
+#define RENDER_SPAN( span ) _swrast_write_rgba_span(ctx, &span);
#include "s_tritemp.h"
-}
-
-
-/*
- * Render a smooth-shaded, textured, RGBA triangle with separate specular
- * interpolation.
- * Interpolate S,T,R with perspective correction and compute lambda for
- * each fragment. Lambda is used to determine whether to use the
- * minification or magnification filter. If minification and using
- * mipmaps, lambda is also used to select the texture level of detail.
- */
-static void lambda_textured_spec_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
-{
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#define INTERP_RGB 1
-#define INTERP_SPEC 1
-#define INTERP_ALPHA 1
-#define INTERP_TEX 1
-#define INTERP_LAMBDA 1
-
-#define SETUP_CODE \
- const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; \
- const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];\
- span.texWidth[0] = (GLfloat) texImage->Width; \
- span.texHeight[0] = (GLfloat) texImage->Height; \
- (void) fixedToDepthShift;
-#define RENDER_SPAN( span ) rasterize_span(ctx, &span);
-#include "s_tritemp.h"
-}
/*
- * This is the big one!
- * Interpolate Z, RGB, Alpha, specular, fog, and N sets of texture coordinates
- * with lambda (LOD).
- * Yup, it's slow.
+ * Special tri function for occlusion testing
*/
-static void
-lambda_multitextured_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
-{
-
+#define NAME occlusion_zless_triangle
#define INTERP_Z 1
-#define INTERP_FOG 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define INTERP_SPEC 1
-#define INTERP_MULTITEX 1
-#define INTERP_LAMBDA 1
-
#define SETUP_CODE \
- GLuint u; \
- 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; \
+ struct gl_renderbuffer *rb = ctx->DrawBuffer->_DepthBuffer; \
+ struct gl_query_object *q = ctx->Query.CurrentOcclusionObject; \
+ ASSERT(ctx->Depth.Test); \
+ ASSERT(!ctx->Depth.Mask); \
+ ASSERT(ctx->Depth.Func == GL_LESS); \
+ if (!q) { \
+ return; \
+ }
+#define RENDER_SPAN( span ) \
+ if (rb->DepthBits <= 16) { \
+ GLuint i; \
+ const GLushort *zRow = (const GLushort *) \
+ rb->GetPointer(ctx, rb, span.x, span.y); \
+ for (i = 0; i < span.end; i++) { \
+ GLuint z = FixedToDepth(span.z); \
+ if (z < zRow[i]) { \
+ q->Result++; \
+ } \
+ span.z += span.zStep; \
} \
} \
- (void) fixedToDepthShift;
-
-#define RENDER_SPAN( span ) rasterize_span(ctx, &span);
-
-#include "s_tritemp.h"
-
-}
-
-
-static void occlusion_zless_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
-{
- if (ctx->OcclusionResult) {
- return;
+ else { \
+ GLuint i; \
+ const GLuint *zRow = (const GLuint *) \
+ rb->GetPointer(ctx, rb, span.x, span.y); \
+ for (i = 0; i < span.end; i++) { \
+ if ((GLuint)span.z < zRow[i]) { \
+ q->Result++; \
+ } \
+ span.z += span.zStep; \
+ } \
}
+#include "s_tritemp.h"
-#define DO_OCCLUSION_TEST
-#define INTERP_Z 1
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#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"
-}
-
-static void nodraw_triangle( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1,
- const SWvertex *v2 )
+static void
+nodraw_triangle( GLcontext *ctx,
+ const SWvertex *v0,
+ const SWvertex *v1,
+ const SWvertex *v2 )
{
(void) (ctx && v0 && v1 && v2);
}
+
+/*
+ * This is used when separate specular color is enabled, but not
+ * texturing. We add the specular color to the primary color,
+ * draw the triangle, then restore the original primary color.
+ * Inefficient, but seldom needed.
+ */
void _swrast_add_spec_terms_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
SWvertex *ncv0 = (SWvertex *)v0; /* drop const qualifier */
SWvertex *ncv1 = (SWvertex *)v1;
SWvertex *ncv2 = (SWvertex *)v2;
+#if CHAN_TYPE == GL_FLOAT
+ GLfloat rSum, gSum, bSum;
+#else
+ GLint rSum, gSum, bSum;
+#endif
GLchan c[3][4];
+ /* save original colors */
COPY_CHAN4( c[0], ncv0->color );
COPY_CHAN4( c[1], ncv1->color );
COPY_CHAN4( c[2], ncv2->color );
- ACC_3V( ncv0->color, ncv0->specular );
- ACC_3V( ncv1->color, ncv1->specular );
- ACC_3V( ncv2->color, ncv2->specular );
+ /* sum v0 */
+ rSum = ncv0->color[0] + ncv0->specular[0];
+ gSum = ncv0->color[1] + ncv0->specular[1];
+ bSum = ncv0->color[2] + ncv0->specular[2];
+ ncv0->color[0] = MIN2(rSum, CHAN_MAX);
+ ncv0->color[1] = MIN2(gSum, CHAN_MAX);
+ ncv0->color[2] = MIN2(bSum, CHAN_MAX);
+ /* sum v1 */
+ rSum = ncv1->color[0] + ncv1->specular[0];
+ gSum = ncv1->color[1] + ncv1->specular[1];
+ bSum = ncv1->color[2] + ncv1->specular[2];
+ ncv1->color[0] = MIN2(rSum, CHAN_MAX);
+ ncv1->color[1] = MIN2(gSum, CHAN_MAX);
+ ncv1->color[2] = MIN2(bSum, CHAN_MAX);
+ /* sum v2 */
+ rSum = ncv2->color[0] + ncv2->specular[0];
+ gSum = ncv2->color[1] + ncv2->specular[1];
+ bSum = ncv2->color[2] + ncv2->specular[2];
+ ncv2->color[0] = MIN2(rSum, CHAN_MAX);
+ ncv2->color[1] = MIN2(gSum, CHAN_MAX);
+ ncv2->color[2] = MIN2(bSum, CHAN_MAX);
+ /* draw */
SWRAST_CONTEXT(ctx)->SpecTriangle( ctx, ncv0, ncv1, ncv2 );
+ /* restore original colors */
COPY_CHAN4( ncv0->color, c[0] );
COPY_CHAN4( ncv1->color, c[1] );
COPY_CHAN4( ncv2->color, c[2] );
#ifdef DEBUG
/* record the current triangle function name */
-static const char *triFuncName = NULL;
+const char *_mesa_triFuncName = NULL;
-#define USE(triFunc) \
-do { \
- triFuncName = #triFunc; \
- /*printf("%s\n", triFuncName);*/ \
- swrast->Triangle = triFunc; \
+#define USE(triFunc) \
+do { \
+ _mesa_triFuncName = #triFunc; \
+ /*printf("%s\n", _mesa_triFuncName);*/ \
+ swrast->Triangle = triFunc; \
} while (0)
#else
if (ctx->RenderMode==GL_RENDER) {
if (ctx->Polygon.SmoothFlag) {
- _mesa_set_aa_triangle_function(ctx);
+ _swrast_set_aa_triangle_function(ctx);
ASSERT(swrast->Triangle);
return;
}
- if (ctx->Depth.OcclusionTest &&
+ /* special case for occlusion testing */
+ if (ctx->Query.CurrentOcclusionObject &&
ctx->Depth.Test &&
ctx->Depth.Mask == GL_FALSE &&
ctx->Depth.Func == GL_LESS &&
}
}
- if (ctx->Texture._ReallyEnabled) {
+ if (!rgbmode) {
+ USE(ci_triangle);
+ return;
+ }
+
+ if (ctx->Texture._EnabledCoordUnits ||
+ ctx->FragmentProgram._Current ||
+ ctx->ATIFragmentShader._Enabled) {
/* Ugh, we do a _lot_ of tests to pick the best textured tri func */
- const struct gl_texture_object *texObj2D;
+ const struct gl_texture_object *texObj2D;
const struct gl_texture_image *texImg;
GLenum minFilter, magFilter, envMode;
GLint format;
texObj2D = ctx->Texture.Unit[0].Current2D;
- texImg = texObj2D ? texObj2D->Image[texObj2D->BaseLevel] : NULL;
+ texImg = texObj2D ? texObj2D->Image[0][texObj2D->BaseLevel] : NULL;
format = texImg ? texImg->TexFormat->MesaFormat : -1;
minFilter = texObj2D ? texObj2D->MinFilter : (GLenum) 0;
magFilter = texObj2D ? texObj2D->MagFilter : (GLenum) 0;
envMode = ctx->Texture.Unit[0].EnvMode;
- /* First see if we can used an optimized 2-D texture function */
- if (ctx->Texture._ReallyEnabled==TEXTURE0_2D
- && texObj2D->WrapS==GL_REPEAT
- && texObj2D->WrapT==GL_REPEAT
- && texImg->Border==0
+ /* First see if we can use an optimized 2-D texture function */
+ if (ctx->Texture._EnabledCoordUnits == 0x1
+ && !ctx->FragmentProgram._Current
+ && !ctx->ATIFragmentShader._Enabled
+ && ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT
+ && texObj2D->WrapS == GL_REPEAT
+ && texObj2D->WrapT == GL_REPEAT
+ && texImg->_IsPowerOfTwo
+ && texImg->Border == 0
+ && texImg->Width == texImg->RowStride
&& (format == MESA_FORMAT_RGB || format == MESA_FORMAT_RGBA)
- && minFilter == magFilter
- && ctx->Light.Model.ColorControl == GL_SINGLE_COLOR
- && ctx->Texture.Unit[0].EnvMode != GL_COMBINE_EXT) {
+ && minFilter == magFilter
+ && ctx->Light.Model.ColorControl == GL_SINGLE_COLOR
+ && ctx->Texture.Unit[0].EnvMode != GL_COMBINE_EXT) {
if (ctx->Hint.PerspectiveCorrection==GL_FASTEST) {
if (minFilter == GL_NEAREST
&& format == MESA_FORMAT_RGB
&& ctx->Depth.Func == GL_LESS
&& ctx->Depth.Mask == GL_TRUE)
|| swrast->_RasterMask == TEXTURE_BIT)
- && ctx->Polygon.StippleFlag == GL_FALSE) {
+ && ctx->Polygon.StippleFlag == GL_FALSE
+ && ctx->DrawBuffer->Visual.depthBits <= 16) {
if (swrast->_RasterMask == (DEPTH_BIT | TEXTURE_BIT)) {
USE(simple_z_textured_triangle);
}
}
}
else {
-#if CHAN_TYPE == GL_FLOAT
- USE(general_textured_triangle);
+#if (CHAN_BITS == 16 || CHAN_BITS == 32)
+ USE(general_triangle);
#else
USE(affine_textured_triangle);
#endif
}
}
else {
-#if CHAN_TYPE == GL_FLOAT
- USE(general_textured_triangle);
+#if (CHAN_BITS == 16 || CHAN_BITS == 32)
+ USE(general_triangle);
#else
USE(persp_textured_triangle);
#endif
}
}
else {
- /* More complicated textures (mipmap, multi-tex, sep specular) */
- GLboolean needLambda;
- /* if mag filter != min filter we need to compute lambda */
- const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
- if (obj && obj->MinFilter != obj->MagFilter)
- needLambda = GL_TRUE;
- else
- needLambda = GL_FALSE;
- if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) {
- USE(lambda_multitextured_triangle);
- }
- else if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
- /* separate specular color interpolation */
- if (needLambda) {
- USE(lambda_textured_spec_triangle);
- }
- else {
- USE(general_textured_spec_triangle);
- }
- }
- else {
- if (needLambda) {
- USE(lambda_textured_triangle);
- }
- else {
- USE(general_textured_triangle);
- }
- }
+ /* general case textured triangles */
+ USE(general_triangle);
}
}
else {
- ASSERT(!ctx->Texture._ReallyEnabled);
+ ASSERT(!ctx->Texture._EnabledCoordUnits);
if (ctx->Light.ShadeModel==GL_SMOOTH) {
/* smooth shaded, no texturing, stippled or some raster ops */
- if (rgbmode) {
- USE(smooth_rgba_triangle);
- }
- else {
- USE(smooth_ci_triangle);
- }
+ USE(smooth_rgba_triangle);
}
else {
/* flat shaded, no texturing, stippled or some raster ops */
- if (rgbmode) {
- USE(flat_rgba_triangle);
- }
- else {
- USE(flat_ci_triangle);
- }
+ USE(flat_rgba_triangle);
}
}
}
else if (ctx->RenderMode==GL_FEEDBACK) {
- USE(_mesa_feedback_triangle);
+ USE(_swrast_feedback_triangle);
}
else {
/* GL_SELECT mode */
- USE(_mesa_select_triangle);
+ USE(_swrast_select_triangle);
}
}