X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fswrast%2Fs_tritemp.h;h=061759d26d2dc96e87a35732bd8966c2efb3cab8;hb=267fb178844d3f17503dd0f921791f3ab059c4e7;hp=3362f3892d104e9b98a13879cfe19590d1112e26;hpb=1e4731f6443a6efdfc4e425977490ddd5387caa3;p=mesa.git diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h index 3362f3892d1..061759d26d2 100644 --- a/src/mesa/swrast/s_tritemp.h +++ b/src/mesa/swrast/s_tritemp.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.1 + * Version: 7.0 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * 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"), @@ -28,19 +28,16 @@ * 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 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_INDEX - if defined, interpolate color index values + * must be interpolated across the triangle: + * INTERP_Z - if defined, interpolate integer Z values + * INTERP_RGB - if defined, interpolate integer RGB values + * INTERP_ALPHA - if defined, interpolate integer Alpha values * INTERP_INT_TEX - if defined, interpolate integer ST texcoords - * (fast, simple 2-D texture mapping) - * INTERP_TEX - if defined, interpolate set 0 float STRQ texcoords - * NOTE: OpenGL STRQ = Mesa STUV (R was taken for red) - * INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords + * (fast, simple 2-D texture mapping, without + * perspective correction) + * INTERP_ATTRIBS - if defined, interpolate arbitrary attribs (texcoords, + * varying vars, etc) This also causes W to be + * computed for perspective correction). * * When one can directly address pixels in the color buffer the following * macros can be defined and used to compute pixel addresses during @@ -51,12 +48,11 @@ * Y==0 at bottom of screen and increases upward. * * Similarly, for direct depth buffer access, this type is used for depth - * buffer addressing: + * buffer addressing (see zRow): * DEPTH_TYPE - either GLushort or GLuint * * Optionally, one may provide one-time setup code per triangle: * SETUP_CODE - code which is to be executed once per triangle - * CLEANUP_CODE - code to execute at end of triangle * * The following macro MUST be defined: * RENDER_SPAN(span) - code to write a span of pixels. @@ -94,81 +90,46 @@ * SUB_PIXEL_BITS. */ -/* - * ColorTemp is used for intermediate color values. - */ -#if CHAN_TYPE == GL_FLOAT -#define ColorTemp GLfloat -#else -#define ColorTemp GLint /* same as GLfixed */ -#endif - /* - * Walk triangle edges with GLfixed or GLdouble + * Some code we unfortunately need to prevent negative interpolated colors. */ -#if TRIANGLE_WALK_DOUBLE -#define GLinterp GLdouble -#define InterpToInt(X) ((GLint) (X)) -#define INTERP_ONE 1.0 -#else -#define GLinterp GLfixed -#define InterpToInt(X) FixedToInt(X) -#define INTERP_ONE FIXED_ONE +#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 -/* - * Either loop over all texture units, or just use unit zero. - */ -#ifdef INTERP_MULTITEX -#define TEX_UNIT_LOOP(CODE) \ - { \ - GLuint u; \ - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \ - if (ctx->Texture._EnabledCoordUnits & (1 << u)) { \ - CODE \ - } \ - } \ - } -#define INTERP_TEX -#elif defined(INTERP_TEX) -#define TEX_UNIT_LOOP(CODE) \ - { \ - const GLuint u = 0; \ - CODE \ - } -#endif - - -static void NAME(GLcontext *ctx, const SWvertex *v0, +static void NAME(struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1, const SWvertex *v2 ) { typedef struct { 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 */ -#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 */ -#endif GLfixed fsx; /* first sample point x coord */ GLfixed fsy; - GLint lines; /* number of lines to be sampled on this edge */ GLfixed fx0; /* fixed pt X of lower endpoint */ + 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; @@ -178,9 +139,12 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */ GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy; - struct sw_span span; + SWspan span; + + (void) swrast; - INIT_SPAN(span, GL_POLYGON, 0, 0, 0); + INIT_SPAN(span, GL_POLYGON); + span.y = 0; /* silence warnings */ #ifdef INTERP_Z (void) fixedToDepthShift; @@ -188,22 +152,27 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, /* 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]); + printf(" %g, %g, %g\n", + v0->attrib[FRAG_ATTRIB_WPOS][0], + v0->attrib[FRAG_ATTRIB_WPOS][1], + v0->attrib[FRAG_ATTRIB_WPOS][2]); + printf(" %g, %g, %g\n", + v1->attrib[FRAG_ATTRIB_WPOS][0], + v1->attrib[FRAG_ATTRIB_WPOS][1], + v1->attrib[FRAG_ATTRIB_WPOS][2]); + printf(" %g, %g, %g\n", + v2->attrib[FRAG_ATTRIB_WPOS][0], + v2->attrib[FRAG_ATTRIB_WPOS][1], + v2->attrib[FRAG_ATTRIB_WPOS][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. */ { - 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; - + const GLfixed fy0 = FloatToFixed(v0->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask; + const GLfixed fy1 = FloatToFixed(v1->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask; + const GLfixed fy2 = FloatToFixed(v2->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask; if (fy0 <= fy1) { if (fy1 <= fy2) { /* y0 <= y1 <= y2 */ @@ -243,9 +212,9 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, } /* fixed point X coords */ - 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; + vMin_fx = FloatToFixed(vMin->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask; + vMid_fx = FloatToFixed(vMid->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask; + vMax_fx = FloatToFixed(vMax->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask; } /* vertex/edge relationship */ @@ -254,40 +223,28 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, eBot.v0 = vMin; eBot.v1 = vMid; /* compute deltas for each edge: vertex[upper] - vertex[lower] */ -#if TRIANGLE_WALK_DOUBLE - eMaj.dx = FixedToDouble(vMax_fx - vMin_fx); - eMaj.dy = FixedToDouble(vMax_fy - vMin_fy); - eTop.dx = FixedToDouble(vMax_fx - vMid_fx); - eTop.dy = FixedToDouble(vMax_fy - vMid_fy); - eBot.dx = FixedToDouble(vMid_fx - vMin_fx); - eBot.dy = FixedToDouble(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 */ { const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy; - /* Do backface culling */ - if (area * bf < 0.0) + if (IS_INF_OR_NAN(area) || area == 0.0F) return; - if (IS_INF_OR_NAN(area) || area == 0.0F) + if (area * bf * swrast->_BackfaceCullSign < 0.0) return; oneOverArea = 1.0F / area; - } -#ifndef DO_OCCLUSION_TEST - ctx->OcclusionResult = GL_TRUE; -#endif - span.facing = ctx->_Facing; /* for 2-sided stencil test */ + /* 0 = front, 1 = back */ + span.facing = oneOverArea * bf > 0.0F; + } /* Edge setup. For a triangle strip these could be reused... */ { @@ -295,9 +252,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy)); if (eMaj.lines > 0) { eMaj.dxdy = eMaj.dx / eMaj.dy; -#ifndef INTERP_DOUBLE eMaj.fdxdy = SignedFloatToFixed(eMaj.dxdy); -#endif eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy); /* SCALED! */ eMaj.fx0 = vMin_fx; eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * eMaj.dxdy); @@ -310,9 +265,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy)); if (eTop.lines > 0) { eTop.dxdy = eTop.dx / eTop.dy; -#ifndef INTERP_DOUBLE eTop.fdxdy = SignedFloatToFixed(eTop.dxdy); -#endif eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */ eTop.fx0 = vMid_fx; eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * eTop.dxdy); @@ -322,9 +275,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy)); if (eBot.lines > 0) { eBot.dxdy = eBot.dx / eBot.dy; -#ifndef INTERP_DOUBLE eBot.fdxdy = SignedFloatToFixed(eBot.dxdy); -#endif eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy); /* SCALED! */ eBot.fx0 = vMin_fx; eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * eBot.dxdy); @@ -367,9 +318,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, { GLint scan_from_left_to_right; /* true if scanning left-to-right */ -#ifdef INTERP_INDEX - GLfloat didx, didy; -#endif /* * Execute user-supplied setup code @@ -385,204 +333,108 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_Z span.interpMask |= SPAN_Z; { - GLfloat eMaj_dz = vMax->win[2] - vMin->win[2]; - GLfloat eBot_dz = vMid->win[2] - vMin->win[2]; - span.dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz); - if (span.dzdx > maxDepth || span.dzdx < -maxDepth) { + GLfloat eMaj_dz = vMax->attrib[FRAG_ATTRIB_WPOS][2] - vMin->attrib[FRAG_ATTRIB_WPOS][2]; + GLfloat eBot_dz = vMid->attrib[FRAG_ATTRIB_WPOS][2] - vMin->attrib[FRAG_ATTRIB_WPOS][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 */ - span.dzdx = 0.0; - span.dzdy = 0.0; + span.attrStepX[FRAG_ATTRIB_WPOS][2] = 0.0; + span.attrStepY[FRAG_ATTRIB_WPOS][2] = 0.0; } else { - span.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) - span.zStep = SignedFloatToFixed(span.dzdx); + span.zStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_WPOS][2]); else - span.zStep = (GLint) span.dzdx; - } -#endif -#ifdef INTERP_W - span.interpMask |= SPAN_W; - { - const GLfloat eMaj_dw = vMax->win[3] - vMin->win[3]; - const GLfloat eBot_dw = vMid->win[3] - vMin->win[3]; - span.dwdx = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw); - span.dwdy = 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.dfogdx = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog); - span.dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx); - span.fogStep = span.dfogdx; + span.zStep = (GLint) span.attrStepX[FRAG_ATTRIB_WPOS][2]; } #endif #ifdef INTERP_RGB span.interpMask |= SPAN_RGBA; if (ctx->Light.ShadeModel == GL_SMOOTH) { - GLfloat eMaj_dr = (GLfloat) ((ColorTemp) vMax->color[RCOMP] - vMin->color[RCOMP]); - GLfloat eBot_dr = (GLfloat) ((ColorTemp) vMid->color[RCOMP] - vMin->color[RCOMP]); - GLfloat eMaj_dg = (GLfloat) ((ColorTemp) vMax->color[GCOMP] - vMin->color[GCOMP]); - GLfloat eBot_dg = (GLfloat) ((ColorTemp) vMid->color[GCOMP] - vMin->color[GCOMP]); - GLfloat eMaj_db = (GLfloat) ((ColorTemp) vMax->color[BCOMP] - vMin->color[BCOMP]); - GLfloat eBot_db = (GLfloat) ((ColorTemp) vMid->color[BCOMP] - vMin->color[BCOMP]); + GLfloat eMaj_dr = (GLfloat) (vMax->color[RCOMP] - vMin->color[RCOMP]); + GLfloat eBot_dr = (GLfloat) (vMid->color[RCOMP] - vMin->color[RCOMP]); + GLfloat eMaj_dg = (GLfloat) (vMax->color[GCOMP] - vMin->color[GCOMP]); + GLfloat eBot_dg = (GLfloat) (vMid->color[GCOMP] - vMin->color[GCOMP]); + GLfloat eMaj_db = (GLfloat) (vMax->color[BCOMP] - vMin->color[BCOMP]); + GLfloat eBot_db = (GLfloat) (vMid->color[BCOMP] - vMin->color[BCOMP]); # ifdef INTERP_ALPHA - GLfloat eMaj_da = (GLfloat) ((ColorTemp) vMax->color[ACOMP] - vMin->color[ACOMP]); - GLfloat eBot_da = (GLfloat) ((ColorTemp) vMid->color[ACOMP] - vMin->color[ACOMP]); + GLfloat eMaj_da = (GLfloat) (vMax->color[ACOMP] - vMin->color[ACOMP]); + GLfloat eBot_da = (GLfloat) (vMid->color[ACOMP] - vMin->color[ACOMP]); # endif - span.drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr); - span.drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx); - span.dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg); - span.dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx); - span.dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db); - span.dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx); -# if CHAN_TYPE == GL_FLOAT - span.redStep = span.drdx; - span.greenStep = span.dgdx; - span.blueStep = span.dbdx; -# else - span.redStep = SignedFloatToFixed(span.drdx); - span.greenStep = SignedFloatToFixed(span.dgdx); - span.blueStep = SignedFloatToFixed(span.dbdx); -# endif /* GL_FLOAT */ + 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); + 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]); # ifdef INTERP_ALPHA - span.dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); - span.dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); -# if CHAN_TYPE == GL_FLOAT - span.alphaStep = span.dadx; -# else - span.alphaStep = SignedFloatToFixed(span.dadx); -# endif /* GL_FLOAT */ + span.attrStepX[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); + span.attrStepY[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); + span.alphaStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3]); # endif /* INTERP_ALPHA */ } else { - ASSERT (ctx->Light.ShadeModel == GL_FLAT); + ASSERT(ctx->Light.ShadeModel == GL_FLAT); span.interpMask |= SPAN_FLAT; - span.drdx = span.drdy = 0.0F; - span.dgdx = span.dgdy = 0.0F; - span.dbdx = span.dbdy = 0.0F; -# if CHAN_TYPE == GL_FLOAT - span.redStep = 0.0F; - span.greenStep = 0.0F; - span.blueStep = 0.0F; -# else + 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; span.redStep = 0; span.greenStep = 0; span.blueStep = 0; -# endif /* GL_FLOAT */ # ifdef INTERP_ALPHA - span.dadx = span.dady = 0.0F; -# if CHAN_TYPE == GL_FLOAT - span.alphaStep = 0.0F; -# else + span.attrStepX[FRAG_ATTRIB_COL0][3] = span.attrStepY[FRAG_ATTRIB_COL0][3] = 0.0F; span.alphaStep = 0; -# endif /* GL_FLOAT */ # endif } #endif /* INTERP_RGB */ -#ifdef INTERP_SPEC - span.interpMask |= SPAN_SPEC; - if (ctx->Light.ShadeModel == GL_SMOOTH) { - GLfloat eMaj_dsr = (GLfloat) ((ColorTemp) vMax->specular[RCOMP] - vMin->specular[RCOMP]); - GLfloat eBot_dsr = (GLfloat) ((ColorTemp) vMid->specular[RCOMP] - vMin->specular[RCOMP]); - GLfloat eMaj_dsg = (GLfloat) ((ColorTemp) vMax->specular[GCOMP] - vMin->specular[GCOMP]); - GLfloat eBot_dsg = (GLfloat) ((ColorTemp) vMid->specular[GCOMP] - vMin->specular[GCOMP]); - GLfloat eMaj_dsb = (GLfloat) ((ColorTemp) vMax->specular[BCOMP] - vMin->specular[BCOMP]); - GLfloat eBot_dsb = (GLfloat) ((ColorTemp) vMid->specular[BCOMP] - vMin->specular[BCOMP]); - span.dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr); - span.dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx); - span.dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg); - span.dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx); - span.dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb); - span.dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx); -# if CHAN_TYPE == GL_FLOAT - span.specRedStep = span.dsrdx; - span.specGreenStep = span.dsgdx; - span.specBlueStep = span.dsbdx; -# else - span.specRedStep = SignedFloatToFixed(span.dsrdx); - span.specGreenStep = SignedFloatToFixed(span.dsgdx); - span.specBlueStep = SignedFloatToFixed(span.dsbdx); -# endif - } - else { - span.dsrdx = span.dsrdy = 0.0F; - span.dsgdx = span.dsgdy = 0.0F; - span.dsbdx = span.dsbdy = 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 /* INTERP_SPEC */ -#ifdef INTERP_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); - 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 = (vMax->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE; - GLfloat eBot_ds = (vMid->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE; - GLfloat eMaj_dt = (vMax->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE; - GLfloat eBot_dt = (vMid->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE; - span.texStepX[0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); - span.texStepY[0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); - span.texStepX[0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); - span.texStepY[0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); - span.intTexStep[0] = SignedFloatToFixed(span.texStepX[0][0]); - span.intTexStep[1] = SignedFloatToFixed(span.texStepX[0][1]); + 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; +#ifdef INTERP_ATTRIBS { - /* win[3] is 1/W */ - const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3]; - TEX_UNIT_LOOP( - GLfloat eMaj_ds = vMax->texcoord[u][0] * wMax - vMin->texcoord[u][0] * wMin; - GLfloat eBot_ds = vMid->texcoord[u][0] * wMid - vMin->texcoord[u][0] * wMin; - GLfloat eMaj_dt = vMax->texcoord[u][1] * wMax - vMin->texcoord[u][1] * wMin; - GLfloat eBot_dt = vMid->texcoord[u][1] * wMid - vMin->texcoord[u][1] * wMin; - GLfloat eMaj_du = vMax->texcoord[u][2] * wMax - vMin->texcoord[u][2] * wMin; - GLfloat eBot_du = vMid->texcoord[u][2] * wMid - vMin->texcoord[u][2] * wMin; - GLfloat eMaj_dv = vMax->texcoord[u][3] * wMax - vMin->texcoord[u][3] * wMin; - GLfloat eBot_dv = vMid->texcoord[u][3] * wMid - vMin->texcoord[u][3] * wMin; - span.texStepX[u][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); - span.texStepY[u][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); - span.texStepX[u][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); - span.texStepY[u][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); - span.texStepX[u][2] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du); - span.texStepY[u][2] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx); - span.texStepX[u][3] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv); - span.texStepY[u][3] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx); - ) + /* attrib[FRAG_ATTRIB_WPOS][3] is 1/W */ + const GLfloat wMax = vMax->attrib[FRAG_ATTRIB_WPOS][3]; + const GLfloat wMin = vMin->attrib[FRAG_ATTRIB_WPOS][3]; + const GLfloat wMid = vMid->attrib[FRAG_ATTRIB_WPOS][3]; + { + const GLfloat eMaj_dw = wMax - wMin; + const GLfloat eBot_dw = wMid - wMin; + 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); + } + ATTRIB_LOOP_BEGIN + if (swrast->_InterpMode[attr] == GL_FLAT) { + ASSIGN_4V(span.attrStepX[attr], 0.0, 0.0, 0.0, 0.0); + ASSIGN_4V(span.attrStepY[attr], 0.0, 0.0, 0.0, 0.0); + } + else { + GLuint c; + for (c = 0; c < 4; c++) { + GLfloat eMaj_da = vMax->attrib[attr][c] * wMax - vMin->attrib[attr][c] * wMin; + GLfloat eBot_da = vMid->attrib[attr][c] * wMid - vMin->attrib[attr][c] * wMin; + span.attrStepX[attr][c] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); + span.attrStepY[attr][c] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); + } + } + ATTRIB_LOOP_END } #endif @@ -635,55 +487,39 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, { GLint subTriangle; - GLinterp fxLeftEdge = 0, fxRightEdge = 0; - GLinterp fdxLeftEdge = 0, fdxRightEdge = 0; - GLinterp fError = 0, fdError = 0; + GLfixed fxLeftEdge = 0, fxRightEdge = 0; + GLfixed fdxLeftEdge = 0, fdxRightEdge = 0; + GLfixed fError = 0, fdError = 0; #ifdef PIXEL_ADDRESS PIXEL_TYPE *pRow = NULL; GLint dPRowOuter = 0, dPRowInner; /* offset in bytes */ #endif #ifdef INTERP_Z # ifdef DEPTH_TYPE + struct gl_renderbuffer *zrb + = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; DEPTH_TYPE *zRow = NULL; GLint dZRowOuter = 0, dZRowInner; /* offset in bytes */ # endif - GLfixed zLeft = 0, fdzOuter = 0, fdzInner; -#endif -#ifdef INTERP_W - GLfloat wLeft = 0, dwOuter = 0, dwInner; -#endif -#ifdef INTERP_FOG - GLfloat fogLeft = 0, dfogOuter = 0, dfogInner; + GLuint zLeft = 0; + GLfixed fdzOuter = 0, fdzInner; #endif #ifdef INTERP_RGB - ColorTemp rLeft = 0, fdrOuter = 0, fdrInner; - ColorTemp gLeft = 0, fdgOuter = 0, fdgInner; - ColorTemp bLeft = 0, fdbOuter = 0, fdbInner; + GLint rLeft = 0, fdrOuter = 0, fdrInner; + GLint gLeft = 0, fdgOuter = 0, fdgInner; + GLint bLeft = 0, fdbOuter = 0, fdbInner; #endif #ifdef INTERP_ALPHA - 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 iLeft=0, diOuter=0, diInner; + GLint aLeft = 0, fdaOuter = 0, fdaInner; #endif #ifdef INTERP_INT_TEX GLfixed sLeft=0, dsOuter=0, dsInner; GLfixed tLeft=0, dtOuter=0, dtInner; #endif -#ifdef INTERP_TEX - GLfloat sLeft[MAX_TEXTURE_COORD_UNITS]; - GLfloat tLeft[MAX_TEXTURE_COORD_UNITS]; - GLfloat uLeft[MAX_TEXTURE_COORD_UNITS]; - GLfloat vLeft[MAX_TEXTURE_COORD_UNITS]; - GLfloat dsOuter[MAX_TEXTURE_COORD_UNITS], dsInner[MAX_TEXTURE_COORD_UNITS]; - GLfloat dtOuter[MAX_TEXTURE_COORD_UNITS], dtInner[MAX_TEXTURE_COORD_UNITS]; - GLfloat duOuter[MAX_TEXTURE_COORD_UNITS], duInner[MAX_TEXTURE_COORD_UNITS]; - GLfloat dvOuter[MAX_TEXTURE_COORD_UNITS], dvInner[MAX_TEXTURE_COORD_UNITS]; +#ifdef INTERP_ATTRIBS + GLfloat wLeft = 0, dwOuter = 0, dwInner; + GLfloat attrLeft[FRAG_ATTRIB_MAX][4]; + GLfloat daOuter[FRAG_ATTRIB_MAX][4], daInner[FRAG_ATTRIB_MAX][4]; #endif for (subTriangle=0; subTriangle<=1; subTriangle++) { @@ -730,22 +566,12 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, if (setupLeft && eLeft->lines > 0) { const SWvertex *vLower = eLeft->v0; - const GLfixed fsx = eLeft->fsx; /* no fractional part */ const GLfixed fsy = eLeft->fsy; + const GLfixed fsx = eLeft->fsx; /* no fractional part */ const GLfixed fx = FixedCeil(fsx); /* no fractional part */ - const GLinterp adjx = (GLinterp) (fx - eLeft->fx0); /* SCALED! */ - const GLinterp adjy = eLeft->adjy; /* SCALED! */ + const GLfixed adjx = (GLfixed) (fx - eLeft->fx0); /* SCALED! */ + const GLfixed adjy = (GLfixed) eLeft->adjy; /* SCALED! */ GLint idxOuter; -#if TRIANGLE_WALK_DOUBLE - GLdouble dxOuter; - - fError = FixedToFloat(fx - fsx - FIXED_ONE); - fxLeftEdge = FixedToFloat(fsx); - fdxLeftEdge = eLeft->dxdy; - dxOuter = floor(fdxLeftEdge); - fdError = dxOuter - fdxLeftEdge + 1.0; - idxOuter = (GLint) dxOuter; -#else GLfloat dxOuter; GLfixed fdxOuter; @@ -756,7 +582,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, fdError = fdxOuter - fdxLeftEdge + FIXED_ONE; idxOuter = FixedToInt(fdxOuter); dxOuter = (GLfloat) idxOuter; -#endif span.y = FixedToInt(fsy); /* silence warnings on some compilers */ @@ -767,7 +592,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef PIXEL_ADDRESS { - pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(InterpToInt(fxLeftEdge), span.y); + pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(FixedToInt(fxLeftEdge), span.y); dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE); /* negative because Y=0 at bottom and increases upward */ } @@ -784,178 +609,122 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_Z { - GLfloat z0 = vLower->win[2]; + GLfloat z0 = vLower->attrib[FRAG_ATTRIB_WPOS][2]; if (depthBits <= 16) { /* interpolate fixed-pt values */ - GLfloat tmp = (z0 * FIXED_SCALE + span.dzdx * adjx + span.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) zLeft = (GLfixed) tmp; else zLeft = MAX_GLUINT / 2; - fdzOuter = SignedFloatToFixed(span.dzdy + dxOuter * span.dzdx); + fdzOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_WPOS][2] + + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]); } else { - /* interpolate depth values exactly */ - zLeft = (GLint) (z0 + span.dzdx * FixedToFloat(adjx) + span.dzdy * FixedToFloat(adjy)); - fdzOuter = (GLint) (span.dzdy + dxOuter * span.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 *) - _swrast_zbuffer_address(ctx, InterpToInt(fxLeftEdge), span.y); + _swrast_pixel_address(zrb, FixedToInt(fxLeftEdge), span.y); dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE); # endif } #endif -#ifdef INTERP_W - wLeft = vLower->win[3] + (span.dwdx * adjx + span.dwdy * adjy) * (1.0F/FIXED_SCALE); - dwOuter = span.dwdy + dxOuter * span.dwdx; -#endif -#ifdef INTERP_FOG -# ifdef INTERP_W - fogLeft = vLower->fog * vLower->win[3] + (span.dfogdx * adjx + span.dfogdy * adjy) * (1.0F/FIXED_SCALE); -# else - fogLeft = vLower->fog + (span.dfogdx * adjx + span.dfogdy * adjy) * (1.0F/FIXED_SCALE); -# endif - dfogOuter = span.dfogdy + dxOuter * span.dfogdx; -#endif #ifdef INTERP_RGB if (ctx->Light.ShadeModel == GL_SMOOTH) { -# if CHAN_TYPE == GL_FLOAT - rLeft = vLower->color[RCOMP] + (span.drdx * adjx + span.drdy * adjy) * (1.0F / FIXED_SCALE); - gLeft = vLower->color[GCOMP] + (span.dgdx * adjx + span.dgdy * adjy) * (1.0F / FIXED_SCALE); - bLeft = vLower->color[BCOMP] + (span.dbdx * adjx + span.dbdy * adjy) * (1.0F / FIXED_SCALE); - fdrOuter = span.drdy + dxOuter * span.drdx; - fdgOuter = span.dgdy + dxOuter * span.dgdx; - fdbOuter = span.dbdy + dxOuter * span.dbdx; -# else - rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP]) + span.drdx * adjx + span.drdy * adjy) + FIXED_HALF; - gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP]) + span.dgdx * adjx + span.dgdy * adjy) + FIXED_HALF; - bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP]) + span.dbdx * adjx + span.dbdy * adjy) + FIXED_HALF; - fdrOuter = SignedFloatToFixed(span.drdy + dxOuter * span.drdx); - fdgOuter = SignedFloatToFixed(span.dgdy + dxOuter * span.dgdx); - fdbOuter = SignedFloatToFixed(span.dbdy + dxOuter * span.dbdx); -# endif + 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]); # ifdef INTERP_ALPHA -# if CHAN_TYPE == GL_FLOAT - aLeft = vLower->color[ACOMP] + (span.dadx * adjx + span.dady * adjy) * (1.0F / FIXED_SCALE); - fdaOuter = span.dady + dxOuter * span.dadx; -# else - aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP]) + span.dadx * adjx + span.dady * adjy) + FIXED_HALF; - fdaOuter = SignedFloatToFixed(span.dady + dxOuter * span.dadx); -# endif + aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP]) + + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx + + span.attrStepY[FRAG_ATTRIB_COL0][3] * adjy) + FIXED_HALF; + fdaOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][3] + + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]); # 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 + ASSERT(ctx->Light.ShadeModel == GL_FLAT); 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 +#endif /* INTERP_RGB */ -#ifdef INTERP_SPEC - if (ctx->Light.ShadeModel == GL_SMOOTH) { -# if CHAN_TYPE == GL_FLOAT - srLeft = vLower->specular[RCOMP] + (span.dsrdx * adjx + span.dsrdy * adjy) * (1.0F / FIXED_SCALE); - sgLeft = vLower->specular[GCOMP] + (span.dsgdx * adjx + span.dsgdy * adjy) * (1.0F / FIXED_SCALE); - sbLeft = vLower->specular[BCOMP] + (span.dsbdx * adjx + span.dsbdy * adjy) * (1.0F / FIXED_SCALE); - dsrOuter = span.dsrdy + dxOuter * span.dsrdx; - dsgOuter = span.dsgdy + dxOuter * span.dsgdx; - dsbOuter = span.dsbdy + dxOuter * span.dsbdx; -# else - srLeft = (GLfixed) (ChanToFixed(vLower->specular[RCOMP]) + span.dsrdx * adjx + span.dsrdy * adjy) + FIXED_HALF; - sgLeft = (GLfixed) (ChanToFixed(vLower->specular[GCOMP]) + span.dsgdx * adjx + span.dsgdy * adjy) + FIXED_HALF; - sbLeft = (GLfixed) (ChanToFixed(vLower->specular[BCOMP]) + span.dsbdx * adjx + span.dsbdy * adjy) + FIXED_HALF; - dsrOuter = SignedFloatToFixed(span.dsrdy + dxOuter * span.dsrdx); - dsgOuter = SignedFloatToFixed(span.dsgdy + dxOuter * span.dsgdx); - dsbOuter = SignedFloatToFixed(span.dsbdy + dxOuter * span.dsbdx); -# endif - } - else { -#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 - if (ctx->Light.ShadeModel == GL_SMOOTH) { - iLeft = (GLfixed)(vLower->index * FIXED_SCALE - + didx * adjx + didy * adjy) + FIXED_HALF; - diOuter = SignedFloatToFixed(didy + dxOuter * didx); - } - else { - iLeft = FloatToFixed(v2->index); - diOuter = 0; - } -#endif #ifdef INTERP_INT_TEX { GLfloat s0, t0; - s0 = vLower->texcoord[0][0] * S_SCALE; - sLeft = (GLfixed)(s0 * FIXED_SCALE + span.texStepX[0][0] * adjx - + span.texStepY[0][0] * adjy) + FIXED_HALF; - dsOuter = SignedFloatToFixed(span.texStepY[0][0] + dxOuter * span.texStepX[0][0]); - - t0 = vLower->texcoord[0][1] * T_SCALE; - tLeft = (GLfixed)(t0 * FIXED_SCALE + span.texStepX[0][1] * adjx - + span.texStepY[0][1] * adjy) + FIXED_HALF; - dtOuter = SignedFloatToFixed(span.texStepY[0][1] + dxOuter * span.texStepX[0][1]); + 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_TEX - TEX_UNIT_LOOP( - const GLfloat invW = vLower->win[3]; - const GLfloat s0 = vLower->texcoord[u][0] * invW; - const GLfloat t0 = vLower->texcoord[u][1] * invW; - const GLfloat u0 = vLower->texcoord[u][2] * invW; - const GLfloat v0 = vLower->texcoord[u][3] * invW; - sLeft[u] = s0 + (span.texStepX[u][0] * adjx + span.texStepY[u][0] * adjy) * (1.0F/FIXED_SCALE); - tLeft[u] = t0 + (span.texStepX[u][1] * adjx + span.texStepY[u][1] * adjy) * (1.0F/FIXED_SCALE); - uLeft[u] = u0 + (span.texStepX[u][2] * adjx + span.texStepY[u][2] * adjy) * (1.0F/FIXED_SCALE); - vLeft[u] = v0 + (span.texStepX[u][3] * adjx + span.texStepY[u][3] * adjy) * (1.0F/FIXED_SCALE); - dsOuter[u] = span.texStepY[u][0] + dxOuter * span.texStepX[u][0]; - dtOuter[u] = span.texStepY[u][1] + dxOuter * span.texStepX[u][1]; - duOuter[u] = span.texStepY[u][2] + dxOuter * span.texStepX[u][2]; - dvOuter[u] = span.texStepY[u][3] + dxOuter * span.texStepX[u][3]; - ) +#ifdef INTERP_ATTRIBS + { + const GLuint attr = FRAG_ATTRIB_WPOS; + wLeft = vLower->attrib[FRAG_ATTRIB_WPOS][3] + + (span.attrStepX[attr][3] * adjx + + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE); + dwOuter = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3]; + } + ATTRIB_LOOP_BEGIN + const GLfloat invW = vLower->attrib[FRAG_ATTRIB_WPOS][3]; + if (swrast->_InterpMode[attr] == GL_FLAT) { + GLuint c; + for (c = 0; c < 4; c++) { + attrLeft[attr][c] = v2->attrib[attr][c] * invW; + daOuter[attr][c] = 0.0; + } + } + else { + GLuint c; + for (c = 0; c < 4; c++) { + const GLfloat a = vLower->attrib[attr][c] * invW; + attrLeft[attr][c] = a + ( span.attrStepX[attr][c] * adjx + + span.attrStepY[attr][c] * adjy) * (1.0F/FIXED_SCALE); + daOuter[attr][c] = span.attrStepY[attr][c] + dxOuter * span.attrStepX[attr][c]; + } + } + ATTRIB_LOOP_END #endif } /*if setupLeft*/ if (setupRight && eRight->lines>0) { -#if TRIANGLE_WALK_DOUBLE - fxRightEdge = FixedToDouble(eRight->fsx); - fdxRightEdge = eRight->dxdy; -#else fxRightEdge = eRight->fsx - FIXED_EPSILON; fdxRightEdge = eRight->fdxdy; -#endif } if (lines==0) { @@ -973,12 +742,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, # endif fdzInner = fdzOuter + span.zStep; #endif -#ifdef INTERP_W - dwInner = dwOuter + span.dwdx; -#endif -#ifdef INTERP_FOG - dfogInner = dfogOuter + span.dfogdx; -#endif #ifdef INTERP_RGB fdrInner = fdrOuter + span.redStep; fdgInner = fdgOuter + span.greenStep; @@ -987,33 +750,25 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_ALPHA fdaInner = fdaOuter + span.alphaStep; #endif -#ifdef INTERP_SPEC - dsrInner = dsrOuter + span.specRedStep; - dsgInner = dsgOuter + span.specGreenStep; - dsbInner = dsbOuter + span.specBlueStep; -#endif -#ifdef INTERP_INDEX - diInner = diOuter + span.indexStep; -#endif #ifdef INTERP_INT_TEX dsInner = dsOuter + span.intTexStep[0]; dtInner = dtOuter + span.intTexStep[1]; #endif -#ifdef INTERP_TEX - TEX_UNIT_LOOP( - dsInner[u] = dsOuter[u] + span.texStepX[u][0]; - dtInner[u] = dtOuter[u] + span.texStepX[u][1]; - duInner[u] = duOuter[u] + span.texStepX[u][2]; - dvInner[u] = dvOuter[u] + span.texStepX[u][3]; - ) +#ifdef INTERP_ATTRIBS + dwInner = dwOuter + span.attrStepX[FRAG_ATTRIB_WPOS][3]; + ATTRIB_LOOP_BEGIN + GLuint c; + for (c = 0; c < 4; c++) { + daInner[attr][c] = daOuter[attr][c] + span.attrStepX[attr][c]; + } + ATTRIB_LOOP_END #endif while (lines > 0) { /* initialize the span interpolants to the leftmost value */ /* ff = fixed-pt fragment */ - const GLint right = InterpToInt(fxRightEdge); - span.x = InterpToInt(fxLeftEdge); - + const GLint right = FixedToInt(fxRightEdge); + span.x = FixedToInt(fxLeftEdge); if (right <= span.x) span.end = 0; else @@ -1022,12 +777,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_Z span.z = zLeft; #endif -#ifdef INTERP_W - span.w = wLeft; -#endif -#ifdef INTERP_FOG - span.fog = fogLeft; -#endif #ifdef INTERP_RGB span.red = rLeft; span.green = gLeft; @@ -1036,97 +785,39 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_ALPHA span.alpha = aLeft; #endif -#ifdef INTERP_SPEC - span.specRed = srLeft; - span.specGreen = sgLeft; - span.specBlue = sbLeft; -#endif -#ifdef INTERP_INDEX - span.index = iLeft; -#endif #ifdef INTERP_INT_TEX span.intTex[0] = sLeft; span.intTex[1] = tLeft; #endif -#ifdef INTERP_TEX - TEX_UNIT_LOOP( - span.tex[u][0] = sLeft[u]; - span.tex[u][1] = tLeft[u]; - span.tex[u][2] = uLeft[u]; - span.tex[u][3] = vLeft[u]; - ) +#ifdef INTERP_ATTRIBS + span.attrStart[FRAG_ATTRIB_WPOS][3] = wLeft; + ATTRIB_LOOP_BEGIN + GLuint c; + for (c = 0; c < 4; c++) { + span.attrStart[attr][c] = attrLeft[attr][c]; + } + ATTRIB_LOOP_END #endif - if (span.end > 1) { - /* Under rare circumstances, we might have to fudge the - * colors. XXX does this really happen anymore??? - */ + /* 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 - { - GLfixed ffrend = span.red + len * span.redStep; - GLfixed ffgend = span.green + len * span.greenStep; - GLfixed ffbend = span.blue + len * span.blueStep; - if (ffrend < 0) { - span.red -= ffrend; - if (span.red < 0) - span.red = 0; - } - if (ffgend < 0) { - span.green -= ffgend; - if (span.green < 0) - span.green = 0; - } - if (ffbend < 0) { - span.blue -= ffbend; - if (span.blue < 0) - span.blue = 0; - } - } + CLAMP_INTERPOLANT(red, redStep, len); + CLAMP_INTERPOLANT(green, greenStep, len); + CLAMP_INTERPOLANT(blue, blueStep, len); #endif #ifdef INTERP_ALPHA - { - GLfixed ffaend = span.alpha + len * span.alphaStep; - if (ffaend < 0) { - span.alpha -= ffaend; - if (span.alpha < 0) - span.alpha = 0; - } - } + CLAMP_INTERPOLANT(alpha, alphaStep, len); #endif -#ifdef INTERP_SPEC { - GLfixed ffsrend = span.specRed + len * span.specRedStep; - GLfixed ffsgend = span.specGreen + len * span.specGreenStep; - GLfixed ffsbend = span.specBlue + len * span.specBlueStep; - if (ffsrend < 0) { - span.specRed -= ffsrend; - if (span.specRed < 0) - span.specRed = 0; - } - if (ffsgend < 0) { - span.specGreen -= ffsgend; - if (span.specGreen < 0) - span.specGreen = 0; - } - if (ffsbend < 0) { - span.specBlue -= ffsbend; - if (span.specBlue < 0) - span.specBlue = 0; - } + RENDER_SPAN( span ); } -#endif -#ifdef INTERP_INDEX - if (span.index < 0) - span.index = 0; -#endif - } /* span.end > 1 */ - - /* This is where we actually generate fragments */ - if (span.end > 0) { - RENDER_SPAN( span ); } /* @@ -1143,7 +834,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, fError += fdError; if (fError >= 0) { - fError -= INTERP_ONE; + fError -= FIXED_ONE; #ifdef PIXEL_ADDRESS pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter); @@ -1154,12 +845,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, # endif zLeft += fdzOuter; #endif -#ifdef INTERP_W - wLeft += dwOuter; -#endif -#ifdef INTERP_FOG - fogLeft += dfogOuter; -#endif #ifdef INTERP_RGB rLeft += fdrOuter; gLeft += fdgOuter; @@ -1168,25 +853,18 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_ALPHA aLeft += fdaOuter; #endif -#ifdef INTERP_SPEC - srLeft += dsrOuter; - sgLeft += dsgOuter; - sbLeft += dsbOuter; -#endif -#ifdef INTERP_INDEX - iLeft += diOuter; -#endif #ifdef INTERP_INT_TEX sLeft += dsOuter; tLeft += dtOuter; #endif -#ifdef INTERP_TEX - TEX_UNIT_LOOP( - sLeft[u] += dsOuter[u]; - tLeft[u] += dtOuter[u]; - uLeft[u] += duOuter[u]; - vLeft[u] += dvOuter[u]; - ) +#ifdef INTERP_ATTRIBS + wLeft += dwOuter; + ATTRIB_LOOP_BEGIN + GLuint c; + for (c = 0; c < 4; c++) { + attrLeft[attr][c] += daOuter[attr][c]; + } + ATTRIB_LOOP_END #endif } else { @@ -1199,12 +877,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, # endif zLeft += fdzInner; #endif -#ifdef INTERP_W - wLeft += dwInner; -#endif -#ifdef INTERP_FOG - fogLeft += dfogInner; -#endif #ifdef INTERP_RGB rLeft += fdrInner; gLeft += fdgInner; @@ -1213,25 +885,18 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_ALPHA aLeft += fdaInner; #endif -#ifdef INTERP_SPEC - srLeft += dsrInner; - sgLeft += dsgInner; - sbLeft += dsbInner; -#endif -#ifdef INTERP_INDEX - iLeft += diInner; -#endif #ifdef INTERP_INT_TEX sLeft += dsInner; tLeft += dtInner; #endif -#ifdef INTERP_TEX - TEX_UNIT_LOOP( - sLeft[u] += dsInner[u]; - tLeft[u] += dtInner[u]; - uLeft[u] += duInner[u]; - vLeft[u] += dvInner[u]; - ) +#ifdef INTERP_ATTRIBS + wLeft += dwInner; + ATTRIB_LOOP_BEGIN + GLuint c; + for (c = 0; c < 4; c++) { + attrLeft[attr][c] += daInner[attr][c]; + } + ATTRIB_LOOP_END #endif } } /*while lines>0*/ @@ -1239,40 +904,26 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, } /* for subTriangle */ } -#ifdef CLEANUP_CODE - CLEANUP_CODE -#endif } } #undef SETUP_CODE -#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_ALPHA -#undef INTERP_SPEC -#undef INTERP_INDEX #undef INTERP_INT_TEX -#undef INTERP_TEX -#undef INTERP_MULTITEX -#undef TEX_UNIT_LOOP +#undef INTERP_ATTRIBS #undef S_SCALE #undef T_SCALE #undef FixedToDepth -#undef ColorTemp -#undef GLinterp -#undef InterpToInt -#undef INTERP_ONE -#undef DO_OCCLUSION_TEST #undef NAME