diff options
Diffstat (limited to 'src/mesa/swrast/s_span.c')
-rw-r--r-- | src/mesa/swrast/s_span.c | 855 |
1 files changed, 126 insertions, 729 deletions
diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 4e4bdf298f6..489a494a7f3 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.24 2002/01/27 18:32:03 brianp Exp $ */ +/* $Id: s_span.c,v 1.25 2002/01/28 00:07:33 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -139,11 +139,6 @@ interpolate_colors(GLcontext *ctx, struct sw_span *span) ASSERT(span->interpMask & SPAN_RGBA); - /* - SW_SPAN_SET_FLAG(span->filledColor); - SW_SPAN_SET_FLAG(span->filledAlpha); - */ - if (span->interpMask & SPAN_FLAT) { /* constant color */ GLchan color[4]; @@ -251,8 +246,6 @@ interpolate_z(GLcontext *ctx, struct sw_span *span) ASSERT(span->interpMask & SPAN_Z); - /* SW_SPAN_SET_FLAG(span->filledDepth);*/ - if (ctx->Visual.depthBits <= 16) { GLfixed zval = span->z; for (i = 0; i < n; i++) { @@ -294,8 +287,6 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) GLfloat r = span->tex[u][2]; GLfloat q = span->tex[u][3]; GLuint i; - SW_SPAN_SET_FLAG(span->filledLambda[u]); - SW_SPAN_SET_FLAG(span->filledTex[u]); for (i = 0; i < span->end; i++) { const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); span->texcoords[u][i][0] = s * invQ; @@ -326,7 +317,6 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) GLfloat r = span->tex[u][2]; GLfloat q = span->tex[u][3]; GLuint i; - SW_SPAN_SET_FLAG(span->filledTex[u]); for (i = 0; i < span->end; i++) { const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); span->texcoords[u][i][0] = s * invQ; @@ -342,13 +332,6 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) } } else { -#ifdef DEBUG - {GLint i; - for (i=0; i<ctx->Const.MaxTextureUnits; i++) { - ASSERT(span->filledTex[i] == GL_FALSE && - span->filledLambda[i] == GL_FALSE); - }} -#endif if (span->interpMask & SPAN_LAMBDA) { /* just texture unit 0, with lambda */ const GLfloat ds = span->texStep[0][0]; @@ -360,8 +343,6 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) GLfloat r = span->tex[0][2]; GLfloat q = span->tex[0][3]; GLuint i; - SW_SPAN_SET_FLAG(span->filledLambda[0]); - SW_SPAN_SET_FLAG(span->filledTex[0]); for (i = 0; i < span->end; i++) { const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); span->texcoords[0][i][0] = s * invQ; @@ -387,7 +368,6 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) GLfloat r = span->tex[0][2]; GLfloat q = span->tex[0][3]; GLuint i; - SW_SPAN_SET_FLAG(span->filledTex[0]); for (i = 0; i < span->end; i++) { const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); span->texcoords[0][i][0] = s * invQ; @@ -407,31 +387,6 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) * Apply the current polygon stipple pattern to a span of pixels. */ static void -old_stipple_polygon_span( GLcontext *ctx, GLuint n, GLint x, GLint y, - GLubyte mask[] ) -{ - const GLuint highbit = 0x80000000; - GLuint i, m, stipple; - - stipple = ctx->PolygonStipple[y % 32]; - m = highbit >> (GLuint) (x % 32); - - for (i = 0; i < n; i++) { - if ((m & stipple) == 0) { - mask[i] = 0; - } - m = m >> 1; - if (m == 0) { - m = highbit; - } - } -} - - -/* - * Apply the current polygon stipple pattern to a span of pixels. - */ -static void stipple_polygon_span( GLcontext *ctx, struct sw_span *span) { const GLuint highbit = 0x80000000; @@ -453,49 +408,6 @@ stipple_polygon_span( GLcontext *ctx, struct sw_span *span) } - -/* - * Clip a pixel span to the current buffer/window boundaries. - * Return: 'n' such that pixel 'n', 'n+1' etc. are clipped, - * as a special case: - * 0 = all pixels clipped - */ -static GLuint -old_clip_span( GLcontext *ctx, GLint n, GLint x, GLint y, GLubyte mask[] ) -{ - /* Clip to top and bottom */ - if (y < 0 || y >= ctx->DrawBuffer->Height) { - return 0; - } - - /* Clip to the left */ - if (x < 0) { - if (x + n <= 0) { - /* completely off left side */ - return 0; - } - else { - /* partially off left side */ - BZERO(mask, -x * sizeof(GLubyte)); - } - } - - /* Clip to right */ - if (x + n > ctx->DrawBuffer->Width) { - if (x >= ctx->DrawBuffer->Width) { - /* completely off right side */ - return 0; - } - else { - /* partially off right side */ - return ctx->DrawBuffer->Width - x; - } - } - - return n; -} - - /* * Clip a pixel span to the current buffer/window boundaries. * Return: GL_TRUE some pixel still visible @@ -596,6 +508,8 @@ multi_write_index_span( GLcontext *ctx, GLuint n, GLint x, GLint y, /* * Draw to more than one RGBA color buffer (or none). + * All fragment operations, up to (but not) blending/logicop should + * have been done first. */ static void multi_write_rgba_span( GLcontext *ctx, GLuint n, GLint x, GLint y, @@ -845,45 +759,26 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span, } } - /* I have to think where to put this!! */ - if (span->interpMask & SPAN_Z) { -#ifdef DEBUG - span->filledDepth = GL_TRUE; -#endif - - if (ctx->Visual.depthBits <= 16) { - GLuint i; - GLfixed zval = span->z; - for (i = 0; i < span->end; i++) { - span->zArray[i] = FixedToInt(zval); - zval += span->zStep; + /* Stencil and Z testing */ + if (ctx->Stencil.Enabled || ctx->Depth.Test) { + if (span->interpMask & SPAN_Z) + interpolate_z(ctx, span); + + if (ctx->Stencil.Enabled) { + if (!_mesa_stencil_and_ztest_span(ctx, span)) { + span->arrayMask = origArrayMask; + return; } } else { - /* Deep Z buffer, no fixed->int shift */ - GLuint i; - GLfixed zval = span->z; - for (i = 0; i < span->end; i++) { - span->zArray[i] = zval; - zval += span->zStep; + ASSERT(ctx->Depth.Test); + ASSERT(span->arrayMask & SPAN_Z); + /* regular depth testing */ + if (!_mesa_depth_test_span(ctx, span)) { + span->arrayMask = origArrayMask; + return; } } - span->arrayMask |= SPAN_Z; - } - - if (ctx->Stencil.Enabled) { - /* first stencil test */ - if (_mesa_stencil_and_ztest_span(ctx, span) == GL_FALSE) { - span->arrayMask = origArrayMask; - return; - } - } - else if (ctx->Depth.Test) { - /* regular depth testing */ - if (_mesa_depth_test_span(ctx, span) == GL_FALSE) { - span->arrayMask = origArrayMask; - return; - } } /* if we get here, something passed the depth test */ @@ -895,8 +790,11 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span, _mesa_fog_rgba_pixels_with_array( ctx, span, span->fogArray, rgba); else if ((span->interpMask & SPAN_FOG) && !swrast->_PreferPixelFog) _mesa_fog_rgba_pixels( ctx, span, rgba ); - else + else { + if ((span->interpMask & SPAN_Z) && (span->arrayMask & SPAN_Z) == 0) + interpolate_z(ctx, span); _mesa_depth_fog_rgba_pixels( ctx, span, rgba ); + } } /* Antialias coverage application */ @@ -985,7 +883,9 @@ _mesa_write_monocolor_span( GLcontext *ctx, struct sw_span *span, /* Do the alpha test */ if (ctx->Color.AlphaEnabled) { - SW_SPAN_SET_FLAG(span->filledAlpha); + if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) + interpolate_colors(ctx, span); + for (i = 0; i < span->end; i++) { rgba[i][ACOMP] = color[ACOMP]; } @@ -994,29 +894,8 @@ _mesa_write_monocolor_span( GLcontext *ctx, struct sw_span *span, } } - /* I have to think where to put this!! */ - if (span->interpMask & SPAN_Z) { - SW_SPAN_SET_FLAG(span->filledDepth); - - if (ctx->Visual.depthBits <= 16) { - GLuint i; - GLfixed zval = span->z; - for (i = 0; i < span->end; i++) { - span->zArray[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->end; i++) { - span->zArray[i] = zval; - zval += span->zStep; - } - } - span->arrayMask |= SPAN_Z; - } + if (span->interpMask & SPAN_Z) + interpolate_z(ctx, span); if (ctx->Stencil.Enabled) { /* first stencil test */ @@ -1130,26 +1009,22 @@ _mesa_write_monocolor_span( GLcontext *ctx, struct sw_span *span, /* * Add specular color to base color. This is used only when - * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR - * or GL_COLOR_SUM_EXT is enabled. + * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR. */ static void -add_colors(CONST struct sw_span *span, GLchan rgba[][4]) +add_colors(GLuint n, GLchan rgba[][4], GLchan specular[][4] ) { GLuint i; - assert(span->arrayMask & SPAN_RGBA); - assert(span->arrayMask & SPAN_SPEC); - - for (i = 0; i < span->end; i++) { + for (i = 0; i < n; i++) { #if CHAN_TYPE == GL_FLOAT /* no clamping */ - rgba[i][RCOMP] += span->specArray[i][RCOMP]; - rgba[i][GCOMP] += span->specArray[i][GCOMP]; - rgba[i][BCOMP] += span->specArray[i][BCOMP]; + rgba[i][RCOMP] += specular[i][RCOMP]; + rgba[i][GCOMP] += specular[i][GCOMP]; + rgba[i][BCOMP] += specular[i][BCOMP]; #else - GLint r = rgba[i][RCOMP] + span->specArray[i][RCOMP]; - GLint g = rgba[i][GCOMP] + span->specArray[i][GCOMP]; - GLint b = rgba[i][BCOMP] + span->specArray[i][BCOMP]; + GLint r = rgba[i][RCOMP] + specular[i][RCOMP]; + GLint g = rgba[i][GCOMP] + specular[i][GCOMP]; + GLint b = rgba[i][BCOMP] + specular[i][BCOMP]; rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); @@ -1159,32 +1034,32 @@ add_colors(CONST struct sw_span *span, GLchan rgba[][4]) /* - * 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: span - contains span-data with the exception of - * fog - array of fog factor values in [0,1] - * primitive - either GL_POINT, GL_LINE, GL_POLYGON or GL_BITMAP. + * This function may modify any of the array values in the span. + * span->arrayMask, however, will not be modified (or we'll + * restore it to the original incoming value before returning. */ void _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span, - GLenum primitive ) + GLenum primitive ) { 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); + const GLuint origArrayMask = span->arrayMask; + + /* printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask);*/ + + ASSERT(ctx->Texture._ReallyEnabled); MEMSET(span->mask, 1, span->end); + /* clip against window bounds */ if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) { if (clip_span(ctx,span) == GL_FALSE) { return; } } - /* Do the scissor test */ + /* Scissor test */ if (ctx->Scissor.Enabled) { if (_mesa_scissor_span( ctx, span ) == GL_FALSE) { return; @@ -1196,300 +1071,109 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span, stipple_polygon_span( ctx, span); } - - if (primitive==GL_BITMAP || (swrast->_RasterMask & MULTI_DRAW_BIT)) { - /* must make a copy of the colors since they may be modified */ - MEMCPY(rgbaBackup, span->color.rgba, 4 * span->end * sizeof(GLchan)); - rgba = rgbaBackup; - } - else { - rgba = span->color.rgba; - } - + /* Need texture coordinates now */ + if ((span->interpMask & SPAN_TEXTURE) + && (span->arrayMask & SPAN_TEXTURE) == 0) + interpolate_texcoords(ctx, span); /* Texture with alpha test */ if (ctx->Color.AlphaEnabled) { + + /* Now we need the rgba array, fill it in if needed */ + if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) + interpolate_colors(ctx, span); + /* Texturing without alpha is done after depth-testing which - gives a potential speed-up. */ - ASSERT(ctx->Texture._ReallyEnabled); - _swrast_texture_fragments( ctx, 0, span, rgba ); + * gives a potential speed-up. + */ + _swrast_multitexture_fragments( ctx, span ); /* Do the alpha test */ - if (_mesa_alpha_test( ctx, span, (const GLchan (*)[4]) rgba ) == 0) { + if (!_old_alpha_test(ctx, span->end, + (CONST GLchan (*)[4]) span->color.rgba, + span->mask)) { + span->arrayMask = origArrayMask; return; } } - if (ctx->Stencil.Enabled) { - /* first stencil test */ - if (_mesa_stencil_and_ztest_span(ctx, span) == GL_FALSE) - return; - } - else if (ctx->Depth.Test) { - /* regular depth testing */ - if (_mesa_depth_test_span(ctx, span) == 0) - return; - } - - /* if we get here, something passed the depth test */ - ctx->OcclusionResult = GL_TRUE; - - /* Texture without alpha test */ - if (! ctx->Color.AlphaEnabled) { - ASSERT(ctx->Texture._ReallyEnabled); - _swrast_texture_fragments( ctx, 0, span, rgba ); - } - + /* Stencil and Z testing */ + if (ctx->Stencil.Enabled || ctx->Depth.Test) { + if (span->interpMask & SPAN_Z) + interpolate_z(ctx, span); - /* Add base and specular colors */ - if ((span->arrayMask & SPAN_SPEC) && /* Is this right test ???*/ - (ctx->Fog.ColorSumEnabled || - (ctx->Light.Enabled && - ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR))) { - add_colors(span, rgba); /* rgba = rgba + span->spec */ - } - - /* Per-pixel fog */ - if (ctx->Fog.Enabled) { - if ((span->arrayMask & SPAN_FOG) && !swrast->_PreferPixelFog) - _mesa_fog_rgba_pixels_with_array( ctx, span, span->fogArray, rgba); - else if ((span->interpMask & SPAN_FOG) && !swrast->_PreferPixelFog) - _mesa_fog_rgba_pixels( ctx, span, rgba ); - else - _mesa_depth_fog_rgba_pixels(ctx, span, rgba); - } - - - /* Antialias coverage application */ - if (span->arrayMask & SPAN_COVERAGE) { - GLuint i; - for (i = 0; i < span->end; i++) { - rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * span->coverage[i]); - } - } - - if (swrast->_RasterMask & MULTI_DRAW_BIT) { - multi_write_rgba_span( ctx, span->end, span->x, span->y, (const GLchan (*)[4]) rgba, span->mask ); - } - else { - /* normal: write to exactly one buffer */ - if (ctx->Color.ColorLogicOpEnabled) { - _mesa_logicop_rgba_span( ctx, span->end, span->x, span->y, rgba, span->mask ); - } - else if (ctx->Color.BlendEnabled) { - _mesa_blend_span( ctx, span->end, span->x, span->y, rgba, span->mask ); - } - if (colorMask == 0x0) { - return; - } - else if (colorMask != 0xffffffff) { - _mesa_mask_rgba_span( ctx, span->end, span->x, span->y, rgba ); - } - - (*swrast->Driver.WriteRGBASpan)( ctx, span->end, span->x, span->y, - (const GLchan (*)[4]) rgba, - span->writeAll ? NULL : span->mask ); - if (swrast->_RasterMask & ALPHABUF_BIT) { - _mesa_write_alpha_span( ctx, span->end, span->x, span->y, - (const GLchan (*)[4]) rgba, - span->writeAll ? NULL : span->mask ); - } - } -} - - -/* - * 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, struct sw_span *span) -{ - const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); - GLchan rgbaBackup[MAX_WIDTH][4]; - GLchan (*rgba)[4]; /* points to either span->color.rgba 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, span->color.rgba, 4 * span->end * sizeof(GLchan)); - rgba = rgbaBackup; - } - else { - rgba = span->color.rgba; - } - - - ASSERT(ctx->Texture._ReallyEnabled); - _swrast_texture_fragments( ctx, 0, span, rgba ); - - - /* Texture with alpha test */ - if (ctx->Color.AlphaEnabled) { - /* Do the alpha test */ - if (_mesa_alpha_test( ctx, span, (const GLchan (*)[4]) rgba ) == 0) { - return; - } - - /* 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, span) == GL_FALSE) + if (!_mesa_stencil_and_ztest_span(ctx, span)) { + span->arrayMask = origArrayMask; return; + } } - else if (ctx->Depth.Test) { + else { + ASSERT(ctx->Depth.Test); + ASSERT(span->arrayMask & SPAN_Z); /* regular depth testing */ - if (_mesa_depth_test_span(ctx, span) == 0) + if (!_mesa_depth_test_span(ctx, span)) { + span->arrayMask = origArrayMask; return; + } } } - /* if we get here, something passed the depth test */ + /* if we get here, some fragments passed the depth test */ ctx->OcclusionResult = GL_TRUE; - - - /* Add base and specular colors */ - if ((span->interpMask & SPAN_SPEC) && /* Is this right test ???*/ - (ctx->Fog.ColorSumEnabled || - (ctx->Light.Enabled && - ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR))) - add_colors(span, rgba); /* rgba = rgba + span->spec */ - - /* Per-pixel fog */ - if (ctx->Fog.Enabled) { - /* Is this the right 'if' ?? */ - if ((span->interpMask & SPAN_FOG) && !swrast->_PreferPixelFog) - _mesa_fog_rgba_pixels(ctx, span, rgba); - else - _mesa_depth_fog_rgba_pixels(ctx, span, rgba); - } - /* Antialias coverage application */ - if (span->arrayMask & SPAN_COVERAGE) { - GLuint i; - for (i = 0; i < span->end; i++) { - rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * span->coverage[i]); - } - } - - if (swrast->_RasterMask & MULTI_DRAW_BIT) { - multi_write_rgba_span( ctx, span->end, span->x, span->y, (const GLchan (*)[4]) rgba, span->mask ); - } - else { - /* normal: write to exactly one buffer */ - if (ctx->Color.ColorLogicOpEnabled) { - _mesa_logicop_rgba_span( ctx, span->end, span->x, span->y, rgba, span->mask ); - } - else if (ctx->Color.BlendEnabled) { - _mesa_blend_span( ctx, span->end, span->x, span->y, rgba, span->mask ); - } - if (colorMask == 0x0) { - return; - } - else if (colorMask != 0xffffffff) { - _mesa_mask_rgba_span( ctx, span->end, span->x, span->y, rgba ); - } - - (*swrast->Driver.WriteRGBASpan)( ctx, span->end, span->x, span->y, - (const GLchan (*)[4]) rgba, - span->writeAll ? NULL : span->mask ); - if (swrast->_RasterMask & ALPHABUF_BIT) { - _mesa_write_alpha_span( ctx, span->end, span->x, span->y, - (const GLchan (*)[4]) rgba, - span->writeAll ? NULL : span->mask ); - } + /* We had to wait until now to check for glColorMask(F,F,F,F) because of + * the occlusion test. + */ + if (colorMask == 0x0) { + span->arrayMask = origArrayMask; + return; } -} + /* Texture without alpha test */ + if (!ctx->Color.AlphaEnabled) { -/* - * As above but perform multiple stages of texture application. - * Contributed by Klaus Niederkrueger. - */ -static void -masked_multitexture_span( GLcontext *ctx, struct sw_span *span) -{ - GLchan rgbaBackup[MAX_WIDTH][4]; - GLchan (*rgba)[4]; /* points to either span->color.rgba or rgbaBackup */ - GLuint i; - const GLuint texUnits = ctx->Const.MaxTextureUnits; - SWcontext *swrast = SWRAST_CONTEXT(ctx); + /* Now we need the rgba array, fill it in if needed */ + if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) + interpolate_colors(ctx, span); - - if ( (swrast->_RasterMask & MULTI_DRAW_BIT) || texUnits > 1) { - /* must make a copy of the colors since they may be modified */ - MEMCPY(rgbaBackup, span->color.rgba, 4 * span->end * sizeof(GLchan)); - rgba = rgbaBackup; + _swrast_multitexture_fragments( ctx, span ); } - else { - rgba = span->color.rgba; - } - - - ASSERT(ctx->Texture._ReallyEnabled); - for (i = 0; i < texUnits; i++) - _swrast_texture_fragments( ctx, i, span, rgba ); - /* Texture with alpha test */ - if (ctx->Color.AlphaEnabled) { - /* Do the alpha test */ - if (_mesa_alpha_test( ctx, span, (const GLchan (*)[4])rgba ) == 0) { - return; - } + ASSERT(span->arrayMask & SPAN_RGBA); - /* 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, span) == GL_FALSE) - return; - } - else if (ctx->Depth.Test) { - /* regular depth testing */ - if (_mesa_depth_test_span(ctx, span) == GL_FALSE) - return; + /* Add base and specular colors */ + if (ctx->Fog.ColorSumEnabled || + (ctx->Light.Enabled && + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { + if (span->interpMask & SPAN_SPEC) { + interpolate_specular(ctx, span); } + ASSERT(span->arrayMask & SPAN_SPEC); + add_colors( span->end, span->color.rgba, span->specArray ); } - /* if we get here, something passed the depth test */ - ctx->OcclusionResult = GL_TRUE; - - - /* Add base and specular colors */ - if ((span->interpMask & SPAN_SPEC) && /* Is this right test ???*/ - (ctx->Fog.ColorSumEnabled || - (ctx->Light.Enabled && - ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR))) - add_colors(span, rgba); /* rgba = rgba + span->spec */ - /* Per-pixel fog */ if (ctx->Fog.Enabled) { - /* Is this the right 'if' ?? */ - if ((span->interpMask & SPAN_FOG) && !swrast->_PreferPixelFog) - _mesa_fog_rgba_pixels( ctx, span, rgba ); - else - _mesa_depth_fog_rgba_pixels( ctx, span, rgba ); +#if 0 + if ((span->interpMask & SPAN_FOG) && (span->arrayMask & SPAN_FOG) == 0) + interpolate_fog(ctx, span); +#endif + if ((span->arrayMask & SPAN_FOG) && !swrast->_PreferPixelFog) + _mesa_fog_rgba_pixels_with_array( ctx, span, span->fogArray, + span->color.rgba); + else if ((span->interpMask & SPAN_FOG) && !swrast->_PreferPixelFog) + _mesa_fog_rgba_pixels( ctx, span, span->color.rgba ); + else { + if ((span->interpMask & SPAN_Z) && (span->arrayMask & SPAN_Z) == 0) + interpolate_z(ctx, span); + _mesa_depth_fog_rgba_pixels(ctx, span, span->color.rgba); + } } - + /* Antialias coverage application */ if (span->arrayMask & SPAN_COVERAGE) { + GLchan (*rgba)[4] = span->color.rgba; GLuint i; for (i = 0; i < span->end; i++) { rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * span->coverage[i]); @@ -1498,325 +1182,38 @@ masked_multitexture_span( GLcontext *ctx, struct sw_span *span) if (swrast->_RasterMask & MULTI_DRAW_BIT) { multi_write_rgba_span( ctx, span->end, span->x, span->y, - (const GLchan (*)[4]) rgba, span->mask ); + (const GLchan (*)[4]) span->color.rgba, + span->mask ); } else { /* normal: write to exactly one buffer */ - const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); - if (ctx->Color.ColorLogicOpEnabled) { - _mesa_logicop_rgba_span( ctx, span->end, span->x, span->y, rgba, span->mask ); + _mesa_logicop_rgba_span( ctx, span->end, span->x, span->y, + span->color.rgba, span->mask ); } else if (ctx->Color.BlendEnabled) { - _mesa_blend_span( ctx, span->end, span->x, span->y, rgba, span->mask ); + _mesa_blend_span( ctx, span->end, span->x, span->y, + span->color.rgba, span->mask); } - if (colorMask == 0x0) { - return; - } - else if (colorMask != 0xffffffff) { - _mesa_mask_rgba_span( ctx, span->end, span->x, span->y, rgba ); + if (colorMask != 0xffffffff) { + _mesa_mask_rgba_span( ctx, span->end, span->x, span->y, + span->color.rgba ); } (*swrast->Driver.WriteRGBASpan)( ctx, span->end, span->x, span->y, - (const GLchan (*)[4])rgba, + (const GLchan (*)[4]) span->color.rgba, span->writeAll ? NULL : span->mask ); if (swrast->_RasterMask & ALPHABUF_BIT) { _mesa_write_alpha_span( ctx, span->end, span->x, span->y, - (const GLchan (*)[4])rgba, + (const GLchan (*)[4]) span->color.rgba, span->writeAll ? NULL : span->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 sw_span *span) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - MEMSET(span->mask, 1, span->end); - - if (swrast->_RasterMask & WINCLIP_BIT) { - if (clip_span(ctx, span) == GL_FALSE) { - return; - } - } - - /* Do the scissor test */ - if (ctx->Scissor.Enabled) { - if (_mesa_scissor_span( ctx, span ) == GL_FALSE) { - return; - } - } - - /* Polygon Stippling */ - if (ctx->Polygon.StippleFlag) { - stipple_polygon_span( ctx, span ); - } - - /* I have to think where to put this!! */ - if (span->interpMask & SPAN_Z) { - SW_SPAN_SET_FLAG(span->filledDepth); - - if (ctx->Visual.depthBits <= 16) { - GLuint i; - GLfixed zval = span->z; - for (i = 0; i < span->end; i++) { - span->zArray[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->end; i++) { - span->zArray[i] = zval; - zval += span->zStep; - } - } - span->arrayMask |= SPAN_Z; - } - - /* 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 (span->interpMask & SPAN_Z && !ctx->Color.AlphaEnabled) { - if (ctx->Stencil.Enabled) { - /* first stencil test */ - if (_mesa_stencil_and_ztest_span(ctx, span) == GL_FALSE) - return; - } - else if (ctx->Depth.Test) { - /* regular depth testing */ - if (_mesa_depth_test_span( ctx, span) == 0) { - return; - } - } - } - - if (span->interpMask & SPAN_RGBA) - interpolate_colors(ctx, span); - - if (span->interpMask & SPAN_SPEC) - interpolate_specular(ctx, span); - - if (span->interpMask & SPAN_INDEX) - interpolate_indexes(ctx, span); - - if (span->interpMask & SPAN_TEXTURE) - interpolate_texcoords(ctx, span); - - /* examine interpMask and call a s_span.c function */ - if (span->interpMask & SPAN_TEXTURE) { - - if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) { - /* multi texture */ - masked_multitexture_span(ctx, span); - } - else { - /* single texture */ - masked_texture_span(ctx, span); - } - } - else { - _mesa_problem(ctx, "rasterize_span() should only be used for texturing"); - } + span->arrayMask = origArrayMask; } -/* - * Add specular color to base color. This is used only when - * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR. - */ -static void -_old_add_colors(GLuint n, GLchan rgba[][4], GLchan specular[][4] ) -{ - GLuint i; - for (i = 0; i < n; i++) { -#if CHAN_TYPE == GL_FLOAT - /* no clamping */ - rgba[i][RCOMP] += specular[i][RCOMP]; - rgba[i][GCOMP] += specular[i][GCOMP]; - rgba[i][BCOMP] += specular[i][BCOMP]; -#else - GLint r = rgba[i][RCOMP] + specular[i][RCOMP]; - GLint g = rgba[i][GCOMP] + specular[i][GCOMP]; - GLint b = rgba[i][BCOMP] + specular[i][BCOMP]; - rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); - rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); - rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); -#endif - } -} - - -/* - * As above but perform multiple stages of texture application. - */ -void -_old_write_multitexture_span( GLcontext *ctx, GLuint n, GLint x, GLint y, - const GLdepth z[], const GLfloat fog[], - GLfloat texcoord[MAX_TEXTURE_UNITS][MAX_WIDTH][4], - GLfloat lambda[][MAX_WIDTH], - GLchan rgbaIn[MAX_TEXTURE_UNITS][4], - GLchan spec[MAX_TEXTURE_UNITS][4], - const GLfloat coverage[], - GLenum primitive ) -{ - GLubyte mask[MAX_WIDTH]; - GLboolean write_all = GL_TRUE; - GLchan rgbaBackup[MAX_WIDTH][4]; - GLchan (*rgba)[4]; /* points to either rgbaIn or rgbaBackup */ - GLuint i; - const GLubyte *Null = 0; - const GLuint texUnits = ctx->Const.MaxTextureUnits; - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - /* init mask to 1's (all pixels are to be written) */ - MEMSET(mask, 1, n); - - if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) { - if ((n=old_clip_span(ctx, n, x, y, mask)) == 0) { - return; - } - if (mask[0] == 0) - write_all = GL_FALSE; - } - - - if (primitive==GL_BITMAP || (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; - } - - /* Do the scissor test */ - if (ctx->Scissor.Enabled) { - if ((n = _old_scissor_span( ctx, n, x, y, mask )) == 0) { - return; - } - if (mask[0] == 0) - write_all = GL_FALSE; - } - - /* Polygon Stippling */ - if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) { - old_stipple_polygon_span( ctx, n, x, y, mask ); - write_all = GL_FALSE; - } - - /* Texture with alpha test */ - if (ctx->Color.AlphaEnabled) { - /* Texturing without alpha is done after depth-testing which - * gives a potential speed-up. - */ - ASSERT(ctx->Texture._ReallyEnabled); - for (i = 0; i < texUnits; i++) - _old_swrast_texture_fragments( ctx, i, n, texcoord[i], lambda[i], - (CONST GLchan (*)[4]) rgbaIn, rgba ); - - /* Do the alpha test */ - if (_old_alpha_test( ctx, n, (const GLchan (*)[4])rgba, mask ) == 0) { - return; - } - write_all = GL_FALSE; - } - - if (ctx->Stencil.Enabled) { - /* first stencil test */ - if (_old_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 = _old_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; - - /* Texture without alpha test */ - if (! ctx->Color.AlphaEnabled) { - ASSERT(ctx->Texture._ReallyEnabled); - for (i = 0; i < texUnits; i++) - _old_swrast_texture_fragments( ctx, i, n, texcoord[i], lambda[i], - (CONST GLchan (*)[4]) rgbaIn, rgba ); - } - - /* Add base and specular colors */ - if (spec && - (ctx->Fog.ColorSumEnabled || - (ctx->Light.Enabled && - ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR))) - _old_add_colors( n, rgba, spec ); /* rgba = rgba + spec */ - - /* Per-pixel fog */ - if (ctx->Fog.Enabled) { - if (fog && !swrast->_PreferPixelFog) - _old_fog_rgba_pixels( ctx, n, fog, rgba ); - else - _old_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 ); - } - } -} /* |