From b38ad54c41aec2d08fdd26a4a8ea4dcdca8b1dfd Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 12 Dec 2000 00:27:51 +0000 Subject: [PATCH] clipping, fog, texture optimizations (Klaus Niederkrueger) --- src/mesa/swrast/s_span.c | 283 +++++++++++++++++++++------------------ 1 file changed, 156 insertions(+), 127 deletions(-) diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 591d7d93a4c..fc2a1d66331 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.4 2000/11/14 17:40:16 brianp Exp $ */ +/* $Id: s_span.c,v 1.5 2000/12/12 00:27:51 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -58,18 +58,19 @@ static void stipple_polygon_span( GLcontext *ctx, GLuint n, GLint x, GLint y, GLubyte mask[] ) { - register GLuint i, m, stipple, highbit=0x80000000; + const GLuint highbit = 0x80000000; + GLuint i, m, stipple; stipple = ctx->PolygonStipple[y % 32]; m = highbit >> (GLuint) (x % 32); - for (i=0;i> 1; - if (m==0) { - m = 0x80000000; + if (m == 0) { + m = highbit; } } } @@ -78,41 +79,43 @@ static void stipple_polygon_span( GLcontext *ctx, /* * Clip a pixel span to the current buffer/window boundaries. - * Return: 0 = all pixels clipped - * 1 = at least one pixel is visible + * Return: 'n' such that pixel 'n', 'n+1' etc. are clipped, + * as a special case: + * 0 = all pixels clipped */ static GLuint clip_span( GLcontext *ctx, GLint n, GLint x, GLint y, GLubyte mask[] ) { - GLint i; - /* Clip to top and bottom */ if (y < 0 || y >= ctx->DrawBuffer->Height) { return 0; } - /* Clip to left and right */ - if (x >= 0 && x + n <= ctx->DrawBuffer->Width) { - /* no clipping needed */ - return 1; - } - else if (x + n <= 0) { - /* completely off left side */ - return 0; - } - else if (x >= ctx->DrawBuffer->Width) { - /* completely off right side */ - return 0; + /* Clip to the left */ + if (x < 0) { + if (x + n <= 0) { + /* completely off left side */ + return 0; + } + else { + /* partially off left side */ + MEMSET(mask, 0, -x); + } } - else { - /* clip-test each pixel, this could be done better */ - for (i=0;i= ctx->DrawBuffer->Width) { - mask[i] = 0; - } + + /* 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 1; } + + return n; } @@ -189,7 +192,7 @@ void gl_write_index_span( GLcontext *ctx, MEMSET(mask, 1, n); if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) { - if (clip_span(ctx,n,x,y,mask)==0) { + if ((n = clip_span(ctx,n,x,y,mask)) == 0) { return; } } @@ -204,17 +207,10 @@ void gl_write_index_span( GLcontext *ctx, index = indexIn; } - /* Per-pixel fog */ - if (ctx->Fog.Enabled) { - if (fog && !swrast->_PreferPixelFog) - _mesa_fog_ci_pixels( ctx, n, fog, index ); - else - _mesa_depth_fog_ci_pixels( ctx, n, z, index ); - } /* Do the scissor test */ if (ctx->Scissor.Enabled) { - if (gl_scissor_span( ctx, n, x, y, mask )==0) { + if (gl_scissor_span( ctx, n, x, y, mask ) == 0) { return; } } @@ -232,12 +228,21 @@ void gl_write_index_span( GLcontext *ctx, } else if (ctx->Depth.Test) { /* regular depth testing */ - if (_mesa_depth_test_span( ctx, n, x, y, z, mask )==0) return; + if (_mesa_depth_test_span( ctx, n, x, y, z, mask ) == 0) + return; } /* if we get here, something passed the depth test */ ctx->OcclusionResult = GL_TRUE; + /* Per-pixel fog */ + if (ctx->Fog.Enabled) { + if (fog && !swrast->_PreferPixelFog) + _mesa_fog_ci_pixels( ctx, n, fog, index ); + else + _mesa_depth_fog_ci_pixels( ctx, n, z, index ); + } + if (swrast->_RasterMask & MULTI_DRAW_BIT) { /* draw to zero or two or more buffers */ multi_write_index_span( ctx, n, x, y, index, mask ); @@ -277,14 +282,14 @@ void gl_write_monoindex_span( GLcontext *ctx, MEMSET(mask, 1, n); if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) { - if (clip_span( ctx, n, x, y, mask)==0) { + if ((n = clip_span( ctx, n, x, y, mask)) == 0) { return; } } /* Do the scissor test */ if (ctx->Scissor.Enabled) { - if (gl_scissor_span( ctx, n, x, y, mask )==0) { + if (gl_scissor_span( ctx, n, x, y, mask ) == 0) { return; } } @@ -302,7 +307,8 @@ void gl_write_monoindex_span( GLcontext *ctx, } else if (ctx->Depth.Test) { /* regular depth testing */ - if (_mesa_depth_test_span( ctx, n, x, y, z, mask )==0) return; + if (_mesa_depth_test_span( ctx, n, x, y, z, mask ) == 0) + return; } /* if we get here, something passed the depth test */ @@ -318,7 +324,7 @@ void gl_write_monoindex_span( GLcontext *ctx, || ctx->Color.IndexMask != 0xffffffff) { /* different index per pixel */ GLuint indexes[MAX_WIDTH]; - for (i=0;i_RasterMask & MULTI_DRAW_BIT) { /* draw to zero or two or more buffers */ GLuint indexes[MAX_WIDTH]; - for (i=0;i_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) { - if (clip_span( ctx,n,x,y,mask)==0) { - return; + if ((n = clip_span( ctx,n,x,y,mask)) == 0) { + return; } - write_all = GL_FALSE; + if (mask[0] == 0) + write_all = GL_FALSE; } if ((primitive==GL_BITMAP && (swrast->_RasterMask & modBits)) @@ -474,17 +481,9 @@ void gl_write_rgba_span( GLcontext *ctx, rgba = rgbaIn; } - /* 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 ); - } - /* Do the scissor test */ if (ctx->Scissor.Enabled) { - if (gl_scissor_span( ctx, n, x, y, mask )==0) { + if (gl_scissor_span( ctx, n, x, y, mask ) == 0) { return; } write_all = GL_FALSE; @@ -498,7 +497,7 @@ void gl_write_rgba_span( GLcontext *ctx, /* Do the alpha test */ if (ctx->Color.AlphaEnabled) { - if (_mesa_alpha_test( ctx, n, (const GLchan (*)[4]) rgba, mask )==0) { + if (_mesa_alpha_test( ctx, n, (const GLchan (*)[4]) rgba, mask ) == 0) { return; } write_all = GL_FALSE; @@ -514,10 +513,10 @@ void gl_write_rgba_span( GLcontext *ctx, else if (ctx->Depth.Test) { /* regular depth testing */ GLuint m = _mesa_depth_test_span( ctx, n, x, y, z, mask ); - if (m==0) { + if (m == 0) { return; } - if (mOcclusionResult = GL_TRUE; + /* 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 ); + } + if (swrast->_RasterMask & MULTI_DRAW_BIT) { multi_write_rgba_span( ctx, n, x, y, (const GLchan (*)[4]) rgba, mask ); } @@ -558,7 +565,6 @@ void gl_write_rgba_span( GLcontext *ctx, (const GLchan (*)[4]) rgba, write_all ? Null : mask ); } - } } @@ -592,15 +598,16 @@ void gl_write_monocolor_span( GLcontext *ctx, MEMSET(mask, 1, n); if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) { - if (clip_span( ctx,n,x,y,mask)==0) { + if ((n = clip_span( ctx,n,x,y,mask)) == 0) { return; } - write_all = GL_FALSE; + if (mask[0] == 0) + write_all = GL_FALSE; } /* Do the scissor test */ if (ctx->Scissor.Enabled) { - if (gl_scissor_span( ctx, n, x, y, mask )==0) { + if (gl_scissor_span( ctx, n, x, y, mask ) == 0) { return; } write_all = GL_FALSE; @@ -614,10 +621,10 @@ void gl_write_monocolor_span( GLcontext *ctx, /* Do the alpha test */ if (ctx->Color.AlphaEnabled) { - for (i=0;iDepth.Test) { /* regular depth testing */ GLuint m = _mesa_depth_test_span( ctx, n, x, y, z, mask ); - if (m==0) { + if (m == 0) { return; } - if (mColor.ColorLogicOpEnabled || colorMask != 0xffffffff || (swrast->_RasterMask & (BLEND_BIT | FOG_BIT))) { /* assign same color to each pixel */ - for (i=0;iColor.ColorLogicOpEnabled); if (swrast->_RasterMask & MULTI_DRAW_BIT) { - for (i=0;i_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) { - if (clip_span(ctx, n, x, y, mask)==0) { + if ((n=clip_span(ctx, n, x, y, mask)) == 0) { return; } - write_all = GL_FALSE; + if (mask[0] == 0) + write_all = GL_FALSE; } @@ -791,27 +799,9 @@ void gl_write_texture_span( GLcontext *ctx, rgba = rgbaIn; } - /* Texture */ - ASSERT(ctx->Texture._ReallyEnabled); - gl_texture_pixels( ctx, 0, n, s, t, u, lambda, rgba, rgba ); - - /* 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 ); - } - /* Do the scissor test */ if (ctx->Scissor.Enabled) { - if (gl_scissor_span( ctx, n, x, y, mask )==0) { + if (gl_scissor_span( ctx, n, x, y, mask ) == 0) { return; } write_all = GL_FALSE; @@ -822,11 +812,17 @@ void gl_write_texture_span( GLcontext *ctx, stipple_polygon_span( ctx, n, x, y, mask ); write_all = GL_FALSE; } - - /* Do the alpha test */ + + /* Texture with alpha test*/ if (ctx->Color.AlphaEnabled) { - if (_mesa_alpha_test( ctx, n, (const GLchan (*)[4]) rgba, mask )==0) { - return; + /* Texturing without alpha is done after depth-testing which + gives a potential speed-up. */ + ASSERT(ctx->Texture._ReallyEnabled); + gl_texture_pixels( ctx, 0, n, s, t, u, lambda, rgba, rgba ); + + /* Do the alpha test */ + if (_mesa_alpha_test( ctx, n, (const GLchan (*)[4]) rgba, mask ) == 0) { + return; } write_all = GL_FALSE; } @@ -841,10 +837,10 @@ void gl_write_texture_span( GLcontext *ctx, else if (ctx->Depth.Test) { /* regular depth testing */ GLuint m = _mesa_depth_test_span( ctx, n, x, y, z, mask ); - if (m==0) { + if (m == 0) { return; } - if (mOcclusionResult = GL_TRUE; + /* Texture without alpha test */ + if (! ctx->Color.AlphaEnabled) { + ASSERT(ctx->Texture._ReallyEnabled); + gl_texture_pixels( ctx, 0, n, s, t, u, lambda, rgba, rgba ); + } + + /* 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 ); + } + if (swrast->_RasterMask & MULTI_DRAW_BIT) { multi_write_rgba_span( ctx, n, x, y, (const GLchan (*)[4]) rgba, mask ); } @@ -910,10 +926,11 @@ gl_write_multitexture_span( GLcontext *ctx, MEMSET(mask, 1, n); if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) { - if (clip_span(ctx, n, x, y, mask)==0) { + if ((n=clip_span(ctx, n, x, y, mask)) == 0) { return; } - write_all = GL_FALSE; + if (mask[0] == 0) + write_all = GL_FALSE; } @@ -927,29 +944,9 @@ gl_write_multitexture_span( GLcontext *ctx, rgba = rgbaIn; } - /* Texture */ - ASSERT(ctx->Texture._ReallyEnabled); - for (i = 0; i < texUnits; i++) - gl_texture_pixels( ctx, i, n, s[i], t[i], u[i], lambda[i], rgbaIn, rgba ); - - /* 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 ); - } - /* Do the scissor test */ if (ctx->Scissor.Enabled) { - if (gl_scissor_span( ctx, n, x, y, mask )==0) { + if (gl_scissor_span( ctx, n, x, y, mask ) == 0) { return; } write_all = GL_FALSE; @@ -961,10 +958,18 @@ gl_write_multitexture_span( GLcontext *ctx, write_all = GL_FALSE; } - /* Do the alpha test */ + /* Texture with alpha test*/ if (ctx->Color.AlphaEnabled) { - if (_mesa_alpha_test( ctx, n, (const GLchan (*)[4])rgba, mask )==0) { - return; + /* Texturing without alpha is done after depth-testing which + * gives a potential speed-up. + */ + ASSERT(ctx->Texture._ReallyEnabled); + for (i = 0; i < texUnits; i++) + gl_texture_pixels( ctx, i, n, s[i], t[i], u[i], lambda[i], rgbaIn, rgba ); + + /* Do the alpha test */ + if (_mesa_alpha_test( ctx, n, (const GLchan (*)[4])rgba, mask ) == 0) { + return; } write_all = GL_FALSE; } @@ -979,10 +984,10 @@ gl_write_multitexture_span( GLcontext *ctx, else if (ctx->Depth.Test) { /* regular depth testing */ GLuint m = _mesa_depth_test_span( ctx, n, x, y, z, mask ); - if (m==0) { + if (m == 0) { return; } - if (mOcclusionResult = GL_TRUE; + /* Texture without alpha test */ + if (! ctx->Color.AlphaEnabled) { + ASSERT(ctx->Texture._ReallyEnabled); + for (i = 0; i < texUnits; i++) + gl_texture_pixels( ctx, i, n, s[i], t[i], u[i], + lambda[i], rgbaIn, rgba ); + } + + /* 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 ); + } + if (swrast->_RasterMask & MULTI_DRAW_BIT) { multi_write_rgba_span( ctx, n, x, y, (const GLchan (*)[4]) rgba, mask ); } @@ -1011,7 +1039,8 @@ gl_write_multitexture_span( GLcontext *ctx, _mesa_mask_rgba_span( ctx, n, x, y, rgba ); } - (*ctx->Driver.WriteRGBASpan)( ctx, n, x, y, (const GLchan (*)[4])rgba, write_all ? Null : mask ); + (*ctx->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 ); -- 2.30.2