X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fswrast%2Fs_tritemp.h;h=435491a0c80e7c036c52f5dceca48ac70b1cf928;hb=1dca0891492dc5d2974239f04883a41a1738d91f;hp=32c0f107e3f5763e38c61b2f19c73fc94d24823d;hpb=3c84ab90f23df09d3114ae0b78cbc65658d5931c;p=mesa.git diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h index 32c0f107e3f..435491a0c80 100644 --- a/src/mesa/swrast/s_tritemp.h +++ b/src/mesa/swrast/s_tritemp.h @@ -1,21 +1,19 @@ -/* $Id: s_tritemp.h,v 1.10 2001/02/12 17:02:00 brianp Exp $ */ - /* * Mesa 3-D graphics library - * Version: 3.5 - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * + * Version: 6.5.3 + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -24,26 +22,24 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - /* * Triangle Rasterizer Template * * This file is #include'd to generate custom triangle rasterizers. * * The following macros may be defined to indicate what auxillary information - * must be interplated across the triangle: - * INTERP_Z - if defined, interpolate Z values + * must be interpolated across the triangle: + * INTERP_Z - if defined, interpolate vertex Z values + * INTERP_W - if defined, interpolate vertex W values + * INTERP_FOG - if defined, interpolate fog values * INTERP_RGB - if defined, interpolate RGB values + * INTERP_ALPHA - if defined, interpolate Alpha values (req's INTERP_RGB) * INTERP_SPEC - if defined, interpolate specular RGB values - * INTERP_ALPHA - if defined, interpolate Alpha values * INTERP_INDEX - if defined, interpolate color index values * INTERP_INT_TEX - if defined, interpolate integer ST texcoords * (fast, simple 2-D texture mapping) - * INTERP_LAMBDA - if defined, the lambda value is computed at every - * pixel, to apply MIPMAPPING, and min/maxification - * INTERP_TEX - if defined, interpolate set 0 float STRQ texcoords + * INTERP_TEX - if defined, interpolate texcoords and varying vars * NOTE: OpenGL STRQ = Mesa STUV (R was taken for red) - * INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords * * When one can directly address pixels in the color buffer the following * macros can be defined and used to compute pixel addresses during @@ -59,76 +55,224 @@ * * Optionally, one may provide one-time setup code per triangle: * SETUP_CODE - code which is to be executed once per triangle - * - * The following macro MUST be defined: - * INNER_LOOP(LEFT,RIGHT,Y) - code to write a span of pixels. - * Something like: + * CLEANUP_CODE - code to execute at end of triangle * - * for (x=LEFT; x_MinFragmentAttrib; \ + attr < swrast->_MaxFragmentAttrib; attr++) { \ + if (swrast->_FragmentAttribs & (1 << attr)) { \ + CODE \ + } \ + } \ + } + + + -/*void triangle( GLcontext *ctx, SWvertex *v0, SWvertex *v1, SWvertex *v2 )*/ +/* + * Some code we unfortunately need to prevent negative interpolated colors. + */ +#ifndef CLAMP_INTERPOLANT +#define CLAMP_INTERPOLANT(CHANNEL, CHANNELSTEP, LEN) \ +do { \ + GLfixed endVal = span.CHANNEL + (LEN) * span.CHANNELSTEP; \ + if (endVal < 0) { \ + span.CHANNEL -= endVal; \ + } \ + if (span.CHANNEL < 0) { \ + span.CHANNEL = 0; \ + } \ +} while (0) +#endif + + +static void NAME(GLcontext *ctx, const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) { typedef struct { - const SWvertex *v0, *v1; /* Y(v0) < Y(v1) */ - GLfloat dx; /* X(v1) - X(v0) */ - GLfloat dy; /* Y(v1) - Y(v0) */ - GLfixed fdxdy; /* dx/dy in fixed-point */ - GLfixed fsx; /* first sample point x coord */ - GLfixed fsy; - GLfloat adjy; /* adjust from v[0]->fy to fsy, scaled */ - GLint lines; /* number of lines to be sampled on this edge */ - GLfixed fx0; /* fixed pt X of lower endpoint */ + const SWvertex *v0, *v1; /* Y(v0) < Y(v1) */ +#if TRIANGLE_WALK_DOUBLE + GLdouble dx; /* X(v1) - X(v0) */ + GLdouble dy; /* Y(v1) - Y(v0) */ + GLdouble dxdy; /* dx/dy */ + GLdouble adjy; /* adjust from v[0]->fy to fsy, scaled */ + GLdouble fsx; /* first sample point x coord */ + GLdouble fsy; + GLdouble fx0; /*X of lower endpoint */ +#else + GLfloat dx; /* X(v1) - X(v0) */ + GLfloat dy; /* Y(v1) - Y(v0) */ + GLfloat dxdy; /* dx/dy */ + GLfixed fdxdy; /* dx/dy in fixed-point */ + GLfloat adjy; /* adjust from v[0]->fy to fsy, scaled */ + GLfixed fsx; /* first sample point x coord */ + GLfixed fsy; + GLfixed fx0; /* fixed pt X of lower endpoint */ +#endif + GLint lines; /* number of lines to be sampled on this edge */ } EdgeT; + const SWcontext *swrast = SWRAST_CONTEXT(ctx); #ifdef INTERP_Z - const GLint depthBits = ctx->Visual.depthBits; + const GLint depthBits = ctx->DrawBuffer->Visual.depthBits; const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0; - const GLfloat maxDepth = ctx->DepthMaxF; + const GLfloat maxDepth = ctx->DrawBuffer->_DepthMaxF; #define FixedToDepth(F) ((F) >> fixedToDepthShift) #endif EdgeT eMaj, eTop, eBot; GLfloat oneOverArea; const SWvertex *vMin, *vMid, *vMax; /* Y(vMin)<=Y(vMid)<=Y(vMax) */ - float bf = SWRAST_CONTEXT(ctx)->_backface_sign; - GLboolean tiny; + GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign; +#if !TRIANGLE_WALK_DOUBLE + const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */ +#endif + GLinterp vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy; - /* find the order of the 3 vertices along the Y axis */ + SWspan span; + + (void) swrast; + + INIT_SPAN(span, GL_POLYGON, 0, 0, 0); + +#ifdef INTERP_Z + (void) fixedToDepthShift; +#endif + + /* + printf("%s()\n", __FUNCTION__); + printf(" %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]); + printf(" %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]); + printf(" %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]); + */ + /* + ASSERT(v0->win[2] >= 0.0); + ASSERT(v1->win[2] >= 0.0); + ASSERT(v2->win[2] >= 0.0); + */ + /* Compute fixed point x,y coords w/ half-pixel offsets and snapping. + * And find the order of the 3 vertices along the Y axis. + */ { - GLfloat y0 = v0->win[1]; - GLfloat y1 = v1->win[1]; - GLfloat y2 = v2->win[1]; - - if (y0<=y1) { - if (y1<=y2) { - vMin = v0; vMid = v1; vMax = v2; /* y0<=y1<=y2 */ - } - else if (y2<=y0) { - vMin = v2; vMid = v0; vMax = v1; /* y2<=y0<=y1 */ - } - else { - vMin = v0; vMid = v2; vMax = v1; bf = -bf; /* y0<=y2<=y1 */ - } +#if TRIANGLE_WALK_DOUBLE + const GLdouble fy0 = v0->win[1] - 0.5; + const GLdouble fy1 = v1->win[1] - 0.5; + const GLdouble fy2 = v2->win[1] - 0.5; +#else + const GLfixed fy0 = FloatToFixed(v0->win[1] - 0.5F) & snapMask; + const GLfixed fy1 = FloatToFixed(v1->win[1] - 0.5F) & snapMask; + const GLfixed fy2 = FloatToFixed(v2->win[1] - 0.5F) & snapMask; +#endif + if (fy0 <= fy1) { + if (fy1 <= fy2) { + /* y0 <= y1 <= y2 */ + vMin = v0; vMid = v1; vMax = v2; + vMin_fy = fy0; vMid_fy = fy1; vMax_fy = fy2; + } + else if (fy2 <= fy0) { + /* y2 <= y0 <= y1 */ + vMin = v2; vMid = v0; vMax = v1; + vMin_fy = fy2; vMid_fy = fy0; vMax_fy = fy1; + } + else { + /* y0 <= y2 <= y1 */ + vMin = v0; vMid = v2; vMax = v1; + vMin_fy = fy0; vMid_fy = fy2; vMax_fy = fy1; + bf = -bf; + } } else { - if (y0<=y2) { - vMin = v1; vMid = v0; vMax = v2; bf = -bf; /* y1<=y0<=y2 */ - } - else if (y2<=y1) { - vMin = v2; vMid = v1; vMax = v0; bf = -bf; /* y2<=y1<=y0 */ - } - else { - vMin = v1; vMid = v2; vMax = v0; /* y1<=y2<=y0 */ - } + if (fy0 <= fy2) { + /* y1 <= y0 <= y2 */ + vMin = v1; vMid = v0; vMax = v2; + vMin_fy = fy1; vMid_fy = fy0; vMax_fy = fy2; + bf = -bf; + } + else if (fy2 <= fy1) { + /* y2 <= y1 <= y0 */ + vMin = v2; vMid = v1; vMax = v0; + vMin_fy = fy2; vMid_fy = fy1; vMax_fy = fy0; + bf = -bf; + } + else { + /* y1 <= y2 <= y0 */ + vMin = v1; vMid = v2; vMax = v0; + vMin_fy = fy1; vMid_fy = fy2; vMax_fy = fy0; + } } + + /* fixed point X coords */ +#if TRIANGLE_WALK_DOUBLE + vMin_fx = vMin->win[0] + 0.5; + vMid_fx = vMid->win[0] + 0.5; + vMax_fx = vMax->win[0] + 0.5; +#else + vMin_fx = FloatToFixed(vMin->win[0] + 0.5F) & snapMask; + vMid_fx = FloatToFixed(vMid->win[0] + 0.5F) & snapMask; + vMax_fx = FloatToFixed(vMax->win[0] + 0.5F) & snapMask; +#endif } /* vertex/edge relationship */ @@ -136,80 +280,109 @@ eTop.v0 = vMid; eTop.v1 = vMax; eBot.v0 = vMin; eBot.v1 = vMid; - /* compute deltas for each edge: vertex[v1] - vertex[v0] */ - eMaj.dx = vMax->win[0] - vMin->win[0]; - eMaj.dy = vMax->win[1] - vMin->win[1]; - eTop.dx = vMax->win[0] - vMid->win[0]; - eTop.dy = vMax->win[1] - vMid->win[1]; - eBot.dx = vMid->win[0] - vMin->win[0]; - eBot.dy = vMid->win[1] - vMin->win[1]; - - /* compute oneOverArea */ + /* compute deltas for each edge: vertex[upper] - vertex[lower] */ +#if TRIANGLE_WALK_DOUBLE + eMaj.dx = vMax_fx - vMin_fx; + eMaj.dy = vMax_fy - vMin_fy; + eTop.dx = vMax_fx - vMid_fx; + eTop.dy = vMax_fy - vMid_fy; + eBot.dx = vMid_fx - vMin_fx; + eBot.dy = vMid_fy - vMin_fy; +#else + eMaj.dx = FixedToFloat(vMax_fx - vMin_fx); + eMaj.dy = FixedToFloat(vMax_fy - vMin_fy); + eTop.dx = FixedToFloat(vMax_fx - vMid_fx); + eTop.dy = FixedToFloat(vMax_fy - vMid_fy); + eBot.dx = FixedToFloat(vMid_fx - vMin_fx); + eBot.dy = FixedToFloat(vMid_fy - vMin_fy); +#endif + + /* compute area, oneOverArea and perform backface culling */ { +#if TRIANGLE_WALK_DOUBLE + const GLdouble area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy; +#else const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy; - +#endif /* Do backface culling */ if (area * bf < 0.0) - return; + return; - if (area == 0.0F) + if (IS_INF_OR_NAN(area) || area == 0.0F) return; - /* check for very tiny triangle */ - if (area * area < (0.05F * 0.05F)) { /* square to ensure positive value */ - oneOverArea = 1.0F / 0.05F; /* a close-enough value */ - tiny = GL_TRUE; - } - else { - oneOverArea = 1.0F / area; - tiny = GL_FALSE; - } + oneOverArea = 1.0F / area; } -#ifndef DO_OCCLUSION_TEST - ctx->OcclusionResult = GL_TRUE; -#endif + + span.facing = ctx->_Facing; /* for 2-sided stencil test */ /* Edge setup. For a triangle strip these could be reused... */ { - /* fixed point Y coordinates */ - GLfixed vMin_fx = FloatToFixed(vMin->win[0] + 0.5F); - GLfixed vMin_fy = FloatToFixed(vMin->win[1] - 0.5F); - GLfixed vMid_fx = FloatToFixed(vMid->win[0] + 0.5F); - GLfixed vMid_fy = FloatToFixed(vMid->win[1] - 0.5F); - GLfixed vMax_fy = FloatToFixed(vMax->win[1] - 0.5F); - +#if TRIANGLE_WALK_DOUBLE + eMaj.fsy = CEILF(vMin_fy); + eMaj.lines = (GLint) CEILF(vMax_fy - eMaj.fsy); +#else eMaj.fsy = FixedCeil(vMin_fy); eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy)); +#endif if (eMaj.lines > 0) { - GLfloat dxdy = eMaj.dx / eMaj.dy; - eMaj.fdxdy = SignedFloatToFixed(dxdy); + eMaj.dxdy = eMaj.dx / eMaj.dy; +#if TRIANGLE_WALK_DOUBLE + eMaj.adjy = (eMaj.fsy - vMin_fy) * FIXED_SCALE; /* SCALED! */ + eMaj.fx0 = vMin_fx; + eMaj.fsx = eMaj.fx0 + (eMaj.adjy * eMaj.dxdy) / (GLdouble) FIXED_SCALE; +#else + eMaj.fdxdy = SignedFloatToFixed(eMaj.dxdy); eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy); /* SCALED! */ eMaj.fx0 = vMin_fx; - eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy); + eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * eMaj.dxdy); +#endif } else { return; /*CULLED*/ } +#if TRIANGLE_WALK_DOUBLE + eTop.fsy = CEILF(vMid_fy); + eTop.lines = (GLint) CEILF(vMax_fy - eTop.fsy); +#else eTop.fsy = FixedCeil(vMid_fy); eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy)); +#endif if (eTop.lines > 0) { - GLfloat dxdy = eTop.dx / eTop.dy; - eTop.fdxdy = SignedFloatToFixed(dxdy); + eTop.dxdy = eTop.dx / eTop.dy; +#if TRIANGLE_WALK_DOUBLE + eTop.adjy = (eTop.fsy - vMid_fy) * FIXED_SCALE; /* SCALED! */ + eTop.fx0 = vMid_fx; + eTop.fsx = eTop.fx0 + (eTop.adjy * eTop.dxdy) / (GLdouble) FIXED_SCALE; +#else + eTop.fdxdy = SignedFloatToFixed(eTop.dxdy); eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */ eTop.fx0 = vMid_fx; - eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy); + eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * eTop.dxdy); +#endif } +#if TRIANGLE_WALK_DOUBLE + eBot.fsy = CEILF(vMin_fy); + eBot.lines = (GLint) CEILF(vMid_fy - eBot.fsy); +#else eBot.fsy = FixedCeil(vMin_fy); eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy)); +#endif if (eBot.lines > 0) { - GLfloat dxdy = eBot.dx / eBot.dy; - eBot.fdxdy = SignedFloatToFixed(dxdy); + eBot.dxdy = eBot.dx / eBot.dy; +#if TRIANGLE_WALK_DOUBLE + eBot.adjy = (eBot.fsy - vMin_fy) * FIXED_SCALE; /* SCALED! */ + eBot.fx0 = vMin_fx; + eBot.fsx = eBot.fx0 + (eBot.adjy * eBot.dxdy) / (GLdouble) FIXED_SCALE; +#else + eBot.fdxdy = SignedFloatToFixed(eBot.dxdy); eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy); /* SCALED! */ eBot.fx0 = vMin_fx; - eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy); + eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * eBot.dxdy); +#endif } } @@ -228,7 +401,7 @@ * By stepping rasterization parameters along the major edge, * we can avoid recomputing them at the discontinuity where * the top and bottom edges meet. However, this forces us to - * be able to scan both left-to-right and right-to-left. + * be able to scan both left-to-right and right-to-left. * Also, we must determine whether the major edge is at the * left or right side of the triangle. We do this by * computing the magnitude of the cross-product of the major @@ -248,51 +421,10 @@ */ { - GLint ltor; /* true if scanning left-to-right */ -#ifdef INTERP_Z - GLfloat dzdx, dzdy; GLfixed fdzdx; - GLfloat dfogdx, dfogdy; GLfixed fdfogdx; -#endif -#ifdef INTERP_RGB - GLfloat drdx, drdy; GLfixed fdrdx; - GLfloat dgdx, dgdy; GLfixed fdgdx; - GLfloat dbdx, dbdy; GLfixed fdbdx; -#endif -#ifdef INTERP_SPEC - GLfloat dsrdx, dsrdy; GLfixed fdsrdx; - GLfloat dsgdx, dsgdy; GLfixed fdsgdx; - GLfloat dsbdx, dsbdy; GLfixed fdsbdx; -#endif -#ifdef INTERP_ALPHA - GLfloat dadx, dady; GLfixed fdadx; -#endif + GLint scan_from_left_to_right; /* true if scanning left-to-right */ #ifdef INTERP_INDEX - GLfloat didx, didy; GLfixed fdidx; -#endif -#ifdef INTERP_INT_TEX - GLfloat dsdx, dsdy; GLfixed fdsdx; - GLfloat dtdx, dtdy; GLfixed fdtdx; -#endif -#ifdef INTERP_TEX - GLfloat dsdx, dsdy; - GLfloat dtdx, dtdy; - GLfloat dudx, dudy; - GLfloat dvdx, dvdy; -#endif -#ifdef INTERP_MULTITEX - GLfloat dsdx[MAX_TEXTURE_UNITS], dsdy[MAX_TEXTURE_UNITS]; - GLfloat dtdx[MAX_TEXTURE_UNITS], dtdy[MAX_TEXTURE_UNITS]; - GLfloat dudx[MAX_TEXTURE_UNITS], dudy[MAX_TEXTURE_UNITS]; - GLfloat dvdx[MAX_TEXTURE_UNITS], dvdy[MAX_TEXTURE_UNITS]; -#endif -#ifdef INTERP_LAMBDA - -#ifndef INTERP_TEX -#error "Mipmapping without texturing doesn't make sense." + GLfloat didx, didy; #endif - GLfloat lambda_nominator; -#endif /* INTERP_LAMBDA */ - /* * Execute user-supplied setup code @@ -301,205 +433,210 @@ SETUP_CODE #endif - ltor = (oneOverArea < 0.0F); + scan_from_left_to_right = (oneOverArea < 0.0F); + /* compute d?/dx and d?/dy derivatives */ #ifdef INTERP_Z + span.interpMask |= SPAN_Z; { - GLfloat eMaj_dz, eBot_dz; - eMaj_dz = vMax->win[2] - vMin->win[2]; - eBot_dz = vMid->win[2] - vMin->win[2]; - dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz); - if (dzdx > maxDepth || dzdx < -maxDepth) { + GLfloat eMaj_dz = vMax->win[2] - vMin->win[2]; + GLfloat eBot_dz = vMid->win[2] - vMin->win[2]; + span.attrStepX[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz); + if (span.attrStepX[FRAG_ATTRIB_WPOS][2] > maxDepth || span.attrStepX[FRAG_ATTRIB_WPOS][2] < -maxDepth) { /* probably a sliver triangle */ - dzdx = 0.0; - dzdy = 0.0; + span.attrStepX[FRAG_ATTRIB_WPOS][2] = 0.0; + span.attrStepY[FRAG_ATTRIB_WPOS][2] = 0.0; } else { - dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx); + span.attrStepY[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx); } if (depthBits <= 16) - fdzdx = SignedFloatToFixed(dzdx); + span.zStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_WPOS][2]); else - fdzdx = (GLint) dzdx; + span.zStep = (GLint) span.attrStepX[FRAG_ATTRIB_WPOS][2]; } +#endif +#ifdef INTERP_W + span.interpMask |= SPAN_W; { - GLfloat eMaj_dfog, eBot_dfog; - eMaj_dfog = (vMax->fog - vMin->fog) * 256; - eBot_dfog = (vMid->fog - vMin->fog) * 256; - dfogdx = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog); - fdfogdx = SignedFloatToFixed(dfogdx); - dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx); + const GLfloat eMaj_dw = vMax->win[3] - vMin->win[3]; + const GLfloat eBot_dw = vMid->win[3] - vMin->win[3]; + span.attrStepX[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw); + span.attrStepY[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx); + } +#endif +#ifdef INTERP_FOG + span.interpMask |= SPAN_FOG; + { +# ifdef INTERP_W + const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3]; + const GLfloat eMaj_dfog = vMax->fog * wMax - vMin->fog * wMin; + const GLfloat eBot_dfog = vMid->fog * wMid - vMin->fog * wMin; +# else + const GLfloat eMaj_dfog = vMax->fog - vMin->fog; + const GLfloat eBot_dfog = vMid->fog - vMin->fog; +# endif + span.attrStepX[FRAG_ATTRIB_FOGC][0] = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog); + span.attrStepY[FRAG_ATTRIB_FOGC][0] = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx); } #endif #ifdef INTERP_RGB - if (tiny) { - /* This is kind of a hack to eliminate RGB color over/underflow - * problems when rendering very tiny triangles. We're not doing - * anything with alpha or specular color at this time. - */ - drdx = drdy = 0.0; fdrdx = 0; - dgdx = dgdy = 0.0; fdgdx = 0; - dbdx = dbdy = 0.0; fdbdx = 0; + span.interpMask |= SPAN_RGBA; + if (ctx->Light.ShadeModel == GL_SMOOTH) { + GLfloat eMaj_dr = (GLfloat) ((ColorTemp) vMax->color[RCOMP] - (ColorTemp) vMin->color[RCOMP]); + GLfloat eBot_dr = (GLfloat) ((ColorTemp) vMid->color[RCOMP] - (ColorTemp) vMin->color[RCOMP]); + GLfloat eMaj_dg = (GLfloat) ((ColorTemp) vMax->color[GCOMP] - (ColorTemp) vMin->color[GCOMP]); + GLfloat eBot_dg = (GLfloat) ((ColorTemp) vMid->color[GCOMP] - (ColorTemp) vMin->color[GCOMP]); + GLfloat eMaj_db = (GLfloat) ((ColorTemp) vMax->color[BCOMP] - (ColorTemp) vMin->color[BCOMP]); + GLfloat eBot_db = (GLfloat) ((ColorTemp) vMid->color[BCOMP] - (ColorTemp) vMin->color[BCOMP]); +# ifdef INTERP_ALPHA + GLfloat eMaj_da = (GLfloat) ((ColorTemp) vMax->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]); + GLfloat eBot_da = (GLfloat) ((ColorTemp) vMid->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]); +# endif + span.attrStepX[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr); + span.attrStepY[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx); + span.attrStepX[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg); + span.attrStepY[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx); + span.attrStepX[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db); + span.attrStepY[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx); +# if CHAN_TYPE == GL_FLOAT + span.redStep = span.attrStepX[FRAG_ATTRIB_COL0][0]; + span.greenStep = span.attrStepX[FRAG_ATTRIB_COL0][1]; + span.blueStep = span.attrStepX[FRAG_ATTRIB_COL0][2]; +# else + span.redStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][0]); + span.greenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][1]); + span.blueStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][2]); +# endif /* GL_FLOAT */ +# ifdef INTERP_ALPHA + span.attrStepX[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); + span.attrStepX[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); +# if CHAN_TYPE == GL_FLOAT + span.alphaStep = span.attrStepX[FRAG_ATTRIB_COL0][3]; +# else + span.alphaStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3]); +# endif /* GL_FLOAT */ +# endif /* INTERP_ALPHA */ } else { - GLfloat eMaj_dr, eBot_dr; - GLfloat eMaj_dg, eBot_dg; - GLfloat eMaj_db, eBot_db; - eMaj_dr = (GLint) vMax->color[0] - (GLint) vMin->color[0]; - eBot_dr = (GLint) vMid->color[0] - (GLint) vMin->color[0]; - drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr); - fdrdx = SignedFloatToFixed(drdx); - drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx); - eMaj_dg = (GLint) vMax->color[1] - (GLint) vMin->color[1]; - eBot_dg = (GLint) vMid->color[1] - (GLint) vMin->color[1]; - dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg); - fdgdx = SignedFloatToFixed(dgdx); - dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx); - eMaj_db = (GLint) vMax->color[2] - (GLint) vMin->color[2]; - eBot_db = (GLint) vMid->color[2] - (GLint) vMin->color[2]; - dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db); - fdbdx = SignedFloatToFixed(dbdx); - dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx); + ASSERT(ctx->Light.ShadeModel == GL_FLAT); + span.interpMask |= SPAN_FLAT; + span.attrStepX[FRAG_ATTRIB_COL0][0] = span.attrStepY[FRAG_ATTRIB_COL0][0] = 0.0F; + span.attrStepX[FRAG_ATTRIB_COL0][1] = span.attrStepY[FRAG_ATTRIB_COL0][1] = 0.0F; + span.attrStepX[FRAG_ATTRIB_COL0][2] = span.attrStepY[FRAG_ATTRIB_COL0][2] = 0.0F; +# if CHAN_TYPE == GL_FLOAT + span.redStep = 0.0F; + span.greenStep = 0.0F; + span.blueStep = 0.0F; +# else + span.redStep = 0; + span.greenStep = 0; + span.blueStep = 0; +# endif /* GL_FLOAT */ +# ifdef INTERP_ALPHA + span.attrStepX[FRAG_ATTRIB_COL0][3] = span.attrStepX[FRAG_ATTRIB_COL0][3] = 0.0F; +# if CHAN_TYPE == GL_FLOAT + span.alphaStep = 0.0F; +# else + span.alphaStep = 0; +# endif /* GL_FLOAT */ +# endif } -#endif +#endif /* INTERP_RGB */ #ifdef INTERP_SPEC - { - GLfloat eMaj_dsr, eBot_dsr; - eMaj_dsr = (GLint) vMax->specular[0] - (GLint) vMin->specular[0]; - eBot_dsr = (GLint) vMid->specular[0] - (GLint) vMin->specular[0]; - dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr); - fdsrdx = SignedFloatToFixed(dsrdx); - dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx); - } - { - GLfloat eMaj_dsg, eBot_dsg; - eMaj_dsg = (GLint) vMax->specular[1] - (GLint) vMin->specular[1]; - eBot_dsg = (GLint) vMid->specular[1] - (GLint) vMin->specular[1]; - dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg); - fdsgdx = SignedFloatToFixed(dsgdx); - dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx); - } - { - GLfloat eMaj_dsb, eBot_dsb; - eMaj_dsb = (GLint) vMax->specular[2] - (GLint) vMin->specular[2]; - eBot_dsb = (GLint) vMid->specular[2] - (GLint) vMin->specular[2]; - dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb); - fdsbdx = SignedFloatToFixed(dsbdx); - dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx); + span.interpMask |= SPAN_SPEC; + if (ctx->Light.ShadeModel == GL_SMOOTH) { + GLfloat eMaj_dsr = (GLfloat) ((ColorTemp) vMax->specular[RCOMP] - (ColorTemp) vMin->specular[RCOMP]); + GLfloat eBot_dsr = (GLfloat) ((ColorTemp) vMid->specular[RCOMP] - (ColorTemp) vMin->specular[RCOMP]); + GLfloat eMaj_dsg = (GLfloat) ((ColorTemp) vMax->specular[GCOMP] - (ColorTemp) vMin->specular[GCOMP]); + GLfloat eBot_dsg = (GLfloat) ((ColorTemp) vMid->specular[GCOMP] - (ColorTemp) vMin->specular[GCOMP]); + GLfloat eMaj_dsb = (GLfloat) ((ColorTemp) vMax->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]); + GLfloat eBot_dsb = (GLfloat) ((ColorTemp) vMid->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]); + span.attrStepX[FRAG_ATTRIB_COL1][0] = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr); + span.attrStepY[FRAG_ATTRIB_COL1][0] = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx); + span.attrStepX[FRAG_ATTRIB_COL1][1] = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg); + span.attrStepY[FRAG_ATTRIB_COL1][1] = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx); + span.attrStepX[FRAG_ATTRIB_COL1][2] = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb); + span.attrStepY[FRAG_ATTRIB_COL1][2] = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx); +# if CHAN_TYPE == GL_FLOAT + span.specRedStep = span.attrStep[FRAG_ATTRIB_COL1][0]; + span.specGreenStep = span.dsgdx; + span.specBlueStep = span.dsbdx; +# else + span.specRedStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][0]); + span.specGreenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][1]); + span.specBlueStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][2]); +# endif } -#endif -#ifdef INTERP_ALPHA - { - GLfloat eMaj_da, eBot_da; - eMaj_da = (GLint) vMax->color[3] - (GLint) vMin->color[3]; - eBot_da = (GLint) vMid->color[3] - (GLint) vMin->color[3]; - dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); - fdadx = SignedFloatToFixed(dadx); - dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); + else { + span.attrStepX[FRAG_ATTRIB_COL1][0] = span.attrStepY[FRAG_ATTRIB_COL1][0] = 0.0F; + span.attrStepX[FRAG_ATTRIB_COL1][1] = span.attrStepY[FRAG_ATTRIB_COL1][1] = 0.0F; + span.attrStepX[FRAG_ATTRIB_COL1][2] = span.attrStepY[FRAG_ATTRIB_COL1][2] = 0.0F; +# if CHAN_TYPE == GL_FLOAT + span.specRedStep = 0.0F; + span.specGreenStep = 0.0F; + span.specBlueStep = 0.0F; +# else + span.specRedStep = 0; + span.specGreenStep = 0; + span.specBlueStep = 0; +# endif } -#endif +#endif /* INTERP_SPEC */ #ifdef INTERP_INDEX - { - GLfloat eMaj_di, eBot_di; - eMaj_di = (GLint) vMax->index - (GLint) vMin->index; - eBot_di = (GLint) vMid->index - (GLint) vMin->index; + span.interpMask |= SPAN_INDEX; + if (ctx->Light.ShadeModel == GL_SMOOTH) { + GLfloat eMaj_di = vMax->index - vMin->index; + GLfloat eBot_di = vMid->index - vMin->index; didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di); - fdidx = SignedFloatToFixed(didx); didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx); + span.indexStep = SignedFloatToFixed(didx); + } + else { + span.interpMask |= SPAN_FLAT; + didx = didy = 0.0F; + span.indexStep = 0; } #endif #ifdef INTERP_INT_TEX + span.interpMask |= SPAN_INT_TEXTURE; { - GLfloat eMaj_ds, eBot_ds; - eMaj_ds = (vMax->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE; - eBot_ds = (vMid->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE; - dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); - fdsdx = SignedFloatToFixed(dsdx); - dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); - } - { - GLfloat eMaj_dt, eBot_dt; - eMaj_dt = (vMax->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE; - eBot_dt = (vMid->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE; - dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); - fdtdx = SignedFloatToFixed(dtdx); - dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); + GLfloat eMaj_ds = (vMax->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE; + GLfloat eBot_ds = (vMid->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE; + GLfloat eMaj_dt = (vMax->attrib[FRAG_ATTRIB_TEX0][1] - vMin->attrib[FRAG_ATTRIB_TEX0][1]) * T_SCALE; + GLfloat eBot_dt = (vMid->attrib[FRAG_ATTRIB_TEX0][1] - vMin->attrib[FRAG_ATTRIB_TEX0][1]) * T_SCALE; + span.attrStepX[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); + span.attrStepY[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); + span.attrStepX[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); + span.attrStepY[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); + span.intTexStep[0] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][0]); + span.intTexStep[1] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][1]); } - #endif #ifdef INTERP_TEX + span.interpMask |= (SPAN_TEXTURE | SPAN_VARYING); { - GLfloat wMax = vMax->win[3]; - GLfloat wMin = vMin->win[3]; - GLfloat wMid = vMid->win[3]; - GLfloat eMaj_ds, eBot_ds; - GLfloat eMaj_dt, eBot_dt; - GLfloat eMaj_du, eBot_du; - GLfloat eMaj_dv, eBot_dv; - - eMaj_ds = vMax->texcoord[0][0] * wMax - vMin->texcoord[0][0] * wMin; - eBot_ds = vMid->texcoord[0][0] * wMid - vMin->texcoord[0][0] * wMin; - dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); - dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); - - eMaj_dt = vMax->texcoord[0][1] * wMax - vMin->texcoord[0][1] * wMin; - eBot_dt = vMid->texcoord[0][1] * wMid - vMin->texcoord[0][1] * wMin; - dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); - dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); - - eMaj_du = vMax->texcoord[0][2] * wMax - vMin->texcoord[0][2] * wMin; - eBot_du = vMid->texcoord[0][2] * wMid - vMin->texcoord[0][2] * wMin; - dudx = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du); - dudy = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx); - - eMaj_dv = vMax->texcoord[0][3] * wMax - vMin->texcoord[0][3] * wMin; - eBot_dv = vMid->texcoord[0][3] * wMid - vMin->texcoord[0][3] * wMin; - dvdx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv); - dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx); - } -#endif -#ifdef INTERP_MULTITEX - { - GLfloat wMax = vMax->win[3]; - GLfloat wMin = vMin->win[3]; - GLfloat wMid = vMid->win[3]; - GLuint u; - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - GLfloat eMaj_ds, eBot_ds; - GLfloat eMaj_dt, eBot_dt; - GLfloat eMaj_du, eBot_du; - GLfloat eMaj_dv, eBot_dv; - eMaj_ds = vMax->texcoord[u][0] * wMax - - vMin->texcoord[u][0] * wMin; - eBot_ds = vMid->texcoord[u][0] * wMid - - vMin->texcoord[u][0] * wMin; - dsdx[u] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); - dsdy[u] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); - - eMaj_dt = vMax->texcoord[u][1] * wMax - - vMin->texcoord[u][1] * wMin; - eBot_dt = vMid->texcoord[u][1] * wMid - - vMin->texcoord[u][1] * wMin; - dtdx[u] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); - dtdy[u] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); - - eMaj_du = vMax->texcoord[u][2] * wMax - - vMin->texcoord[u][2] * wMin; - eBot_du = vMid->texcoord[u][2] * wMid - - vMin->texcoord[u][2] * wMin; - dudx[u] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du); - dudy[u] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx); - - eMaj_dv = vMax->texcoord[u][3] * wMax - - vMin->texcoord[u][3] * wMin; - eBot_dv = vMid->texcoord[u][3] * wMid - - vMin->texcoord[u][3] * wMin; - dvdx[u] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv); - dvdy[u] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx); - } - } + /* win[3] is 1/W */ + const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3]; + TEXVAR_LOOP( + GLfloat eMaj_ds = vMax->attrib[attr][0] * wMax - vMin->attrib[attr][0] * wMin; + GLfloat eBot_ds = vMid->attrib[attr][0] * wMid - vMin->attrib[attr][0] * wMin; + GLfloat eMaj_dt = vMax->attrib[attr][1] * wMax - vMin->attrib[attr][1] * wMin; + GLfloat eBot_dt = vMid->attrib[attr][1] * wMid - vMin->attrib[attr][1] * wMin; + GLfloat eMaj_du = vMax->attrib[attr][2] * wMax - vMin->attrib[attr][2] * wMin; + GLfloat eBot_du = vMid->attrib[attr][2] * wMid - vMin->attrib[attr][2] * wMin; + GLfloat eMaj_dv = vMax->attrib[attr][3] * wMax - vMin->attrib[attr][3] * wMin; + GLfloat eBot_dv = vMid->attrib[attr][3] * wMid - vMin->attrib[attr][3] * wMin; + span.attrStepX[attr][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); + span.attrStepY[attr][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); + span.attrStepX[attr][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); + span.attrStepY[attr][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); + span.attrStepX[attr][2] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du); + span.attrStepY[attr][2] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx); + span.attrStepX[attr][3] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv); + span.attrStepY[attr][3] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx); + ) } #endif @@ -526,7 +663,7 @@ * inside the triangle. * * Next we creep down the major edge until we reach that y, - * and compute the corresponding x coordinate on the edge. + * and compute the corresponding x coordinate on the edge. * Then we find the half-integral x that lies on or just * inside the edge. This is the first pixel that might lie in * the interior of the triangle. (We won't know for sure @@ -551,62 +688,59 @@ */ { - int subTriangle; - GLfixed fx, fxLeftEdge, fxRightEdge, fdxLeftEdge, fdxRightEdge; - GLfixed fdxOuter; - int idxOuter; - float dxOuter; - GLfixed fError, fdError; - float adjx, adjy; - GLfixed fy; - int iy; + GLint subTriangle; + GLinterp fxLeftEdge = 0, fxRightEdge = 0; + GLinterp fdxLeftEdge = 0, fdxRightEdge = 0; + GLinterp fError = 0, fdError = 0; #ifdef PIXEL_ADDRESS - PIXEL_TYPE *pRow; - int dPRowOuter, dPRowInner; /* offset in bytes */ + PIXEL_TYPE *pRow = NULL; + GLint dPRowOuter = 0, dPRowInner; /* offset in bytes */ #endif #ifdef INTERP_Z # ifdef DEPTH_TYPE - DEPTH_TYPE *zRow; - int dZRowOuter, dZRowInner; /* offset in bytes */ + struct gl_renderbuffer *zrb + = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; + DEPTH_TYPE *zRow = NULL; + GLint dZRowOuter = 0, dZRowInner; /* offset in bytes */ # endif - GLfixed fz, fdzOuter, fdzInner; - GLfixed ffog, fdfogOuter, fdfogInner; + GLuint zLeft = 0; + GLfixed fdzOuter = 0, fdzInner; #endif -#ifdef INTERP_RGB - GLfixed fr, fdrOuter, fdrInner; - GLfixed fg, fdgOuter, fdgInner; - GLfixed fb, fdbOuter, fdbInner; +#ifdef INTERP_W + GLfloat wLeft = 0, dwOuter = 0, dwInner; #endif -#ifdef INTERP_SPEC - GLfixed fsr, fdsrOuter, fdsrInner; - GLfixed fsg, fdsgOuter, fdsgInner; - GLfixed fsb, fdsbOuter, fdsbInner; +#ifdef INTERP_FOG + GLfloat fogLeft = 0, dfogOuter = 0, dfogInner; +#endif +#ifdef INTERP_RGB + ColorTemp rLeft = 0, fdrOuter = 0, fdrInner; + ColorTemp gLeft = 0, fdgOuter = 0, fdgInner; + ColorTemp bLeft = 0, fdbOuter = 0, fdbInner; #endif #ifdef INTERP_ALPHA - GLfixed fa, fdaOuter, fdaInner; + ColorTemp aLeft = 0, fdaOuter = 0, fdaInner; +#endif +#ifdef INTERP_SPEC + ColorTemp srLeft=0, dsrOuter=0, dsrInner; + ColorTemp sgLeft=0, dsgOuter=0, dsgInner; + ColorTemp sbLeft=0, dsbOuter=0, dsbInner; #endif #ifdef INTERP_INDEX - GLfixed fi, fdiOuter, fdiInner; + GLfixed iLeft=0, diOuter=0, diInner; #endif #ifdef INTERP_INT_TEX - GLfixed fs, fdsOuter, fdsInner; - GLfixed ft, fdtOuter, fdtInner; + GLfixed sLeft=0, dsOuter=0, dsInner; + GLfixed tLeft=0, dtOuter=0, dtInner; #endif #ifdef INTERP_TEX - GLfloat sLeft, dsOuter, dsInner; - GLfloat tLeft, dtOuter, dtInner; - GLfloat uLeft, duOuter, duInner; - GLfloat vLeft, dvOuter, dvInner; -#endif -#ifdef INTERP_MULTITEX - GLfloat sLeft[MAX_TEXTURE_UNITS]; - GLfloat tLeft[MAX_TEXTURE_UNITS]; - GLfloat uLeft[MAX_TEXTURE_UNITS]; - GLfloat vLeft[MAX_TEXTURE_UNITS]; - GLfloat dsOuter[MAX_TEXTURE_UNITS], dsInner[MAX_TEXTURE_UNITS]; - GLfloat dtOuter[MAX_TEXTURE_UNITS], dtInner[MAX_TEXTURE_UNITS]; - GLfloat duOuter[MAX_TEXTURE_UNITS], duInner[MAX_TEXTURE_UNITS]; - GLfloat dvOuter[MAX_TEXTURE_UNITS], dvInner[MAX_TEXTURE_UNITS]; + GLfloat sLeft[FRAG_ATTRIB_MAX]; + GLfloat tLeft[FRAG_ATTRIB_MAX]; + GLfloat uLeft[FRAG_ATTRIB_MAX]; + GLfloat vLeft[FRAG_ATTRIB_MAX]; + GLfloat dsOuter[FRAG_ATTRIB_MAX], dsInner[FRAG_ATTRIB_MAX]; + GLfloat dtOuter[FRAG_ATTRIB_MAX], dtInner[FRAG_ATTRIB_MAX]; + GLfloat duOuter[FRAG_ATTRIB_MAX], duInner[FRAG_ATTRIB_MAX]; + GLfloat dvOuter[FRAG_ATTRIB_MAX], dvInner[FRAG_ATTRIB_MAX]; #endif for (subTriangle=0; subTriangle<=1; subTriangle++) { @@ -616,7 +750,7 @@ if (subTriangle==0) { /* bottom half */ - if (ltor) { + if (scan_from_left_to_right) { eLeft = &eMaj; eRight = &eBot; lines = eRight->lines; @@ -633,7 +767,7 @@ } else { /* top half */ - if (ltor) { + if (scan_from_left_to_right) { eLeft = &eMaj; eRight = &eTop; lines = eRight->lines; @@ -652,39 +786,60 @@ } if (setupLeft && eLeft->lines > 0) { - const SWvertex *vLower; - GLfixed fsx = eLeft->fsx; - fx = FixedCeil(fsx); + const SWvertex *vLower = eLeft->v0; +#if TRIANGLE_WALK_DOUBLE + const GLdouble fsy = eLeft->fsy; + const GLdouble fsx = eLeft->fsx; + const GLdouble fx = CEILF(fsx); + const GLdouble adjx = (fx - eLeft->fx0) * FIXED_SCALE; /* SCALED! */ +#else + const GLfixed fsy = eLeft->fsy; + const GLfixed fsx = eLeft->fsx; /* no fractional part */ + const GLfixed fx = FixedCeil(fsx); /* no fractional part */ + const GLfixed adjx = (GLinterp) (fx - eLeft->fx0); /* SCALED! */ +#endif + const GLinterp adjy = (GLinterp) eLeft->adjy; /* SCALED! */ + GLint idxOuter; +#if TRIANGLE_WALK_DOUBLE + GLdouble dxOuter; + + fError = fx - fsx - 1.0; + fxLeftEdge = fsx; + fdxLeftEdge = eLeft->dxdy; + dxOuter = FLOORF(fdxLeftEdge); + fdError = dxOuter - fdxLeftEdge + 1.0; + idxOuter = (GLint) dxOuter; + span.y = (GLint) fsy; +#else + GLfloat dxOuter; + GLfixed fdxOuter; + fError = fx - fsx - FIXED_ONE; fxLeftEdge = fsx - FIXED_EPSILON; fdxLeftEdge = eLeft->fdxdy; fdxOuter = FixedFloor(fdxLeftEdge - FIXED_EPSILON); fdError = fdxOuter - fdxLeftEdge + FIXED_ONE; idxOuter = FixedToInt(fdxOuter); - dxOuter = (float) idxOuter; - (void) dxOuter; - - fy = eLeft->fsy; - iy = FixedToInt(fy); - - adjx = (float)(fx - eLeft->fx0); /* SCALED! */ - adjy = eLeft->adjy; /* SCALED! */ - (void) adjx; /* silence compiler warnings */ - (void) adjy; /* silence compiler warnings */ + dxOuter = (GLfloat) idxOuter; + span.y = FixedToInt(fsy); +#endif - vLower = eLeft->v0; - (void) vLower; /* silence compiler warnings */ + /* silence warnings on some compilers */ + (void) dxOuter; + (void) adjx; + (void) adjy; + (void) vLower; #ifdef PIXEL_ADDRESS { - pRow = PIXEL_ADDRESS( FixedToInt(fxLeftEdge), iy ); + pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(InterpToInt(fxLeftEdge), span.y); dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE); /* negative because Y=0 at bottom and increases upward */ } #endif /* * Now we need the set of parameter (z, color, etc.) values at - * the point (fx, fy). This gives us properly-sampled parameter + * the point (fx, fsy). This gives us properly-sampled parameter * values that we can step from pixel to pixel. Furthermore, * although we might have intermediate results that overflow * the normal parameter range when we step temporarily outside @@ -697,125 +852,181 @@ GLfloat z0 = vLower->win[2]; if (depthBits <= 16) { /* interpolate fixed-pt values */ - GLfloat tmp = (z0 * FIXED_SCALE + - dzdx * adjx + dzdy * adjy) + FIXED_HALF; + GLfloat tmp = (z0 * FIXED_SCALE + + span.attrStepX[FRAG_ATTRIB_WPOS][2] * adjx + + span.attrStepY[FRAG_ATTRIB_WPOS][2] * adjy) + FIXED_HALF; if (tmp < MAX_GLUINT / 2) - fz = (GLfixed) tmp; + zLeft = (GLfixed) tmp; else - fz = MAX_GLUINT / 2; - fdzOuter = SignedFloatToFixed(dzdy + dxOuter * dzdx); + zLeft = MAX_GLUINT / 2; + fdzOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]); } else { - /* interpolate depth values exactly */ - fz = (GLint) (z0 + dzdx*FixedToFloat(adjx) + dzdy*FixedToFloat(adjy)); - fdzOuter = (GLint) (dzdy + dxOuter * dzdx); + /* interpolate depth values w/out scaling */ + zLeft = (GLuint) (z0 + span.attrStepX[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjx) + + span.attrStepY[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjy)); + fdzOuter = (GLint) (span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]); } # ifdef DEPTH_TYPE - zRow = (DEPTH_TYPE *) _mesa_zbuffer_address(ctx, FixedToInt(fxLeftEdge), iy); + zRow = (DEPTH_TYPE *) + zrb->GetPointer(ctx, zrb, InterpToInt(fxLeftEdge), span.y); dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE); # endif } - { - ffog = FloatToFixed(vLower->fog) * 256 + dfogdx * adjx + dfogdy * adjy + FIXED_HALF; - fdfogOuter = SignedFloatToFixed(dfogdy + dxOuter * dfogdx); - } +#endif +#ifdef INTERP_W + wLeft = vLower->win[3] + (span.attrStepX[FRAG_ATTRIB_WPOS][3] * adjx + span.attrStepY[FRAG_ATTRIB_WPOS][3] * adjy) * (1.0F/FIXED_SCALE); + dwOuter = span.attrStepY[FRAG_ATTRIB_WPOS][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][3]; +#endif +#ifdef INTERP_FOG +# ifdef INTERP_W + fogLeft = vLower->fog * vLower->win[3] + (span.attrStepX[FRAG_ATTRIB_FOGC][0] * adjx + span.attrStepY[FRAG_ATTRIB_FOGC][0] * adjy) * (1.0F/FIXED_SCALE); +# else + fogLeft = vLower->fog + (span.attrStepX[FRAG_ATTRIB_FOGC][0] * adjx + span.attrStepY[FRAG_ATTRIB_FOGC][0] * adjy) * (1.0F/FIXED_SCALE); +# endif + dfogOuter = span.attrStepY[FRAG_ATTRIB_FOGC][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_FOGC][0]; #endif #ifdef INTERP_RGB - fr = (GLfixed)(IntToFixed(vLower->color[0]) - + drdx * adjx + drdy * adjy) + FIXED_HALF; - fdrOuter = SignedFloatToFixed(drdy + dxOuter * drdx); + if (ctx->Light.ShadeModel == GL_SMOOTH) { +# if CHAN_TYPE == GL_FLOAT + rLeft = vLower->color[RCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) * (1.0F / FIXED_SCALE); + gLeft = vLower->color[GCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) * (1.0F / FIXED_SCALE); + bLeft = vLower->color[BCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) * (1.0F / FIXED_SCALE); + fdrOuter = span.attrStepY[FRAG_ATTRIB_COL0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0]; + fdgOuter = span.attrStepY[FRAG_ATTRIB_COL0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1]; + fdbOuter = span.attrStepY[FRAG_ATTRIB_COL0][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2]; +# else + rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) + FIXED_HALF; + gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) + FIXED_HALF; + bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) + FIXED_HALF; + fdrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0]); + fdgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1]); + fdbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2]); +# endif +# ifdef INTERP_ALPHA +# if CHAN_TYPE == GL_FLOAT + aLeft = vLower->color[ACOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjy) * (1.0F / FIXED_SCALE); + fdaOuter = span.attrStepX[FRAG_ATTRIB_COL0][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]; +# else + aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjy) + FIXED_HALF; + fdaOuter = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]); +# endif +# endif + } + else { + ASSERT(ctx->Light.ShadeModel == GL_FLAT); +# if CHAN_TYPE == GL_FLOAT + rLeft = v2->color[RCOMP]; + gLeft = v2->color[GCOMP]; + bLeft = v2->color[BCOMP]; + fdrOuter = fdgOuter = fdbOuter = 0.0F; +# else + rLeft = ChanToFixed(v2->color[RCOMP]); + gLeft = ChanToFixed(v2->color[GCOMP]); + bLeft = ChanToFixed(v2->color[BCOMP]); + fdrOuter = fdgOuter = fdbOuter = 0; +# endif +# ifdef INTERP_ALPHA +# if CHAN_TYPE == GL_FLOAT + aLeft = v2->color[ACOMP]; + fdaOuter = 0.0F; +# else + aLeft = ChanToFixed(v2->color[ACOMP]); + fdaOuter = 0; +# endif +# endif + } +#endif /* INTERP_RGB */ - fg = (GLfixed)(IntToFixed(vLower->color[1]) - + dgdx * adjx + dgdy * adjy) + FIXED_HALF; - fdgOuter = SignedFloatToFixed(dgdy + dxOuter * dgdx); - fb = (GLfixed)(IntToFixed(vLower->color[2]) - + dbdx * adjx + dbdy * adjy) + FIXED_HALF; - fdbOuter = SignedFloatToFixed(dbdy + dxOuter * dbdx); -#endif #ifdef INTERP_SPEC - fsr = (GLfixed)(IntToFixed(vLower->specular[0]) - + dsrdx * adjx + dsrdy * adjy) + FIXED_HALF; - fdsrOuter = SignedFloatToFixed(dsrdy + dxOuter * dsrdx); - - fsg = (GLfixed)(IntToFixed(vLower->specular[1]) - + dsgdx * adjx + dsgdy * adjy) + FIXED_HALF; - fdsgOuter = SignedFloatToFixed(dsgdy + dxOuter * dsgdx); - - fsb = (GLfixed)(IntToFixed(vLower->specular[2]) - + dsbdx * adjx + dsbdy * adjy) + FIXED_HALF; - fdsbOuter = SignedFloatToFixed(dsbdy + dxOuter * dsbdx); -#endif -#ifdef INTERP_ALPHA - fa = (GLfixed)(IntToFixed(vLower->color[3]) - + dadx * adjx + dady * adjy) + FIXED_HALF; - fdaOuter = SignedFloatToFixed(dady + dxOuter * dadx); + if (ctx->Light.ShadeModel == GL_SMOOTH) { +# if CHAN_TYPE == GL_FLOAT + srLeft = vLower->specular[RCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][0] * adjy) * (1.0F / FIXED_SCALE); + sgLeft = vLower->specular[GCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][1] * adjy) * (1.0F / FIXED_SCALE); + sbLeft = vLower->specular[BCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][2] * adjy) * (1.0F / FIXED_SCALE); + dsrOuter = span.attrStepY[FRAG_ATTRIB_COL1][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][0]; + dsgOuter = span.attrStepY[FRAG_ATTRIB_COL1][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][1]; + dsbOuter = span.attrStepY[FRAG_ATTRIB_COL1][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][2]; +# else + srLeft = (GLfixed) (ChanToFixed(vLower->specular[RCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][0] * adjy) + FIXED_HALF; + sgLeft = (GLfixed) (ChanToFixed(vLower->specular[GCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][1] * adjy) + FIXED_HALF; + sbLeft = (GLfixed) (ChanToFixed(vLower->specular[BCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][2] * adjy) + FIXED_HALF; + dsrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][0]); + dsgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][1]); + dsbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][2]); +# endif + } + else { + ASSERT(ctx->Light.ShadeModel == GL_FLAT); +#if CHAN_TYPE == GL_FLOAT + srLeft = v2->specular[RCOMP]; + sgLeft = v2->specular[GCOMP]; + sbLeft = v2->specular[BCOMP]; + dsrOuter = dsgOuter = dsbOuter = 0.0F; +# else + srLeft = ChanToFixed(v2->specular[RCOMP]); + sgLeft = ChanToFixed(v2->specular[GCOMP]); + sbLeft = ChanToFixed(v2->specular[BCOMP]); + dsrOuter = dsgOuter = dsbOuter = 0; +# endif + } #endif + #ifdef INTERP_INDEX - fi = (GLfixed)(vLower->index * FIXED_SCALE - + didx * adjx + didy * adjy) + FIXED_HALF; - fdiOuter = SignedFloatToFixed(didy + dxOuter * didx); + if (ctx->Light.ShadeModel == GL_SMOOTH) { + iLeft = (GLfixed)(vLower->index * FIXED_SCALE + + didx * adjx + didy * adjy) + FIXED_HALF; + diOuter = SignedFloatToFixed(didy + dxOuter * didx); + } + else { + ASSERT(ctx->Light.ShadeModel == GL_FLAT); + iLeft = FloatToFixed(v2->index); + diOuter = 0; + } #endif #ifdef INTERP_INT_TEX { GLfloat s0, t0; - s0 = vLower->texcoord[0][0] * S_SCALE; - fs = (GLfixed)(s0 * FIXED_SCALE + dsdx * adjx + dsdy * adjy) + FIXED_HALF; - fdsOuter = SignedFloatToFixed(dsdy + dxOuter * dsdx); - - t0 = vLower->texcoord[0][1] * T_SCALE; - ft = (GLfixed)(t0 * FIXED_SCALE + dtdx * adjx + dtdy * adjy) + FIXED_HALF; - fdtOuter = SignedFloatToFixed(dtdy + dxOuter * dtdx); - } -#endif -#ifdef INTERP_TEX - { - GLfloat invW = vLower->win[3]; - GLfloat s0, t0, u0, v0; - s0 = vLower->texcoord[0][0] * invW; - sLeft = s0 + (dsdx * adjx + dsdy * adjy) * (1.0F/FIXED_SCALE); - dsOuter = dsdy + dxOuter * dsdx; - t0 = vLower->texcoord[0][1] * invW; - tLeft = t0 + (dtdx * adjx + dtdy * adjy) * (1.0F/FIXED_SCALE); - dtOuter = dtdy + dxOuter * dtdx; - u0 = vLower->texcoord[0][2] * invW; - uLeft = u0 + (dudx * adjx + dudy * adjy) * (1.0F/FIXED_SCALE); - duOuter = dudy + dxOuter * dudx; - v0 = vLower->texcoord[0][3] * invW; - vLeft = v0 + (dvdx * adjx + dvdy * adjy) * (1.0F/FIXED_SCALE); - dvOuter = dvdy + dxOuter * dvdx; + s0 = vLower->attrib[FRAG_ATTRIB_TEX0][0] * S_SCALE; + sLeft = (GLfixed)(s0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][0] * adjx + + span.attrStepY[FRAG_ATTRIB_TEX0][0] * adjy) + FIXED_HALF; + dsOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][0]); + + t0 = vLower->attrib[FRAG_ATTRIB_TEX0][1] * T_SCALE; + tLeft = (GLfixed)(t0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][1] * adjx + + span.attrStepY[FRAG_ATTRIB_TEX0][1] * adjy) + FIXED_HALF; + dtOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][1]); } #endif -#ifdef INTERP_MULTITEX - { - GLuint u; - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - GLfloat invW = vLower->win[3]; - GLfloat s0, t0, u0, v0; - s0 = vLower->texcoord[u][0] * invW; - sLeft[u] = s0 + (dsdx[u] * adjx + dsdy[u] * adjy) * (1.0F/FIXED_SCALE); - dsOuter[u] = dsdy[u] + dxOuter * dsdx[u]; - t0 = vLower->texcoord[u][1] * invW; - tLeft[u] = t0 + (dtdx[u] * adjx + dtdy[u] * adjy) * (1.0F/FIXED_SCALE); - dtOuter[u] = dtdy[u] + dxOuter * dtdx[u]; - u0 = vLower->texcoord[u][2] * invW; - uLeft[u] = u0 + (dudx[u] * adjx + dudy[u] * adjy) * (1.0F/FIXED_SCALE); - duOuter[u] = dudy[u] + dxOuter * dudx[u]; - v0 = vLower->texcoord[u][3] * invW; - vLeft[u] = v0 + (dvdx[u] * adjx + dvdy[u] * adjy) * (1.0F/FIXED_SCALE); - dvOuter[u] = dvdy[u] + dxOuter * dvdx[u]; - } - } - } +#ifdef INTERP_TEX + TEXVAR_LOOP( + const GLfloat invW = vLower->win[3]; + const GLfloat s0 = vLower->attrib[attr][0] * invW; + const GLfloat t0 = vLower->attrib[attr][1] * invW; + const GLfloat u0 = vLower->attrib[attr][2] * invW; + const GLfloat v0 = vLower->attrib[attr][3] * invW; + sLeft[attr] = s0 + (span.attrStepX[attr][0] * adjx + span.attrStepY[attr][0] * adjy) * (1.0F/FIXED_SCALE); + tLeft[attr] = t0 + (span.attrStepX[attr][1] * adjx + span.attrStepY[attr][1] * adjy) * (1.0F/FIXED_SCALE); + uLeft[attr] = u0 + (span.attrStepX[attr][2] * adjx + span.attrStepY[attr][2] * adjy) * (1.0F/FIXED_SCALE); + vLeft[attr] = v0 + (span.attrStepX[attr][3] * adjx + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE); + dsOuter[attr] = span.attrStepY[attr][0] + dxOuter * span.attrStepX[attr][0]; + dtOuter[attr] = span.attrStepY[attr][1] + dxOuter * span.attrStepX[attr][1]; + duOuter[attr] = span.attrStepY[attr][2] + dxOuter * span.attrStepX[attr][2]; + dvOuter[attr] = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3]; + ) #endif - } /*if setupLeft*/ if (setupRight && eRight->lines>0) { +#if TRIANGLE_WALK_DOUBLE + fxRightEdge = eRight->fsx; + fdxRightEdge = eRight->dxdy; +#else fxRightEdge = eRight->fsx - FIXED_EPSILON; fdxRightEdge = eRight->fdxdy; +#endif } if (lines==0) { @@ -831,164 +1042,119 @@ # ifdef DEPTH_TYPE dZRowInner = dZRowOuter + sizeof(DEPTH_TYPE); # endif - fdzInner = fdzOuter + fdzdx; - fdfogInner = fdfogOuter + fdfogdx; + fdzInner = fdzOuter + span.zStep; #endif -#ifdef INTERP_RGB - fdrInner = fdrOuter + fdrdx; - fdgInner = fdgOuter + fdgdx; - fdbInner = fdbOuter + fdbdx; +#ifdef INTERP_W + dwInner = dwOuter + span.attrStepX[FRAG_ATTRIB_WPOS][3]; #endif -#ifdef INTERP_SPEC - fdsrInner = fdsrOuter + fdsrdx; - fdsgInner = fdsgOuter + fdsgdx; - fdsbInner = fdsbOuter + fdsbdx; +#ifdef INTERP_FOG + dfogInner = dfogOuter + span.attrStepX[FRAG_ATTRIB_FOGC][0]; +#endif +#ifdef INTERP_RGB + fdrInner = fdrOuter + span.redStep; + fdgInner = fdgOuter + span.greenStep; + fdbInner = fdbOuter + span.blueStep; #endif #ifdef INTERP_ALPHA - fdaInner = fdaOuter + fdadx; + fdaInner = fdaOuter + span.alphaStep; +#endif +#ifdef INTERP_SPEC + dsrInner = dsrOuter + span.specRedStep; + dsgInner = dsgOuter + span.specGreenStep; + dsbInner = dsbOuter + span.specBlueStep; #endif #ifdef INTERP_INDEX - fdiInner = fdiOuter + fdidx; + diInner = diOuter + span.indexStep; #endif #ifdef INTERP_INT_TEX - fdsInner = fdsOuter + fdsdx; - fdtInner = fdtOuter + fdtdx; + dsInner = dsOuter + span.intTexStep[0]; + dtInner = dtOuter + span.intTexStep[1]; #endif #ifdef INTERP_TEX - dsInner = dsOuter + dsdx; - dtInner = dtOuter + dtdx; - duInner = duOuter + dudx; - dvInner = dvOuter + dvdx; -#endif -#ifdef INTERP_MULTITEX - { - GLuint u; - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - dsInner[u] = dsOuter[u] + dsdx[u]; - dtInner[u] = dtOuter[u] + dtdx[u]; - duInner[u] = duOuter[u] + dudx[u]; - dvInner[u] = dvOuter[u] + dvdx[u]; - } - } - } + TEXVAR_LOOP( + dsInner[attr] = dsOuter[attr] + span.attrStepX[attr][0]; + dtInner[attr] = dtOuter[attr] + span.attrStepX[attr][1]; + duInner[attr] = duOuter[attr] + span.attrStepX[attr][2]; + dvInner[attr] = dvOuter[attr] + span.attrStepX[attr][3]; + ) #endif - while (lines>0) { + while (lines > 0) { /* initialize the span interpolants to the leftmost value */ /* ff = fixed-pt fragment */ - GLint left = FixedToInt(fxLeftEdge); - GLint right = FixedToInt(fxRightEdge); + const GLint right = InterpToInt(fxRightEdge); + span.x = InterpToInt(fxLeftEdge); + if (right <= span.x) + span.end = 0; + else + span.end = right - span.x; + #ifdef INTERP_Z - GLfixed ffz = fz; - GLfixed fffog = ffog; + span.z = zLeft; #endif -#ifdef INTERP_RGB - GLfixed ffr = fr, ffg = fg, ffb = fb; +#ifdef INTERP_W + span.attrStart[FRAG_ATTRIB_WPOS][3] = wLeft; #endif -#ifdef INTERP_SPEC - GLfixed ffsr = fsr, ffsg = fsg, ffsb = fsb; +#ifdef INTERP_FOG + span.attrStart[FRAG_ATTRIB_FOGC][0] = fogLeft; +#endif +#ifdef INTERP_RGB + span.red = rLeft; + span.green = gLeft; + span.blue = bLeft; #endif #ifdef INTERP_ALPHA - GLfixed ffa = fa; + span.alpha = aLeft; +#endif +#ifdef INTERP_SPEC + span.specRed = srLeft; + span.specGreen = sgLeft; + span.specBlue = sbLeft; #endif #ifdef INTERP_INDEX - GLfixed ffi = fi; + span.index = iLeft; #endif #ifdef INTERP_INT_TEX - GLfixed ffs = fs, fft = ft; + span.intTex[0] = sLeft; + span.intTex[1] = tLeft; #endif + #ifdef INTERP_TEX - GLfloat ss = sLeft, tt = tLeft, uu = uLeft, vv = vLeft; -#endif -#ifdef INTERP_MULTITEX - GLfloat ss[MAX_TEXTURE_UNITS]; - GLfloat tt[MAX_TEXTURE_UNITS]; - GLfloat uu[MAX_TEXTURE_UNITS]; - GLfloat vv[MAX_TEXTURE_UNITS]; - { - GLuint u; - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - ss[u] = sLeft[u]; - tt[u] = tLeft[u]; - uu[u] = uLeft[u]; - vv[u] = vLeft[u]; - } - } - } + TEXVAR_LOOP( + span.attrStart[attr][0] = sLeft[attr]; + span.attrStart[attr][1] = tLeft[attr]; + span.attrStart[attr][2] = uLeft[attr]; + span.attrStart[attr][3] = vLeft[attr]; + ) #endif + /* This is where we actually generate fragments */ + /* XXX the test for span.y > 0 _shouldn't_ be needed but + * it fixes a problem on 64-bit Opterons (bug 4842). + */ + if (span.end > 0 && span.y >= 0) { + const GLint len = span.end - 1; + (void) len; #ifdef INTERP_RGB - { - /* need this to accomodate round-off errors */ - GLfixed ffrend = ffr+(right-left-1)*fdrdx; - GLfixed ffgend = ffg+(right-left-1)*fdgdx; - GLfixed ffbend = ffb+(right-left-1)*fdbdx; - if (ffrend<0) ffr -= ffrend; - if (ffgend<0) ffg -= ffgend; - if (ffbend<0) ffb -= ffbend; - if (ffr<0) ffr = 0; - if (ffg<0) ffg = 0; - if (ffb<0) ffb = 0; - } -#endif -#ifdef INTERP_SPEC - { - /* need this to accomodate round-off errors */ - GLfixed ffsrend = ffsr+(right-left-1)*fdsrdx; - GLfixed ffsgend = ffsg+(right-left-1)*fdsgdx; - GLfixed ffsbend = ffsb+(right-left-1)*fdsbdx; - if (ffsrend<0) ffsr -= ffsrend; - if (ffsgend<0) ffsg -= ffsgend; - if (ffsbend<0) ffsb -= ffsbend; - if (ffsr<0) ffsr = 0; - if (ffsg<0) ffsg = 0; - if (ffsb<0) ffsb = 0; - } + CLAMP_INTERPOLANT(red, redStep, len); + CLAMP_INTERPOLANT(green, greenStep, len); + CLAMP_INTERPOLANT(blue, blueStep, len); #endif #ifdef INTERP_ALPHA - { - GLfixed ffaend = ffa+(right-left-1)*fdadx; - if (ffaend<0) ffa -= ffaend; - if (ffa<0) ffa = 0; - } + CLAMP_INTERPOLANT(alpha, alphaStep, len); +#endif +#ifdef INTERP_SPEC + CLAMP_INTERPOLANT(specRed, specRedStep, len); + CLAMP_INTERPOLANT(specGreen, specGreenStep, len); + CLAMP_INTERPOLANT(specBlue, specBlueStep, len); #endif #ifdef INTERP_INDEX - if (ffi<0) ffi = 0; + CLAMP_INTERPOLANT(index, indexStep, len); #endif - -#ifdef INTERP_LAMBDA -/* - * The lambda value is: - * log_2(sqrt(f(n))) = 1/2*log_2(f(n)), where f(n) is a function - * defined by - * f(n):= dudx * dudx + dudy * dudy + dvdx * dvdx + dvdy * dvdy; - * and each of this terms is resp. - * dudx = dsdx * invQ(n) * tex_width; - * dudy = dsdy * invQ(n) * tex_width; - * dvdx = dtdx * invQ(n) * tex_height; - * dvdy = dtdy * invQ(n) * tex_height; - * Therefore the function lambda can be represented (by factoring out) as: - * f(n) = lambda_nominator * invQ(n) * invQ(n), - * which saves some computation time. - */ - { - GLfloat dudx = dsdx /* * invQ*/ * twidth; - GLfloat dudy = dsdy /* * invQ*/ * twidth; - GLfloat dvdx = dtdx /* * invQ*/ * theight; - GLfloat dvdy = dtdy /* * invQ*/ * theight; - GLfloat r1 = dudx * dudx + dudy * dudy; - GLfloat r2 = dvdx * dvdx + dvdy * dvdy; - GLfloat rho2 = r1 + r2; /* used to be: rho2 = MAX2(r1,r2); */ - lambda_nominator = rho2; - } - - /* return log base 2 of sqrt(rho) */ -#define COMPUTE_LAMBDA(X) log( lambda_nominator * (X)*(X) ) * 1.442695F * 0.5F /* 1.442695 = 1/log(2) */ -#endif - - INNER_LOOP( left, right, iy ); + { + RENDER_SPAN( span ); + } + } /* * Advance to the next scan line. Compute the @@ -996,105 +1162,103 @@ * pixel-center x coordinate so that it stays * on or inside the major edge. */ - iy++; + span.y++; lines--; fxLeftEdge += fdxLeftEdge; fxRightEdge += fdxRightEdge; - fError += fdError; if (fError >= 0) { - fError -= FIXED_ONE; + fError -= INTERP_ONE; + #ifdef PIXEL_ADDRESS - pRow = (PIXEL_TYPE *) ((GLubyte*)pRow + dPRowOuter); + pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter); #endif #ifdef INTERP_Z # ifdef DEPTH_TYPE - zRow = (DEPTH_TYPE *) ((GLubyte*)zRow + dZRowOuter); + zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowOuter); # endif - fz += fdzOuter; - ffog += fdfogOuter; + zLeft += fdzOuter; #endif -#ifdef INTERP_RGB - fr += fdrOuter; fg += fdgOuter; fb += fdbOuter; +#ifdef INTERP_W + wLeft += dwOuter; #endif -#ifdef INTERP_SPEC - fsr += fdsrOuter; fsg += fdsgOuter; fsb += fdsbOuter; +#ifdef INTERP_FOG + fogLeft += dfogOuter; +#endif +#ifdef INTERP_RGB + rLeft += fdrOuter; + gLeft += fdgOuter; + bLeft += fdbOuter; #endif #ifdef INTERP_ALPHA - fa += fdaOuter; + aLeft += fdaOuter; +#endif +#ifdef INTERP_SPEC + srLeft += dsrOuter; + sgLeft += dsgOuter; + sbLeft += dsbOuter; #endif #ifdef INTERP_INDEX - fi += fdiOuter; + iLeft += diOuter; #endif #ifdef INTERP_INT_TEX - fs += fdsOuter; ft += fdtOuter; + sLeft += dsOuter; + tLeft += dtOuter; #endif #ifdef INTERP_TEX - sLeft += dsOuter; - tLeft += dtOuter; - uLeft += duOuter; - vLeft += dvOuter; -#endif -#ifdef INTERP_MULTITEX - { - GLuint u; - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - sLeft[u] += dsOuter[u]; - tLeft[u] += dtOuter[u]; - uLeft[u] += duOuter[u]; - vLeft[u] += dvOuter[u]; - } - } - } + TEXVAR_LOOP( + sLeft[attr] += dsOuter[attr]; + tLeft[attr] += dtOuter[attr]; + uLeft[attr] += duOuter[attr]; + vLeft[attr] += dvOuter[attr]; + ) #endif } else { #ifdef PIXEL_ADDRESS - pRow = (PIXEL_TYPE *) ((GLubyte*)pRow + dPRowInner); + pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowInner); #endif #ifdef INTERP_Z # ifdef DEPTH_TYPE - zRow = (DEPTH_TYPE *) ((GLubyte*)zRow + dZRowInner); + zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowInner); # endif - fz += fdzInner; - ffog += fdfogInner; + zLeft += fdzInner; #endif -#ifdef INTERP_RGB - fr += fdrInner; fg += fdgInner; fb += fdbInner; +#ifdef INTERP_W + wLeft += dwInner; #endif -#ifdef INTERP_SPEC - fsr += fdsrInner; fsg += fdsgInner; fsb += fdsbInner; +#ifdef INTERP_FOG + fogLeft += dfogInner; +#endif +#ifdef INTERP_RGB + rLeft += fdrInner; + gLeft += fdgInner; + bLeft += fdbInner; #endif #ifdef INTERP_ALPHA - fa += fdaInner; + aLeft += fdaInner; +#endif +#ifdef INTERP_SPEC + srLeft += dsrInner; + sgLeft += dsgInner; + sbLeft += dsbInner; #endif #ifdef INTERP_INDEX - fi += fdiInner; + iLeft += diInner; #endif #ifdef INTERP_INT_TEX - fs += fdsInner; ft += fdtInner; + sLeft += dsInner; + tLeft += dtInner; #endif #ifdef INTERP_TEX - sLeft += dsInner; - tLeft += dtInner; - uLeft += duInner; - vLeft += dvInner; -#endif -#ifdef INTERP_MULTITEX - { - GLuint u; - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - sLeft[u] += dsInner[u]; - tLeft[u] += dtInner[u]; - uLeft[u] += duInner[u]; - vLeft[u] += dvInner[u]; - } - } - } + TEXVAR_LOOP( + sLeft[attr] += dsInner[attr]; + tLeft[attr] += dtInner[attr]; + uLeft[attr] += duInner[attr]; + vLeft[attr] += dvInner[attr]; + ) #endif } } /*while lines>0*/ @@ -1102,30 +1266,40 @@ } /* for subTriangle */ } +#ifdef CLEANUP_CODE + CLEANUP_CODE +#endif } } #undef SETUP_CODE -#undef INNER_LOOP +#undef CLEANUP_CODE +#undef RENDER_SPAN #undef PIXEL_TYPE #undef BYTES_PER_ROW #undef PIXEL_ADDRESS +#undef DEPTH_TYPE #undef INTERP_Z +#undef INTERP_W +#undef INTERP_FOG #undef INTERP_RGB -#undef INTERP_SPEC #undef INTERP_ALPHA +#undef INTERP_SPEC #undef INTERP_INDEX -#undef INTERP_LAMBDA -#undef COMPUTE_LAMBDA #undef INTERP_INT_TEX #undef INTERP_TEX -#undef INTERP_MULTITEX +#undef TEX_UNIT_LOOP +#undef VARYING_LOOP #undef S_SCALE #undef T_SCALE #undef FixedToDepth +#undef ColorTemp +#undef GLinterp +#undef InterpToInt +#undef INTERP_ONE -#undef DO_OCCLUSION_TEST +#undef NAME