X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fswrast%2Fs_span.c;h=41db42e2b80726689fe1b1fdf39acdb224fab2f3;hb=1a544b0500ebacb52a7412ad17c4a2002a00ff94;hp=e65d19c9d31785e9cb2a38ac86da376097a1bea4;hpb=6a98bef96189fbacc326ad9e407c1d4423aa8572;p=mesa.git diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index e65d19c9d31..41db42e2b80 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1,10 +1,8 @@ -/* $Id: s_span.c,v 1.55 2003/02/27 18:15:18 brianp Exp $ */ - /* * Mesa 3-D graphics library - * Version: 5.0.1 + * Version: 6.1 * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2004 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"), @@ -36,7 +34,6 @@ #include "colormac.h" #include "context.h" #include "macros.h" -#include "mmath.h" #include "imports.h" #include "s_alpha.h" @@ -58,7 +55,7 @@ * Used during setup for glDraw/CopyPixels. */ void -_mesa_span_default_z( GLcontext *ctx, struct sw_span *span ) +_swrast_span_default_z( GLcontext *ctx, struct sw_span *span ) { if (ctx->Visual.depthBits <= 16) span->z = FloatToFixed(ctx->Current.RasterPos[2] * ctx->DepthMax + 0.5F); @@ -74,10 +71,10 @@ _mesa_span_default_z( GLcontext *ctx, struct sw_span *span ) * Used during setup for glDraw/CopyPixels. */ void -_mesa_span_default_fog( GLcontext *ctx, struct sw_span *span ) +_swrast_span_default_fog( GLcontext *ctx, struct sw_span *span ) { - span->fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance); - span->fogStep = 0; + span->fog = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); + span->fogStep = span->dfogdx = span->dfogdy = 0.0F; span->interpMask |= SPAN_FOG; } @@ -87,7 +84,7 @@ _mesa_span_default_fog( GLcontext *ctx, struct sw_span *span ) * Used during setup for glDraw/CopyPixels. */ void -_mesa_span_default_color( GLcontext *ctx, struct sw_span *span ) +_swrast_span_default_color( GLcontext *ctx, struct sw_span *span ) { if (ctx->Visual.rgbMode) { GLchan r, g, b, a; @@ -113,7 +110,7 @@ _mesa_span_default_color( GLcontext *ctx, struct sw_span *span ) span->interpMask |= SPAN_RGBA; } else { - span->index = IntToFixed(ctx->Current.RasterIndex); + span->index = FloatToFixed(ctx->Current.RasterIndex); span->indexStep = 0; span->interpMask |= SPAN_INDEX; } @@ -125,11 +122,21 @@ _mesa_span_default_color( GLcontext *ctx, struct sw_span *span ) * Used during setup for glDraw/CopyPixels. */ void -_mesa_span_default_texcoords( GLcontext *ctx, struct sw_span *span ) +_swrast_span_default_texcoords( GLcontext *ctx, struct sw_span *span ) { GLuint i; for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - COPY_4V(span->tex[i], ctx->Current.RasterTexCoords[i]); + const GLfloat *tc = ctx->Current.RasterTexCoords[i]; + if (tc[3] > 0.0F) { + /* use (s/q, t/q, r/q, 1) */ + span->tex[i][0] = tc[0] / tc[3]; + span->tex[i][1] = tc[1] / tc[3]; + span->tex[i][2] = tc[2] / tc[3]; + span->tex[i][3] = 1.0; + } + else { + ASSIGN_4V(span->tex[i], 0.0F, 0.0F, 0.0F, 1.0F); + } ASSIGN_4V(span->texStepX[i], 0.0F, 0.0F, 0.0F, 0.0F); ASSIGN_4V(span->texStepY[i], 0.0F, 0.0F, 0.0F, 0.0F); } @@ -268,7 +275,7 @@ interpolate_specular(GLcontext *ctx, struct sw_span *span) /* Fill in the span.zArray array from the interpolation values */ void -_mesa_span_interpolate_z( const GLcontext *ctx, struct sw_span *span ) +_swrast_span_interpolate_z( const GLcontext *ctx, struct sw_span *span ) { const GLuint n = span->end; GLuint i; @@ -310,8 +317,8 @@ compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ); GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ); GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ); - GLfloat x = sqrt(dudx * dudx + dvdx * dvdx); - GLfloat y = sqrt(dudy * dudy + dvdy * dvdy); + GLfloat x = SQRTF(dudx * dudx + dvdx * dvdx); + GLfloat y = SQRTF(dudy * dudy + dvdy * dvdy); GLfloat rho = MAX2(x, y); GLfloat lambda = LOG2(rho); return lambda; @@ -322,10 +329,10 @@ compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, /* * This is a faster approximation */ -static GLfloat -compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, - GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, - GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) +GLfloat +_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, + GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, + GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) { GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ; GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ; @@ -343,10 +350,16 @@ compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, return lambda; } -/* + +/** * Fill in the span.texcoords array from the interpolation values. - * XXX We could optimize here for the case when dq = 0. That would - * usually be the case when using an orthographic projection. + * Note: in the places where we divide by Q (or mult by invQ) we're + * really doing two things: perspective correction and texcoord + * projection. Remember, for texcoord (s,t,r,q) we need to index + * texels with (s/q, t/q, r/q). + * If we're using a fragment program, we never do the division + * for texcoord projection. That's done by the TXP instruction + * or user-written code. */ static void interpolate_texcoords(GLcontext *ctx, struct sw_span *span) @@ -354,20 +367,31 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) ASSERT(span->interpMask & SPAN_TEXTURE); ASSERT(!(span->arrayMask & SPAN_TEXTURE)); - if (ctx->Texture._EnabledUnits > 1) { + if (ctx->Texture._EnabledCoordUnits > 1) { /* multitexture */ GLuint u; span->arrayMask |= SPAN_TEXTURE; for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { + if (ctx->Texture._EnabledCoordUnits & (1 << u)) { const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current; - const struct gl_texture_image *img = obj->Image[obj->BaseLevel]; - GLboolean needLambda = (obj->MinFilter != obj->MagFilter); + GLfloat texW, texH; + GLboolean needLambda; + if (obj) { + const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; + needLambda = (obj->MinFilter != obj->MagFilter) + || ctx->FragmentProgram._Enabled; + texW = img->WidthScale; + texH = img->HeightScale; + } + else { + /* using a fragment program */ + texW = 1.0; + texH = 1.0; + needLambda = GL_FALSE; + } if (needLambda) { GLfloat (*texcoord)[4] = span->array->texcoords[u]; GLfloat *lambda = span->array->lambda[u]; - const GLfloat texW = (GLfloat) img->WidthScale; - const GLfloat texH = (GLfloat) img->HeightScale; const GLfloat dsdx = span->texStepX[u][0]; const GLfloat dsdy = span->texStepY[u][0]; const GLfloat dtdx = span->texStepX[u][1]; @@ -380,18 +404,42 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) GLfloat r = span->tex[u][2]; GLfloat q = span->tex[u][3]; GLuint i; - for (i = 0; i < span->end; i++) { - const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - texcoord[i][0] = s * invQ; - texcoord[i][1] = t * invQ; - texcoord[i][2] = r * invQ; - lambda[i] = compute_lambda(dsdx, dsdy, dtdx, dtdy, - dqdx, dqdy, texW, texH, - s, t, q, invQ); - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; + if (ctx->FragmentProgram._Enabled) { + /* do perspective correction but don't divide s, t, r by q */ + const GLfloat dwdx = span->dwdx; + GLfloat w = span->w; + for (i = 0; i < span->end; i++) { + const GLfloat invW = 1.0F / w; + texcoord[i][0] = s * invW; + texcoord[i][1] = t * invW; + texcoord[i][2] = r * invW; + texcoord[i][3] = q * invW; + lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, + dqdx, dqdy, texW, texH, + s, t, q, invW); + s += dsdx; + t += dtdx; + r += drdx; + q += dqdx; + w += dwdx; + } + + } + else { + for (i = 0; i < span->end; i++) { + const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); + texcoord[i][0] = s * invQ; + texcoord[i][1] = t * invQ; + texcoord[i][2] = r * invQ; + texcoord[i][3] = q; + lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, + dqdx, dqdy, texW, texH, + s, t, q, invQ); + s += dsdx; + t += dtdx; + r += drdx; + q += dqdx; + } } span->arrayMask |= SPAN_LAMBDA; } @@ -407,13 +455,32 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) GLfloat r = span->tex[u][2]; GLfloat q = span->tex[u][3]; GLuint i; - if (dqdx == 0.0) { + if (ctx->FragmentProgram._Enabled) { + /* do perspective correction but don't divide s, t, r by q */ + const GLfloat dwdx = span->dwdx; + GLfloat w = span->w; + for (i = 0; i < span->end; i++) { + const GLfloat invW = 1.0F / w; + texcoord[i][0] = s * invW; + texcoord[i][1] = t * invW; + texcoord[i][2] = r * invW; + texcoord[i][3] = q * invW; + lambda[i] = 0.0; + s += dsdx; + t += dtdx; + r += drdx; + q += dqdx; + w += dwdx; + } + } + else if (dqdx == 0.0F) { /* Ortho projection or polygon's parallel to window X axis */ const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); for (i = 0; i < span->end; i++) { texcoord[i][0] = s * invQ; texcoord[i][1] = t * invQ; texcoord[i][2] = r * invQ; + texcoord[i][3] = q; lambda[i] = 0.0; s += dsdx; t += dtdx; @@ -426,6 +493,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) texcoord[i][0] = s * invQ; texcoord[i][1] = t * invQ; texcoord[i][2] = r * invQ; + texcoord[i][3] = q; lambda[i] = 0.0; s += dsdx; t += dtdx; @@ -440,15 +508,24 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) else { /* single texture */ const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; - const struct gl_texture_image *img = obj->Image[obj->BaseLevel]; - GLboolean needLambda = (obj->MinFilter != obj->MagFilter); + GLfloat texW, texH; + GLboolean needLambda; + if (obj) { + const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; + needLambda = (obj->MinFilter != obj->MagFilter) + || ctx->FragmentProgram._Enabled; + texW = (GLfloat) img->WidthScale; + texH = (GLfloat) img->HeightScale; + } + else { + needLambda = GL_FALSE; + texW = texH = 1.0; + } span->arrayMask |= SPAN_TEXTURE; if (needLambda) { /* just texture unit 0, with lambda */ GLfloat (*texcoord)[4] = span->array->texcoords[0]; GLfloat *lambda = span->array->lambda[0]; - const GLfloat texW = (GLfloat) img->WidthScale; - const GLfloat texH = (GLfloat) img->HeightScale; const GLfloat dsdx = span->texStepX[0][0]; const GLfloat dsdy = span->texStepY[0][0]; const GLfloat dtdx = span->texStepX[0][1]; @@ -461,18 +538,42 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) GLfloat r = span->tex[0][2]; GLfloat q = span->tex[0][3]; GLuint i; - for (i = 0; i < span->end; i++) { - const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - lambda[i] = compute_lambda(dsdx, dsdy, dtdx, dtdy, - dqdx, dqdy, texW, texH, - s, t, q, invQ); - texcoord[i][0] = s * invQ; - texcoord[i][1] = t * invQ; - texcoord[i][2] = r * invQ; - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; + if (ctx->FragmentProgram._Enabled) { + /* do perspective correction but don't divide s, t, r by q */ + const GLfloat dwdx = span->dwdx; + GLfloat w = span->w; + for (i = 0; i < span->end; i++) { + const GLfloat invW = 1.0F / w; + texcoord[i][0] = s * invW; + texcoord[i][1] = t * invW; + texcoord[i][2] = r * invW; + texcoord[i][3] = q * invW; + lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, + dqdx, dqdy, texW, texH, + s, t, q, invW); + s += dsdx; + t += dtdx; + r += drdx; + q += dqdx; + w += dwdx; + } + } + else { + /* tex.c */ + for (i = 0; i < span->end; i++) { + const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); + lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, + dqdx, dqdy, texW, texH, + s, t, q, invQ); + texcoord[i][0] = s * invQ; + texcoord[i][1] = t * invQ; + texcoord[i][2] = r * invQ; + texcoord[i][3] = q; + s += dsdx; + t += dtdx; + r += drdx; + q += dqdx; + } } span->arrayMask |= SPAN_LAMBDA; } @@ -488,13 +589,31 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) GLfloat r = span->tex[0][2]; GLfloat q = span->tex[0][3]; GLuint i; - if (dqdx == 0.0) { + if (ctx->FragmentProgram._Enabled) { + /* do perspective correction but don't divide s, t, r by q */ + const GLfloat dwdx = span->dwdx; + GLfloat w = span->w; + for (i = 0; i < span->end; i++) { + const GLfloat invW = 1.0F / w; + texcoord[i][0] = s * invW; + texcoord[i][1] = t * invW; + texcoord[i][2] = r * invW; + texcoord[i][3] = q * invW; + s += dsdx; + t += dtdx; + r += drdx; + q += dqdx; + w += dwdx; + } + } + else if (dqdx == 0.0F) { /* Ortho projection or polygon's parallel to window X axis */ const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); for (i = 0; i < span->end; i++) { texcoord[i][0] = s * invQ; texcoord[i][1] = t * invQ; texcoord[i][2] = r * invQ; + texcoord[i][3] = q; s += dsdx; t += dtdx; r += drdx; @@ -506,6 +625,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span) texcoord[i][0] = s * invQ; texcoord[i][1] = t * invQ; texcoord[i][2] = r * invQ; + texcoord[i][3] = q; s += dsdx; t += dtdx; r += drdx; @@ -631,18 +751,18 @@ multi_write_index_span( GLcontext *ctx, struct sw_span *span ) ASSERT(span->end < MAX_WIDTH); /* Set the current read/draw buffer */ - swrast->CurrentBuffer = bufferBit; + swrast->CurrentBufferBit = bufferBit; (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit); /* make copy of incoming indexes */ MEMCPY( indexTmp, span->array->index, span->end * sizeof(GLuint) ); if (ctx->Color.IndexLogicOpEnabled) { - _mesa_logicop_ci_span(ctx, span, indexTmp); + _swrast_logicop_ci_span(ctx, span, indexTmp); } if (ctx->Color.IndexMask != 0xffffffff) { - _mesa_mask_index_span(ctx, span, indexTmp); + _swrast_mask_index_span(ctx, span, indexTmp); } if (span->arrayMask & SPAN_XY) { @@ -688,21 +808,21 @@ multi_write_rgba_span( GLcontext *ctx, struct sw_span *span ) ASSERT(span->end < MAX_WIDTH); /* Set the current read/draw buffer */ - swrast->CurrentBuffer = bufferBit; + swrast->CurrentBufferBit = bufferBit; (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit); /* make copy of incoming colors */ MEMCPY( rgbaTmp, span->array->rgba, 4 * span->end * sizeof(GLchan) ); - if (ctx->Color.ColorLogicOpEnabled) { - _mesa_logicop_rgba_span(ctx, span, rgbaTmp); + if (ctx->Color._LogicOpEnabled) { + _swrast_logicop_rgba_span(ctx, span, rgbaTmp); } else if (ctx->Color.BlendEnabled) { - _mesa_blend_span(ctx, span, rgbaTmp); + _swrast_blend_span(ctx, span, rgbaTmp); } if (colorMask != 0xffffffff) { - _mesa_mask_rgba_span(ctx, span, rgbaTmp); + _swrast_mask_rgba_span(ctx, span, rgbaTmp); } if (span->arrayMask & SPAN_XY) { @@ -712,7 +832,7 @@ multi_write_rgba_span( GLcontext *ctx, struct sw_span *span ) (const GLchan (*)[4]) rgbaTmp, span->array->mask); if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { - _mesa_write_alpha_pixels(ctx, span->end, + _swrast_write_alpha_pixels(ctx, span->end, span->array->x, span->array->y, (const GLchan (*)[4]) rgbaTmp, span->array->mask); @@ -724,7 +844,7 @@ multi_write_rgba_span( GLcontext *ctx, struct sw_span *span ) (const GLchan (*)[4]) rgbaTmp, span->array->mask); if (swrast->_RasterMask & ALPHABUF_BIT) { - _mesa_write_alpha_span(ctx, span->end, span->x, span->y, + _swrast_write_alpha_span(ctx, span->end, span->x, span->y, (const GLchan (*)[4]) rgbaTmp, span->array->mask); } @@ -744,7 +864,7 @@ multi_write_rgba_span( GLcontext *ctx, struct sw_span *span ) * to their original values before returning. */ void -_mesa_write_index_span( GLcontext *ctx, struct sw_span *span) +_swrast_write_index_span( GLcontext *ctx, struct sw_span *span) { SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLuint origInterpMask = span->interpMask; @@ -772,6 +892,13 @@ _mesa_write_index_span( GLcontext *ctx, struct sw_span *span) } } + /* Depth bounds test */ + if (ctx->Depth.BoundsTest && ctx->Visual.depthBits > 0) { + if (!_swrast_depth_bounds_test(ctx, span)) { + return; + } + } + #ifdef DEBUG if (span->arrayMask & SPAN_XY) { GLuint i; @@ -794,17 +921,17 @@ _mesa_write_index_span( GLcontext *ctx, struct sw_span *span) /* Depth test and stencil */ if (ctx->Depth.Test || ctx->Stencil.Enabled) { if (span->interpMask & SPAN_Z) - _mesa_span_interpolate_z(ctx, span); + _swrast_span_interpolate_z(ctx, span); if (ctx->Stencil.Enabled) { - if (!_mesa_stencil_and_ztest_span(ctx, span)) { + if (!_swrast_stencil_and_ztest_span(ctx, span)) { span->arrayMask = origArrayMask; return; } } else { ASSERT(ctx->Depth.Test); - if (!_mesa_depth_test_span(ctx, span)) { + if (!_swrast_depth_test_span(ctx, span)) { span->arrayMask = origArrayMask; return; } @@ -814,6 +941,14 @@ _mesa_write_index_span( GLcontext *ctx, struct sw_span *span) /* if we get here, something passed the depth test */ ctx->OcclusionResult = GL_TRUE; +#if FEATURE_ARB_occlusion_query + if (ctx->Occlusion.Active) { + GLuint i; + for (i = 0; i < span->end; i++) + ctx->Occlusion.PassedCounter += span->array->mask[i]; + } +#endif + /* we have to wait until after occlusion to do this test */ if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) { /* write no pixels */ @@ -830,7 +965,7 @@ _mesa_write_index_span( GLcontext *ctx, struct sw_span *span) /* Fog */ if (ctx->Fog.Enabled) { - _mesa_fog_ci_span(ctx, span); + _swrast_fog_ci_span(ctx, span); } /* Antialias coverage application */ @@ -851,11 +986,11 @@ _mesa_write_index_span( GLcontext *ctx, struct sw_span *span) else { /* normal situation: draw to exactly one buffer */ if (ctx->Color.IndexLogicOpEnabled) { - _mesa_logicop_ci_span(ctx, span, span->array->index); + _swrast_logicop_ci_span(ctx, span, span->array->index); } if (ctx->Color.IndexMask != 0xffffffff) { - _mesa_mask_index_span(ctx, span, span->array->index); + _swrast_mask_index_span(ctx, span, span->array->index); } /* write pixels */ @@ -901,7 +1036,7 @@ _mesa_write_index_span( GLcontext *ctx, struct sw_span *span) * to their original values before returning. */ void -_mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span) +_swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span) { SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); @@ -942,6 +1077,13 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span) } } + /* Depth bounds test */ + if (ctx->Depth.BoundsTest && ctx->Visual.depthBits > 0) { + if (!_swrast_depth_bounds_test(ctx, span)) { + return; + } + } + #ifdef DEBUG if (span->arrayMask & SPAN_XY) { GLuint i; @@ -962,20 +1104,26 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span) } /* Fragment program */ - if (ctx->FragmentProgram.Enabled) { - /* Now we may need to interpolate the colors */ + if (ctx->FragmentProgram._Enabled) { + /* Now we may need to interpolate the colors and texcoords */ if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) { interpolate_colors(ctx, span); span->interpMask &= ~SPAN_RGBA; } - _swrast_exec_nv_fragment_program(ctx, span); + if (span->interpMask & SPAN_SPEC) { + interpolate_specular(ctx, span); + } + if ((span->interpMask & SPAN_TEXTURE) + && (span->arrayMask & SPAN_TEXTURE) == 0) + interpolate_texcoords(ctx, span); + _swrast_exec_fragment_program(ctx, span); monoColor = GL_FALSE; } /* Do the alpha test */ if (ctx->Color.AlphaEnabled) { - if (!_mesa_alpha_test(ctx, span)) { + if (!_swrast_alpha_test(ctx, span)) { span->interpMask = origInterpMask; span->arrayMask = origArrayMask; return; @@ -985,10 +1133,10 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span) /* Stencil and Z testing */ if (ctx->Stencil.Enabled || ctx->Depth.Test) { if (span->interpMask & SPAN_Z) - _mesa_span_interpolate_z(ctx, span); + _swrast_span_interpolate_z(ctx, span); if (ctx->Stencil.Enabled) { - if (!_mesa_stencil_and_ztest_span(ctx, span)) { + if (!_swrast_stencil_and_ztest_span(ctx, span)) { span->interpMask = origInterpMask; span->arrayMask = origArrayMask; return; @@ -998,7 +1146,7 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span) ASSERT(ctx->Depth.Test); ASSERT(span->arrayMask & SPAN_Z); /* regular depth testing */ - if (!_mesa_depth_test_span(ctx, span)) { + if (!_swrast_depth_test_span(ctx, span)) { span->interpMask = origInterpMask; span->arrayMask = origArrayMask; return; @@ -1009,6 +1157,14 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span) /* if we get here, something passed the depth test */ ctx->OcclusionResult = GL_TRUE; +#if FEATURE_ARB_occlusion_query + if (ctx->Occlusion.Active) { + GLuint i; + for (i = 0; i < span->end; i++) + ctx->Occlusion.PassedCounter += span->array->mask[i]; + } +#endif + /* can't abort span-writing until after occlusion testing */ if (colorMask == 0x0) { span->interpMask = origInterpMask; @@ -1024,8 +1180,8 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span) } /* Fog */ - if (ctx->Fog.Enabled) { - _mesa_fog_rgba_span(ctx, span); + if (swrast->_FogEnabled) { + _swrast_fog_rgba_span(ctx, span); monoColor = GL_FALSE; } @@ -1045,32 +1201,50 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span) } else { /* normal: write to exactly one buffer */ - if (ctx->Color.ColorLogicOpEnabled) { - _mesa_logicop_rgba_span(ctx, span, span->array->rgba); + if (ctx->Color._LogicOpEnabled) { + _swrast_logicop_rgba_span(ctx, span, span->array->rgba); monoColor = GL_FALSE; } else if (ctx->Color.BlendEnabled) { - _mesa_blend_span(ctx, span, span->array->rgba); + _swrast_blend_span(ctx, span, span->array->rgba); monoColor = GL_FALSE; } /* Color component masking */ if (colorMask != 0xffffffff) { - _mesa_mask_rgba_span(ctx, span, span->array->rgba); + _swrast_mask_rgba_span(ctx, span, span->array->rgba); monoColor = GL_FALSE; } /* write pixels */ if (span->arrayMask & SPAN_XY) { /* array of pixel coords */ - /* XXX test for mono color */ - (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->array->x, - span->array->y, (const GLchan (*)[4]) span->array->rgba, span->array->mask); - if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { - _mesa_write_alpha_pixels(ctx, span->end, - span->array->x, span->array->y, - (const GLchan (*)[4]) span->array->rgba, - span->array->mask); + if (monoColor) { + /* all pixels have same color */ + GLchan color[4]; + color[RCOMP] = FixedToChan(span->red); + color[GCOMP] = FixedToChan(span->green); + color[BCOMP] = FixedToChan(span->blue); + color[ACOMP] = FixedToChan(span->alpha); + (*swrast->Driver.WriteMonoRGBAPixels)(ctx, span->end, + span->array->x, span->array->y, color, span->array->mask); + if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { + _swrast_write_mono_alpha_pixels(ctx, span->end, + span->array->x, span->array->y, + color[ACOMP], span->array->mask); + } + } + else { + (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, + span->array->x, span->array->y, + (const GLchan (*)[4]) span->array->rgba, + span->array->mask); + if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { + _swrast_write_alpha_pixels(ctx, span->end, + span->array->x, span->array->y, + (const GLchan (*)[4]) span->array->rgba, + span->array->mask); + } } } else { @@ -1083,9 +1257,9 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span) color[BCOMP] = FixedToChan(span->blue); color[ACOMP] = FixedToChan(span->alpha); (*swrast->Driver.WriteMonoRGBASpan)(ctx, span->end, span->x, - span->y, color, span->array->mask); + span->y, color, span->array->mask); if (swrast->_RasterMask & ALPHABUF_BIT) { - _mesa_write_mono_alpha_span(ctx, span->end, span->x, span->y, + _swrast_write_mono_alpha_span(ctx, span->end, span->x, span->y, color[ACOMP], span->writeAll ? ((const GLubyte *) NULL) : span->array->mask); } @@ -1096,7 +1270,7 @@ _mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span) (const GLchan (*)[4]) span->array->rgba, span->writeAll ? ((const GLubyte *) NULL) : span->array->mask); if (swrast->_RasterMask & ALPHABUF_BIT) { - _mesa_write_alpha_span(ctx, span->end, span->x, span->y, + _swrast_write_alpha_span(ctx, span->end, span->x, span->y, (const GLchan (*)[4]) span->array->rgba, span->writeAll ? ((const GLubyte *) NULL) : span->array->mask); } @@ -1141,17 +1315,18 @@ add_colors(GLuint n, GLchan rgba[][4], GLchan specular[][4] ) * to their original values before returning. */ void -_mesa_write_texture_span( GLcontext *ctx, struct sw_span *span) +_swrast_write_texture_span( GLcontext *ctx, struct sw_span *span) { const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); SWcontext *swrast = SWRAST_CONTEXT(ctx); + const GLuint origInterpMask = span->interpMask; const GLuint origArrayMask = span->arrayMask; ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE || span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); ASSERT(span->end <= MAX_WIDTH); ASSERT((span->interpMask & span->arrayMask) == 0); - ASSERT(ctx->Texture._EnabledUnits); + ASSERT(ctx->Texture._EnabledCoordUnits || ctx->FragmentProgram._Enabled); /* printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask); @@ -1204,16 +1379,20 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span) if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) interpolate_colors(ctx, span); + if (span->interpMask & SPAN_SPEC) { + interpolate_specular(ctx, span); + } + /* Texturing without alpha is done after depth-testing which * gives a potential speed-up. */ - if (ctx->FragmentProgram.Enabled) - _swrast_exec_nv_fragment_program( ctx, span ); + if (ctx->FragmentProgram._Enabled) + _swrast_exec_fragment_program( ctx, span ); else _swrast_texture_span( ctx, span ); /* Do the alpha test */ - if (!_mesa_alpha_test(ctx, span)) { + if (!_swrast_alpha_test(ctx, span)) { span->arrayMask = origArrayMask; return; } @@ -1222,10 +1401,11 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span) /* Stencil and Z testing */ if (ctx->Stencil.Enabled || ctx->Depth.Test) { if (span->interpMask & SPAN_Z) - _mesa_span_interpolate_z(ctx, span); + _swrast_span_interpolate_z(ctx, span); if (ctx->Stencil.Enabled) { - if (!_mesa_stencil_and_ztest_span(ctx, span)) { + if (!_swrast_stencil_and_ztest_span(ctx, span)) { + span->interpMask = origInterpMask; span->arrayMask = origArrayMask; return; } @@ -1234,7 +1414,8 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span) ASSERT(ctx->Depth.Test); ASSERT(span->arrayMask & SPAN_Z); /* regular depth testing */ - if (!_mesa_depth_test_span(ctx, span)) { + if (!_swrast_depth_test_span(ctx, span)) { + span->interpMask = origInterpMask; span->arrayMask = origArrayMask; return; } @@ -1244,10 +1425,19 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span) /* if we get here, some fragments passed the depth test */ ctx->OcclusionResult = GL_TRUE; +#if FEATURE_ARB_occlusion_query + if (ctx->Occlusion.Active) { + GLuint i; + for (i = 0; i < span->end; i++) + ctx->Occlusion.PassedCounter += span->array->mask[i]; + } +#endif + /* We had to wait until now to check for glColorMask(F,F,F,F) because of * the occlusion test. */ if (colorMask == 0x0) { + span->interpMask = origInterpMask; span->arrayMask = origArrayMask; return; } @@ -1259,8 +1449,12 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span) if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) interpolate_colors(ctx, span); - if (ctx->FragmentProgram.Enabled) - _swrast_exec_nv_fragment_program( ctx, span ); + if (span->interpMask & SPAN_SPEC) { + interpolate_specular(ctx, span); + } + + if (ctx->FragmentProgram._Enabled) + _swrast_exec_fragment_program( ctx, span ); else _swrast_texture_span( ctx, span ); } @@ -1279,8 +1473,8 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span) } /* Fog */ - if (ctx->Fog.Enabled) { - _mesa_fog_rgba_span(ctx, span); + if (swrast->_FogEnabled) { + _swrast_fog_rgba_span(ctx, span); } /* Antialias coverage application */ @@ -1298,24 +1492,25 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span) } else { /* normal: write to exactly one buffer */ - if (ctx->Color.ColorLogicOpEnabled) { - _mesa_logicop_rgba_span(ctx, span, span->array->rgba); + if (ctx->Color._LogicOpEnabled) { + _swrast_logicop_rgba_span(ctx, span, span->array->rgba); } else if (ctx->Color.BlendEnabled) { - _mesa_blend_span(ctx, span, span->array->rgba); + _swrast_blend_span(ctx, span, span->array->rgba); } + /* Color component masking */ if (colorMask != 0xffffffff) { - _mesa_mask_rgba_span(ctx, span, span->array->rgba); + _swrast_mask_rgba_span(ctx, span, span->array->rgba); } - + /* write pixels */ if (span->arrayMask & SPAN_XY) { /* array of pixel coords */ (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->array->x, span->array->y, (const GLchan (*)[4]) span->array->rgba, span->array->mask); if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { - _mesa_write_alpha_pixels(ctx, span->end, + _swrast_write_alpha_pixels(ctx, span->end, span->array->x, span->array->y, (const GLchan (*)[4]) span->array->rgba, span->array->mask); @@ -1327,13 +1522,14 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span) (const GLchan (*)[4]) span->array->rgba, span->writeAll ? NULL : span->array->mask); if (swrast->_RasterMask & ALPHABUF_BIT) { - _mesa_write_alpha_span(ctx, span->end, span->x, span->y, + _swrast_write_alpha_span(ctx, span->end, span->x, span->y, (const GLchan (*)[4]) span->array->rgba, span->writeAll ? NULL : span->array->mask); } } } + span->interpMask = origInterpMask; span->arrayMask = origArrayMask; } @@ -1344,7 +1540,7 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span) * reading ouside the buffer's boundaries. */ void -_mesa_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer, +_swrast_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer, GLuint n, GLint x, GLint y, GLchan rgba[][4] ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); @@ -1387,7 +1583,7 @@ _mesa_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer, (*swrast->Driver.ReadRGBASpan)( ctx, length, x + skip, y, rgba + skip ); if (buffer->UseSoftwareAlphaBuffers) { - _mesa_read_alpha_span(ctx, length, x + skip, y, rgba + skip); + _swrast_read_alpha_span(ctx, length, x + skip, y, rgba + skip); } } } @@ -1398,7 +1594,7 @@ _mesa_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer, * reading ouside the buffer's boundaries. */ void -_mesa_read_index_span( GLcontext *ctx, GLframebuffer *buffer, +_swrast_read_index_span( GLcontext *ctx, GLframebuffer *buffer, GLuint n, GLint x, GLint y, GLuint indx[] ) { SWcontext *swrast = SWRAST_CONTEXT(ctx);