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