X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fswrast%2Fs_tritemp.h;h=8e3c5b5eebb189d9cedf353ae0ff0628bb905251;hb=a3eb0f718e19653a2ad8e49396c904183be456f3;hp=1949e7cd40f132471d291b4961729c65ad621b99;hpb=c360a721e7081c08cd33621462056a62335908a7;p=mesa.git diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h index 1949e7cd40f..8e3c5b5eebb 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: 5.1 + * Version: 7.0 * - * Copyright (C) 1999-2003 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,18 +28,17 @@ * 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 - * 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 + * 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_INDEX - if defined, interpolate color index 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 @@ -50,12 +49,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. @@ -63,38 +61,51 @@ * This code was designed for the origin to be in the lower-left corner. * * Inspired by triangle rasterizer code written by Allen Akin. Thanks Allen! + * + * + * Some notes on rasterization accuracy: + * + * This code uses fixed point arithmetic (the GLfixed type) to iterate + * over the triangle edges and interpolate ancillary data (such as Z, + * color, secondary color, etc). The number of fractional bits in + * GLfixed and the value of SUB_PIXEL_BITS has a direct bearing on the + * accuracy of rasterization. + * + * If SUB_PIXEL_BITS=4 then we'll snap the vertices to the nearest + * 1/16 of a pixel. If we're walking up a long, nearly vertical edge + * (dx=1/16, dy=1024) we'll need 4 + 10 = 14 fractional bits in + * GLfixed to walk the edge without error. If the maximum viewport + * height is 4K pixels, then we'll need 4 + 12 = 16 fractional bits. + * + * Historically, Mesa has used 11 fractional bits in GLfixed, snaps + * vertices to 1/16 pixel and allowed a maximum viewport height of 2K + * pixels. 11 fractional bits is actually insufficient for accurately + * rasterizing some triangles. More recently, the maximum viewport + * height was increased to 4K pixels. Thus, Mesa should be using 16 + * fractional bits in GLfixed. Unfortunately, there may be some issues + * with setting FIXED_FRAC_BITS=16, such as multiplication overflow. + * This will have to be examined in some detail... + * + * For now, if you find rasterization errors, particularly with tall, + * sliver triangles, try increasing FIXED_FRAC_BITS and/or decreasing + * SUB_PIXEL_BITS. */ /* - * ColorTemp is used for intermediate color values. + * Some code we unfortunately need to prevent negative interpolated colors. */ -#if CHAN_TYPE == GL_FLOAT -#define ColorTemp GLfloat -#else -#define ColorTemp GLint /* same as GLfixed */ -#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 \ - } +#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 @@ -103,21 +114,23 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, 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) */ + 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 */ + 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; @@ -127,9 +140,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; - INIT_SPAN(span, GL_POLYGON, 0, 0, 0); + (void) swrast; + + INIT_SPAN(span, GL_POLYGON); + span.y = 0; /* silence warnings */ #ifdef INTERP_Z (void) fixedToDepthShift; @@ -137,19 +153,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]); */ /* 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 */ @@ -189,9 +213,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 */ @@ -211,31 +235,28 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, { 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... */ { eMaj.fsy = FixedCeil(vMin_fy); eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy)); if (eMaj.lines > 0) { - GLfloat dxdy = eMaj.dx / eMaj.dy; - eMaj.fdxdy = SignedFloatToFixed(dxdy); + eMaj.dxdy = eMaj.dx / eMaj.dy; + 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); } else { return; /*CULLED*/ @@ -244,21 +265,21 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, eTop.fsy = FixedCeil(vMid_fy); eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy)); if (eTop.lines > 0) { - GLfloat dxdy = eTop.dx / eTop.dy; - eTop.fdxdy = SignedFloatToFixed(dxdy); + eTop.dxdy = eTop.dx / eTop.dy; + 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); } eBot.fsy = FixedCeil(vMin_fy); eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy)); if (eBot.lines > 0) { - GLfloat dxdy = eBot.dx / eBot.dy; - eBot.fdxdy = SignedFloatToFixed(dxdy); + eBot.dxdy = eBot.dx / eBot.dy; + 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); } } @@ -316,149 +337,72 @@ 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 - { - 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; - { - const GLfloat eMaj_dfog = vMax->fog - vMin->fog; - const GLfloat eBot_dfog = vMid->fog - vMin->fog; - 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 = (GLfloat) ((GLint) vMax->index - (GLint) vMin->index); - GLfloat eBot_di = (GLfloat) ((GLint) vMid->index - (GLint) vMin->index); + GLfloat eMaj_di = vMax->attrib[FRAG_ATTRIB_CI][0] - vMin->attrib[FRAG_ATTRIB_CI][0]; + GLfloat eBot_di = vMid->attrib[FRAG_ATTRIB_CI][0] - vMin->attrib[FRAG_ATTRIB_CI][0]; didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di); didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx); span.indexStep = SignedFloatToFixed(didx); @@ -470,43 +414,46 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, } #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 @@ -558,45 +505,31 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, */ { - int subTriangle; - GLfixed fx; + GLint subTriangle; GLfixed fxLeftEdge = 0, fxRightEdge = 0; GLfixed fdxLeftEdge = 0, fdxRightEdge = 0; - GLfixed fdxOuter; - int idxOuter; - float dxOuter; GLfixed fError = 0, fdError = 0; - float adjx, adjy; - GLfixed fy; #ifdef PIXEL_ADDRESS PIXEL_TYPE *pRow = NULL; - int dPRowOuter = 0, dPRowInner; /* offset in bytes */ + 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; - int dZRowOuter = 0, dZRowInner; /* offset in bytes */ + 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; + GLint aLeft = 0, fdaOuter = 0, fdaInner; #endif #ifdef INTERP_INDEX GLfixed iLeft=0, diOuter=0, diInner; @@ -605,15 +538,10 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, 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++) { @@ -659,31 +587,30 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, } if (setupLeft && eLeft->lines > 0) { - const SWvertex *vLower; - GLfixed fsx = eLeft->fsx; - fx = FixedCeil(fsx); + const SWvertex *vLower = eLeft->v0; + const GLfixed fsy = eLeft->fsy; + const GLfixed fsx = eLeft->fsx; /* no fractional part */ + const GLfixed fx = FixedCeil(fsx); /* no fractional part */ + const GLfixed adjx = (GLfixed) (fx - eLeft->fx0); /* SCALED! */ + const GLfixed adjy = (GLfixed) eLeft->adjy; /* SCALED! */ + GLint idxOuter; + 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; - span.y = FixedToInt(fy); + dxOuter = (GLfloat) idxOuter; + span.y = FixedToInt(fsy); - adjx = (float)(fx - eLeft->fx0); /* SCALED! */ - adjy = eLeft->adjy; /* SCALED! */ -#ifndef __IBMCPP__ - (void) adjx; /* silence compiler warnings */ - (void) adjy; /* silence compiler warnings */ -#endif - vLower = eLeft->v0; -#ifndef __IBMCPP__ - (void) vLower; /* silence compiler warnings */ -#endif + /* silence warnings on some compilers */ + (void) dxOuter; + (void) adjx; + (void) adjy; + (void) vLower; #ifdef PIXEL_ADDRESS { @@ -694,7 +621,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #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 @@ -704,162 +631,127 @@ 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, FixedToInt(fxLeftEdge), span.y); + zrb->GetPointer(ctx, 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 - fogLeft = vLower->fog + (span.dfogdx * adjx + span.dfogdy * adjy) * (1.0F/FIXED_SCALE); - 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 + iLeft = (GLfixed)(vLower->attrib[FRAG_ATTRIB_CI][0] * FIXED_SCALE + didx * adjx + didy * adjy) + FIXED_HALF; diOuter = SignedFloatToFixed(didy + dxOuter * didx); } else { - iLeft = (GLfixed) (v2->index * FIXED_SCALE); + ASSERT(ctx->Light.ShadeModel == GL_FLAT); + iLeft = FloatToFixed(v2->attrib[FRAG_ATTRIB_CI][0]); 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*/ @@ -884,25 +776,14 @@ 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 -#if defined(INTERP_RGB) +#ifdef INTERP_RGB fdrInner = fdrOuter + span.redStep; fdgInner = fdgOuter + span.greenStep; fdbInner = fdbOuter + span.blueStep; #endif -#if defined(INTERP_ALPHA) +#ifdef INTERP_ALPHA fdaInner = fdaOuter + span.alphaStep; #endif -#if defined(INTERP_SPEC) - dsrInner = dsrOuter + span.specRedStep; - dsgInner = dsgOuter + span.specGreenStep; - dsbInner = dsbOuter + span.specBlueStep; -#endif #ifdef INTERP_INDEX diInner = diOuter + span.indexStep; #endif @@ -910,22 +791,21 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, 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 = FixedToInt(fxRightEdge); - span.x = FixedToInt(fxLeftEdge); - if (right <= span.x) span.end = 0; else @@ -934,25 +814,14 @@ 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 -#if defined(INTERP_RGB) +#ifdef INTERP_RGB span.red = rLeft; span.green = gLeft; span.blue = bLeft; #endif -#if defined(INTERP_ALPHA) +#ifdef INTERP_ALPHA span.alpha = aLeft; #endif -#if defined(INTERP_SPEC) - span.specRed = srLeft; - span.specGreen = sgLeft; - span.specBlue = sbLeft; -#endif #ifdef INTERP_INDEX span.index = iLeft; #endif @@ -961,81 +830,37 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, 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 + /* 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 */ - const GLint len = right - span.x - 1; - 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 - { - const GLint len = right - span.x - 1; - GLfixed ffaend = span.alpha + len * span.alphaStep; - if (ffaend < 0) { - span.alpha -= ffaend; - if (span.alpha < 0) - span.alpha = 0; - } - } -#endif -#ifdef INTERP_SPEC - { - /* need this to accomodate round-off errors */ - const GLint len = right - span.x - 1; - 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; - } - } + CLAMP_INTERPOLANT(alpha, alphaStep, len); #endif #ifdef INTERP_INDEX - if (span.index < 0) span.index = 0; + CLAMP_INTERPOLANT(index, indexStep, len); #endif - - /* This is where we actually generate fragments */ - if (span.end > 0) { - RENDER_SPAN( span ); + { + RENDER_SPAN( span ); + } } /* @@ -1044,16 +869,16 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, * pixel-center x coordinate so that it stays * on or inside the major edge. */ - (span.y)++; + span.y++; lines--; fxLeftEdge += fdxLeftEdge; fxRightEdge += fdxRightEdge; - fError += fdError; if (fError >= 0) { fError -= FIXED_ONE; + #ifdef PIXEL_ADDRESS pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter); #endif @@ -1063,25 +888,14 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, # endif zLeft += fdzOuter; #endif -#ifdef INTERP_W - wLeft += dwOuter; -#endif -#ifdef INTERP_FOG - fogLeft += dfogOuter; -#endif -#if defined(INTERP_RGB) +#ifdef INTERP_RGB rLeft += fdrOuter; gLeft += fdgOuter; bLeft += fdbOuter; #endif -#if defined(INTERP_ALPHA) +#ifdef INTERP_ALPHA aLeft += fdaOuter; #endif -#if defined(INTERP_SPEC) - srLeft += dsrOuter; - sgLeft += dsgOuter; - sbLeft += dsbOuter; -#endif #ifdef INTERP_INDEX iLeft += diOuter; #endif @@ -1089,13 +903,14 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, 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 { @@ -1108,25 +923,14 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, # endif zLeft += fdzInner; #endif -#ifdef INTERP_W - wLeft += dwInner; -#endif -#ifdef INTERP_FOG - fogLeft += dfogInner; -#endif -#if defined(INTERP_RGB) +#ifdef INTERP_RGB rLeft += fdrInner; gLeft += fdgInner; bLeft += fdbInner; #endif -#if defined(INTERP_ALPHA) +#ifdef INTERP_ALPHA aLeft += fdaInner; #endif -#if defined(INTERP_SPEC) - srLeft += dsrInner; - sgLeft += dsgInner; - sbLeft += dsbInner; -#endif #ifdef INTERP_INDEX iLeft += diInner; #endif @@ -1134,13 +938,14 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, 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*/ @@ -1148,36 +953,27 @@ 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 DO_OCCLUSION_TEST #undef NAME