Home | History | Annotate | Download | only in swrast
      1 /*
      2  * Mesa 3-D graphics library
      3  * Version:  7.0
      4  *
      5  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the "Software"),
      9  * to deal in the Software without restriction, including without limitation
     10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     11  * and/or sell copies of the Software, and to permit persons to whom the
     12  * Software is furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included
     15  * in all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     21  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     23  */
     24 
     25 /*
     26  * Triangle Rasterizer Template
     27  *
     28  * This file is #include'd to generate custom triangle rasterizers.
     29  *
     30  * The following macros may be defined to indicate what auxillary information
     31  * must be interpolated across the triangle:
     32  *    INTERP_Z        - if defined, interpolate integer Z values
     33  *    INTERP_RGB      - if defined, interpolate integer RGB values
     34  *    INTERP_ALPHA    - if defined, interpolate integer Alpha values
     35  *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
     36  *                         (fast, simple 2-D texture mapping, without
     37  *                         perspective correction)
     38  *    INTERP_ATTRIBS  - if defined, interpolate arbitrary attribs (texcoords,
     39  *                         varying vars, etc)  This also causes W to be
     40  *                         computed for perspective correction).
     41  *
     42  * When one can directly address pixels in the color buffer the following
     43  * macros can be defined and used to compute pixel addresses during
     44  * rasterization (see pRow):
     45  *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
     46  *    BYTES_PER_ROW       - number of bytes per row in the color buffer
     47  *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
     48  *                          Y==0 at bottom of screen and increases upward.
     49  *
     50  * Similarly, for direct depth buffer access, this type is used for depth
     51  * buffer addressing (see zRow):
     52  *    DEPTH_TYPE          - either GLushort or GLuint
     53  *
     54  * Optionally, one may provide one-time setup code per triangle:
     55  *    SETUP_CODE    - code which is to be executed once per triangle
     56  *
     57  * The following macro MUST be defined:
     58  *    RENDER_SPAN(span) - code to write a span of pixels.
     59  *
     60  * This code was designed for the origin to be in the lower-left corner.
     61  *
     62  * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
     63  *
     64  *
     65  * Some notes on rasterization accuracy:
     66  *
     67  * This code uses fixed point arithmetic (the GLfixed type) to iterate
     68  * over the triangle edges and interpolate ancillary data (such as Z,
     69  * color, secondary color, etc).  The number of fractional bits in
     70  * GLfixed and the value of SUB_PIXEL_BITS has a direct bearing on the
     71  * accuracy of rasterization.
     72  *
     73  * If SUB_PIXEL_BITS=4 then we'll snap the vertices to the nearest
     74  * 1/16 of a pixel.  If we're walking up a long, nearly vertical edge
     75  * (dx=1/16, dy=1024) we'll need 4 + 10 = 14 fractional bits in
     76  * GLfixed to walk the edge without error.  If the maximum viewport
     77  * height is 4K pixels, then we'll need 4 + 12 = 16 fractional bits.
     78  *
     79  * Historically, Mesa has used 11 fractional bits in GLfixed, snaps
     80  * vertices to 1/16 pixel and allowed a maximum viewport height of 2K
     81  * pixels.  11 fractional bits is actually insufficient for accurately
     82  * rasterizing some triangles.  More recently, the maximum viewport
     83  * height was increased to 4K pixels.  Thus, Mesa should be using 16
     84  * fractional bits in GLfixed.  Unfortunately, there may be some issues
     85  * with setting FIXED_FRAC_BITS=16, such as multiplication overflow.
     86  * This will have to be examined in some detail...
     87  *
     88  * For now, if you find rasterization errors, particularly with tall,
     89  * sliver triangles, try increasing FIXED_FRAC_BITS and/or decreasing
     90  * SUB_PIXEL_BITS.
     91  */
     92 
     93 
     94 /*
     95  * Some code we unfortunately need to prevent negative interpolated colors.
     96  */
     97 #ifndef CLAMP_INTERPOLANT
     98 #define CLAMP_INTERPOLANT(CHANNEL, CHANNELSTEP, LEN)		\
     99 do {								\
    100    GLfixed endVal = span.CHANNEL + (LEN) * span.CHANNELSTEP;	\
    101    if (endVal < 0) {						\
    102       span.CHANNEL -= endVal;					\
    103    }								\
    104    if (span.CHANNEL < 0) {					\
    105       span.CHANNEL = 0;						\
    106    }								\
    107 } while (0)
    108 #endif
    109 
    110 
    111 static void NAME(struct gl_context *ctx, const SWvertex *v0,
    112                                  const SWvertex *v1,
    113                                  const SWvertex *v2 )
    114 {
    115    typedef struct {
    116       const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
    117       GLfloat dx;	/* X(v1) - X(v0) */
    118       GLfloat dy;	/* Y(v1) - Y(v0) */
    119       GLfloat dxdy;	/* dx/dy */
    120       GLfixed fdxdy;	/* dx/dy in fixed-point */
    121       GLfloat adjy;	/* adjust from v[0]->fy to fsy, scaled */
    122       GLfixed fsx;	/* first sample point x coord */
    123       GLfixed fsy;
    124       GLfixed fx0;	/* fixed pt X of lower endpoint */
    125       GLint lines;	/* number of lines to be sampled on this edge */
    126    } EdgeT;
    127 
    128    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
    129 #ifdef INTERP_Z
    130    const GLint depthBits = ctx->DrawBuffer->Visual.depthBits;
    131    const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0;
    132    const GLfloat maxDepth = ctx->DrawBuffer->_DepthMaxF;
    133 #define FixedToDepth(F)  ((F) >> fixedToDepthShift)
    134 #endif
    135    EdgeT eMaj, eTop, eBot;
    136    GLfloat oneOverArea;
    137    const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
    138    GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign;
    139    const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */
    140    GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
    141 
    142    SWspan span;
    143 
    144    (void) swrast;
    145 
    146    INIT_SPAN(span, GL_POLYGON);
    147    span.y = 0; /* silence warnings */
    148 
    149 #ifdef INTERP_Z
    150    (void) fixedToDepthShift;
    151 #endif
    152 
    153    /*
    154    printf("%s()\n", __FUNCTION__);
    155    printf("  %g, %g, %g\n",
    156           v0->attrib[FRAG_ATTRIB_WPOS][0],
    157           v0->attrib[FRAG_ATTRIB_WPOS][1],
    158           v0->attrib[FRAG_ATTRIB_WPOS][2]);
    159    printf("  %g, %g, %g\n",
    160           v1->attrib[FRAG_ATTRIB_WPOS][0],
    161           v1->attrib[FRAG_ATTRIB_WPOS][1],
    162           v1->attrib[FRAG_ATTRIB_WPOS][2]);
    163    printf("  %g, %g, %g\n",
    164           v2->attrib[FRAG_ATTRIB_WPOS][0],
    165           v2->attrib[FRAG_ATTRIB_WPOS][1],
    166           v2->attrib[FRAG_ATTRIB_WPOS][2]);
    167    */
    168 
    169    /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
    170     * And find the order of the 3 vertices along the Y axis.
    171     */
    172    {
    173       const GLfixed fy0 = FloatToFixed(v0->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask;
    174       const GLfixed fy1 = FloatToFixed(v1->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask;
    175       const GLfixed fy2 = FloatToFixed(v2->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask;
    176       if (fy0 <= fy1) {
    177          if (fy1 <= fy2) {
    178             /* y0 <= y1 <= y2 */
    179             vMin = v0;   vMid = v1;   vMax = v2;
    180             vMin_fy = fy0;  vMid_fy = fy1;  vMax_fy = fy2;
    181          }
    182          else if (fy2 <= fy0) {
    183             /* y2 <= y0 <= y1 */
    184             vMin = v2;   vMid = v0;   vMax = v1;
    185             vMin_fy = fy2;  vMid_fy = fy0;  vMax_fy = fy1;
    186          }
    187          else {
    188             /* y0 <= y2 <= y1 */
    189             vMin = v0;   vMid = v2;   vMax = v1;
    190             vMin_fy = fy0;  vMid_fy = fy2;  vMax_fy = fy1;
    191             bf = -bf;
    192          }
    193       }
    194       else {
    195          if (fy0 <= fy2) {
    196             /* y1 <= y0 <= y2 */
    197             vMin = v1;   vMid = v0;   vMax = v2;
    198             vMin_fy = fy1;  vMid_fy = fy0;  vMax_fy = fy2;
    199             bf = -bf;
    200          }
    201          else if (fy2 <= fy1) {
    202             /* y2 <= y1 <= y0 */
    203             vMin = v2;   vMid = v1;   vMax = v0;
    204             vMin_fy = fy2;  vMid_fy = fy1;  vMax_fy = fy0;
    205             bf = -bf;
    206          }
    207          else {
    208             /* y1 <= y2 <= y0 */
    209             vMin = v1;   vMid = v2;   vMax = v0;
    210             vMin_fy = fy1;  vMid_fy = fy2;  vMax_fy = fy0;
    211          }
    212       }
    213 
    214       /* fixed point X coords */
    215       vMin_fx = FloatToFixed(vMin->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask;
    216       vMid_fx = FloatToFixed(vMid->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask;
    217       vMax_fx = FloatToFixed(vMax->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask;
    218    }
    219 
    220    /* vertex/edge relationship */
    221    eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
    222    eTop.v0 = vMid;   eTop.v1 = vMax;
    223    eBot.v0 = vMin;   eBot.v1 = vMid;
    224 
    225    /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
    226    eMaj.dx = FixedToFloat(vMax_fx - vMin_fx);
    227    eMaj.dy = FixedToFloat(vMax_fy - vMin_fy);
    228    eTop.dx = FixedToFloat(vMax_fx - vMid_fx);
    229    eTop.dy = FixedToFloat(vMax_fy - vMid_fy);
    230    eBot.dx = FixedToFloat(vMid_fx - vMin_fx);
    231    eBot.dy = FixedToFloat(vMid_fy - vMin_fy);
    232 
    233    /* compute area, oneOverArea and perform backface culling */
    234    {
    235       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
    236 
    237       if (IS_INF_OR_NAN(area) || area == 0.0F)
    238          return;
    239 
    240       if (area * bf * swrast->_BackfaceCullSign < 0.0)
    241          return;
    242 
    243       oneOverArea = 1.0F / area;
    244 
    245       /* 0 = front, 1 = back */
    246       span.facing = oneOverArea * bf > 0.0F;
    247    }
    248 
    249    /* Edge setup.  For a triangle strip these could be reused... */
    250    {
    251       eMaj.fsy = FixedCeil(vMin_fy);
    252       eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy));
    253       if (eMaj.lines > 0) {
    254          eMaj.dxdy = eMaj.dx / eMaj.dy;
    255          eMaj.fdxdy = SignedFloatToFixed(eMaj.dxdy);
    256          eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
    257          eMaj.fx0 = vMin_fx;
    258          eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * eMaj.dxdy);
    259       }
    260       else {
    261          return;  /*CULLED*/
    262       }
    263 
    264       eTop.fsy = FixedCeil(vMid_fy);
    265       eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy));
    266       if (eTop.lines > 0) {
    267          eTop.dxdy = eTop.dx / eTop.dy;
    268          eTop.fdxdy = SignedFloatToFixed(eTop.dxdy);
    269          eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
    270          eTop.fx0 = vMid_fx;
    271          eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * eTop.dxdy);
    272       }
    273 
    274       eBot.fsy = FixedCeil(vMin_fy);
    275       eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy));
    276       if (eBot.lines > 0) {
    277          eBot.dxdy = eBot.dx / eBot.dy;
    278          eBot.fdxdy = SignedFloatToFixed(eBot.dxdy);
    279          eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
    280          eBot.fx0 = vMin_fx;
    281          eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * eBot.dxdy);
    282       }
    283    }
    284 
    285    /*
    286     * Conceptually, we view a triangle as two subtriangles
    287     * separated by a perfectly horizontal line.  The edge that is
    288     * intersected by this line is one with maximal absolute dy; we
    289     * call it a ``major'' edge.  The other two edges are the
    290     * ``top'' edge (for the upper subtriangle) and the ``bottom''
    291     * edge (for the lower subtriangle).  If either of these two
    292     * edges is horizontal or very close to horizontal, the
    293     * corresponding subtriangle might cover zero sample points;
    294     * we take care to handle such cases, for performance as well
    295     * as correctness.
    296     *
    297     * By stepping rasterization parameters along the major edge,
    298     * we can avoid recomputing them at the discontinuity where
    299     * the top and bottom edges meet.  However, this forces us to
    300     * be able to scan both left-to-right and right-to-left.
    301     * Also, we must determine whether the major edge is at the
    302     * left or right side of the triangle.  We do this by
    303     * computing the magnitude of the cross-product of the major
    304     * and top edges.  Since this magnitude depends on the sine of
    305     * the angle between the two edges, its sign tells us whether
    306     * we turn to the left or to the right when travelling along
    307     * the major edge to the top edge, and from this we infer
    308     * whether the major edge is on the left or the right.
    309     *
    310     * Serendipitously, this cross-product magnitude is also a
    311     * value we need to compute the iteration parameter
    312     * derivatives for the triangle, and it can be used to perform
    313     * backface culling because its sign tells us whether the
    314     * triangle is clockwise or counterclockwise.  In this code we
    315     * refer to it as ``area'' because it's also proportional to
    316     * the pixel area of the triangle.
    317     */
    318 
    319    {
    320       GLint scan_from_left_to_right;  /* true if scanning left-to-right */
    321 
    322       /*
    323        * Execute user-supplied setup code
    324        */
    325 #ifdef SETUP_CODE
    326       SETUP_CODE
    327 #endif
    328 
    329       scan_from_left_to_right = (oneOverArea < 0.0F);
    330 
    331 
    332       /* compute d?/dx and d?/dy derivatives */
    333 #ifdef INTERP_Z
    334       span.interpMask |= SPAN_Z;
    335       {
    336          GLfloat eMaj_dz = vMax->attrib[FRAG_ATTRIB_WPOS][2] - vMin->attrib[FRAG_ATTRIB_WPOS][2];
    337          GLfloat eBot_dz = vMid->attrib[FRAG_ATTRIB_WPOS][2] - vMin->attrib[FRAG_ATTRIB_WPOS][2];
    338          span.attrStepX[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
    339          if (span.attrStepX[FRAG_ATTRIB_WPOS][2] > maxDepth ||
    340              span.attrStepX[FRAG_ATTRIB_WPOS][2] < -maxDepth) {
    341             /* probably a sliver triangle */
    342             span.attrStepX[FRAG_ATTRIB_WPOS][2] = 0.0;
    343             span.attrStepY[FRAG_ATTRIB_WPOS][2] = 0.0;
    344          }
    345          else {
    346             span.attrStepY[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
    347          }
    348          if (depthBits <= 16)
    349             span.zStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_WPOS][2]);
    350          else
    351             span.zStep = (GLint) span.attrStepX[FRAG_ATTRIB_WPOS][2];
    352       }
    353 #endif
    354 #ifdef INTERP_RGB
    355       span.interpMask |= SPAN_RGBA;
    356       if (ctx->Light.ShadeModel == GL_SMOOTH) {
    357          GLfloat eMaj_dr = (GLfloat) (vMax->color[RCOMP] - vMin->color[RCOMP]);
    358          GLfloat eBot_dr = (GLfloat) (vMid->color[RCOMP] - vMin->color[RCOMP]);
    359          GLfloat eMaj_dg = (GLfloat) (vMax->color[GCOMP] - vMin->color[GCOMP]);
    360          GLfloat eBot_dg = (GLfloat) (vMid->color[GCOMP] - vMin->color[GCOMP]);
    361          GLfloat eMaj_db = (GLfloat) (vMax->color[BCOMP] - vMin->color[BCOMP]);
    362          GLfloat eBot_db = (GLfloat) (vMid->color[BCOMP] - vMin->color[BCOMP]);
    363 #  ifdef INTERP_ALPHA
    364          GLfloat eMaj_da = (GLfloat) (vMax->color[ACOMP] - vMin->color[ACOMP]);
    365          GLfloat eBot_da = (GLfloat) (vMid->color[ACOMP] - vMin->color[ACOMP]);
    366 #  endif
    367          span.attrStepX[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
    368          span.attrStepY[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
    369          span.attrStepX[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
    370          span.attrStepY[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
    371          span.attrStepX[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
    372          span.attrStepY[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
    373          span.redStep   = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][0]);
    374          span.greenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][1]);
    375          span.blueStep  = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][2]);
    376 #  ifdef INTERP_ALPHA
    377          span.attrStepX[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
    378          span.attrStepY[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
    379          span.alphaStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3]);
    380 #  endif /* INTERP_ALPHA */
    381       }
    382       else {
    383          ASSERT(ctx->Light.ShadeModel == GL_FLAT);
    384          span.interpMask |= SPAN_FLAT;
    385          span.attrStepX[FRAG_ATTRIB_COL0][0] = span.attrStepY[FRAG_ATTRIB_COL0][0] = 0.0F;
    386          span.attrStepX[FRAG_ATTRIB_COL0][1] = span.attrStepY[FRAG_ATTRIB_COL0][1] = 0.0F;
    387          span.attrStepX[FRAG_ATTRIB_COL0][2] = span.attrStepY[FRAG_ATTRIB_COL0][2] = 0.0F;
    388 	 span.redStep   = 0;
    389 	 span.greenStep = 0;
    390 	 span.blueStep  = 0;
    391 #  ifdef INTERP_ALPHA
    392          span.attrStepX[FRAG_ATTRIB_COL0][3] = span.attrStepY[FRAG_ATTRIB_COL0][3] = 0.0F;
    393 	 span.alphaStep = 0;
    394 #  endif
    395       }
    396 #endif /* INTERP_RGB */
    397 #ifdef INTERP_INT_TEX
    398       {
    399          GLfloat eMaj_ds = (vMax->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE;
    400          GLfloat eBot_ds = (vMid->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE;
    401          GLfloat eMaj_dt = (vMax->attrib[FRAG_ATTRIB_TEX0][1] - vMin->attrib[FRAG_ATTRIB_TEX0][1]) * T_SCALE;
    402          GLfloat eBot_dt = (vMid->attrib[FRAG_ATTRIB_TEX0][1] - vMin->attrib[FRAG_ATTRIB_TEX0][1]) * T_SCALE;
    403          span.attrStepX[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
    404          span.attrStepY[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
    405          span.attrStepX[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
    406          span.attrStepY[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
    407          span.intTexStep[0] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][0]);
    408          span.intTexStep[1] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][1]);
    409       }
    410 #endif
    411 #ifdef INTERP_ATTRIBS
    412       {
    413          /* attrib[FRAG_ATTRIB_WPOS][3] is 1/W */
    414          const GLfloat wMax = vMax->attrib[FRAG_ATTRIB_WPOS][3];
    415          const GLfloat wMin = vMin->attrib[FRAG_ATTRIB_WPOS][3];
    416          const GLfloat wMid = vMid->attrib[FRAG_ATTRIB_WPOS][3];
    417          {
    418             const GLfloat eMaj_dw = wMax - wMin;
    419             const GLfloat eBot_dw = wMid - wMin;
    420             span.attrStepX[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw);
    421             span.attrStepY[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx);
    422          }
    423          ATTRIB_LOOP_BEGIN
    424             if (swrast->_InterpMode[attr] == GL_FLAT) {
    425                ASSIGN_4V(span.attrStepX[attr], 0.0, 0.0, 0.0, 0.0);
    426                ASSIGN_4V(span.attrStepY[attr], 0.0, 0.0, 0.0, 0.0);
    427             }
    428             else {
    429                GLuint c;
    430                for (c = 0; c < 4; c++) {
    431                   GLfloat eMaj_da = vMax->attrib[attr][c] * wMax - vMin->attrib[attr][c] * wMin;
    432                   GLfloat eBot_da = vMid->attrib[attr][c] * wMid - vMin->attrib[attr][c] * wMin;
    433                   span.attrStepX[attr][c] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
    434                   span.attrStepY[attr][c] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
    435                }
    436             }
    437          ATTRIB_LOOP_END
    438       }
    439 #endif
    440 
    441       /*
    442        * We always sample at pixel centers.  However, we avoid
    443        * explicit half-pixel offsets in this code by incorporating
    444        * the proper offset in each of x and y during the
    445        * transformation to window coordinates.
    446        *
    447        * We also apply the usual rasterization rules to prevent
    448        * cracks and overlaps.  A pixel is considered inside a
    449        * subtriangle if it meets all of four conditions: it is on or
    450        * to the right of the left edge, strictly to the left of the
    451        * right edge, on or below the top edge, and strictly above
    452        * the bottom edge.  (Some edges may be degenerate.)
    453        *
    454        * The following discussion assumes left-to-right scanning
    455        * (that is, the major edge is on the left); the right-to-left
    456        * case is a straightforward variation.
    457        *
    458        * We start by finding the half-integral y coordinate that is
    459        * at or below the top of the triangle.  This gives us the
    460        * first scan line that could possibly contain pixels that are
    461        * inside the triangle.
    462        *
    463        * Next we creep down the major edge until we reach that y,
    464        * and compute the corresponding x coordinate on the edge.
    465        * Then we find the half-integral x that lies on or just
    466        * inside the edge.  This is the first pixel that might lie in
    467        * the interior of the triangle.  (We won't know for sure
    468        * until we check the other edges.)
    469        *
    470        * As we rasterize the triangle, we'll step down the major
    471        * edge.  For each step in y, we'll move an integer number
    472        * of steps in x.  There are two possible x step sizes, which
    473        * we'll call the ``inner'' step (guaranteed to land on the
    474        * edge or inside it) and the ``outer'' step (guaranteed to
    475        * land on the edge or outside it).  The inner and outer steps
    476        * differ by one.  During rasterization we maintain an error
    477        * term that indicates our distance from the true edge, and
    478        * select either the inner step or the outer step, whichever
    479        * gets us to the first pixel that falls inside the triangle.
    480        *
    481        * All parameters (z, red, etc.) as well as the buffer
    482        * addresses for color and z have inner and outer step values,
    483        * so that we can increment them appropriately.  This method
    484        * eliminates the need to adjust parameters by creeping a
    485        * sub-pixel amount into the triangle at each scanline.
    486        */
    487 
    488       {
    489          GLint subTriangle;
    490          GLfixed fxLeftEdge = 0, fxRightEdge = 0;
    491          GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
    492          GLfixed fError = 0, fdError = 0;
    493 #ifdef PIXEL_ADDRESS
    494          PIXEL_TYPE *pRow = NULL;
    495          GLint dPRowOuter = 0, dPRowInner;  /* offset in bytes */
    496 #endif
    497 #ifdef INTERP_Z
    498 #  ifdef DEPTH_TYPE
    499          struct gl_renderbuffer *zrb
    500             = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
    501          DEPTH_TYPE *zRow = NULL;
    502          GLint dZRowOuter = 0, dZRowInner;  /* offset in bytes */
    503 #  endif
    504          GLuint zLeft = 0;
    505          GLfixed fdzOuter = 0, fdzInner;
    506 #endif
    507 #ifdef INTERP_RGB
    508          GLint rLeft = 0, fdrOuter = 0, fdrInner;
    509          GLint gLeft = 0, fdgOuter = 0, fdgInner;
    510          GLint bLeft = 0, fdbOuter = 0, fdbInner;
    511 #endif
    512 #ifdef INTERP_ALPHA
    513          GLint aLeft = 0, fdaOuter = 0, fdaInner;
    514 #endif
    515 #ifdef INTERP_INT_TEX
    516          GLfixed sLeft=0, dsOuter=0, dsInner;
    517          GLfixed tLeft=0, dtOuter=0, dtInner;
    518 #endif
    519 #ifdef INTERP_ATTRIBS
    520          GLfloat wLeft = 0, dwOuter = 0, dwInner;
    521          GLfloat attrLeft[FRAG_ATTRIB_MAX][4];
    522          GLfloat daOuter[FRAG_ATTRIB_MAX][4], daInner[FRAG_ATTRIB_MAX][4];
    523 #endif
    524 
    525          for (subTriangle=0; subTriangle<=1; subTriangle++) {
    526             EdgeT *eLeft, *eRight;
    527             int setupLeft, setupRight;
    528             int lines;
    529 
    530             if (subTriangle==0) {
    531                /* bottom half */
    532                if (scan_from_left_to_right) {
    533                   eLeft = &eMaj;
    534                   eRight = &eBot;
    535                   lines = eRight->lines;
    536                   setupLeft = 1;
    537                   setupRight = 1;
    538                }
    539                else {
    540                   eLeft = &eBot;
    541                   eRight = &eMaj;
    542                   lines = eLeft->lines;
    543                   setupLeft = 1;
    544                   setupRight = 1;
    545                }
    546             }
    547             else {
    548                /* top half */
    549                if (scan_from_left_to_right) {
    550                   eLeft = &eMaj;
    551                   eRight = &eTop;
    552                   lines = eRight->lines;
    553                   setupLeft = 0;
    554                   setupRight = 1;
    555                }
    556                else {
    557                   eLeft = &eTop;
    558                   eRight = &eMaj;
    559                   lines = eLeft->lines;
    560                   setupLeft = 1;
    561                   setupRight = 0;
    562                }
    563                if (lines == 0)
    564                   return;
    565             }
    566 
    567             if (setupLeft && eLeft->lines > 0) {
    568                const SWvertex *vLower = eLeft->v0;
    569                const GLfixed fsy = eLeft->fsy;
    570                const GLfixed fsx = eLeft->fsx;  /* no fractional part */
    571                const GLfixed fx = FixedCeil(fsx);  /* no fractional part */
    572                const GLfixed adjx = (GLfixed) (fx - eLeft->fx0); /* SCALED! */
    573                const GLfixed adjy = (GLfixed) eLeft->adjy;      /* SCALED! */
    574                GLint idxOuter;
    575                GLfloat dxOuter;
    576                GLfixed fdxOuter;
    577 
    578                fError = fx - fsx - FIXED_ONE;
    579                fxLeftEdge = fsx - FIXED_EPSILON;
    580                fdxLeftEdge = eLeft->fdxdy;
    581                fdxOuter = FixedFloor(fdxLeftEdge - FIXED_EPSILON);
    582                fdError = fdxOuter - fdxLeftEdge + FIXED_ONE;
    583                idxOuter = FixedToInt(fdxOuter);
    584                dxOuter = (GLfloat) idxOuter;
    585                span.y = FixedToInt(fsy);
    586 
    587                /* silence warnings on some compilers */
    588                (void) dxOuter;
    589                (void) adjx;
    590                (void) adjy;
    591                (void) vLower;
    592 
    593 #ifdef PIXEL_ADDRESS
    594                {
    595                   pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(FixedToInt(fxLeftEdge), span.y);
    596                   dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE);
    597                   /* negative because Y=0 at bottom and increases upward */
    598                }
    599 #endif
    600                /*
    601                 * Now we need the set of parameter (z, color, etc.) values at
    602                 * the point (fx, fsy).  This gives us properly-sampled parameter
    603                 * values that we can step from pixel to pixel.  Furthermore,
    604                 * although we might have intermediate results that overflow
    605                 * the normal parameter range when we step temporarily outside
    606                 * the triangle, we shouldn't overflow or underflow for any
    607                 * pixel that's actually inside the triangle.
    608                 */
    609 
    610 #ifdef INTERP_Z
    611                {
    612                   GLfloat z0 = vLower->attrib[FRAG_ATTRIB_WPOS][2];
    613                   if (depthBits <= 16) {
    614                      /* interpolate fixed-pt values */
    615                      GLfloat tmp = (z0 * FIXED_SCALE
    616                                     + span.attrStepX[FRAG_ATTRIB_WPOS][2] * adjx
    617                                     + span.attrStepY[FRAG_ATTRIB_WPOS][2] * adjy) + FIXED_HALF;
    618                      if (tmp < MAX_GLUINT / 2)
    619                         zLeft = (GLfixed) tmp;
    620                      else
    621                         zLeft = MAX_GLUINT / 2;
    622                      fdzOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_WPOS][2] +
    623                                                    dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
    624                   }
    625                   else {
    626                      /* interpolate depth values w/out scaling */
    627                      zLeft = (GLuint) (z0 + span.attrStepX[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjx)
    628                                           + span.attrStepY[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjy));
    629                      fdzOuter = (GLint) (span.attrStepY[FRAG_ATTRIB_WPOS][2] +
    630                                          dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
    631                   }
    632 #  ifdef DEPTH_TYPE
    633                   zRow = (DEPTH_TYPE *)
    634                     _swrast_pixel_address(zrb, FixedToInt(fxLeftEdge), span.y);
    635                   dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE);
    636 #  endif
    637                }
    638 #endif
    639 #ifdef INTERP_RGB
    640                if (ctx->Light.ShadeModel == GL_SMOOTH) {
    641                   rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP])
    642                                   + span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx
    643                                   + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) + FIXED_HALF;
    644                   gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP])
    645                                   + span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx
    646                                   + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) + FIXED_HALF;
    647                   bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP])
    648                                   + span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx
    649                                   + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) + FIXED_HALF;
    650                   fdrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][0]
    651                                                 + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0]);
    652                   fdgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][1]
    653                                                 + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1]);
    654                   fdbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][2]
    655                                                 + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2]);
    656 #  ifdef INTERP_ALPHA
    657                   aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP])
    658                                   + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx
    659                                   + span.attrStepY[FRAG_ATTRIB_COL0][3] * adjy) + FIXED_HALF;
    660                   fdaOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][3]
    661                                                 + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]);
    662 #  endif
    663                }
    664                else {
    665                   ASSERT(ctx->Light.ShadeModel == GL_FLAT);
    666                   rLeft = ChanToFixed(v2->color[RCOMP]);
    667                   gLeft = ChanToFixed(v2->color[GCOMP]);
    668                   bLeft = ChanToFixed(v2->color[BCOMP]);
    669                   fdrOuter = fdgOuter = fdbOuter = 0;
    670 #  ifdef INTERP_ALPHA
    671                   aLeft = ChanToFixed(v2->color[ACOMP]);
    672                   fdaOuter = 0;
    673 #  endif
    674                }
    675 #endif /* INTERP_RGB */
    676 
    677 
    678 #ifdef INTERP_INT_TEX
    679                {
    680                   GLfloat s0, t0;
    681                   s0 = vLower->attrib[FRAG_ATTRIB_TEX0][0] * S_SCALE;
    682                   sLeft = (GLfixed)(s0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][0] * adjx
    683                                  + span.attrStepY[FRAG_ATTRIB_TEX0][0] * adjy) + FIXED_HALF;
    684                   dsOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][0]
    685                                                + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][0]);
    686 
    687                   t0 = vLower->attrib[FRAG_ATTRIB_TEX0][1] * T_SCALE;
    688                   tLeft = (GLfixed)(t0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][1] * adjx
    689                                  + span.attrStepY[FRAG_ATTRIB_TEX0][1] * adjy) + FIXED_HALF;
    690                   dtOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][1]
    691                                                + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][1]);
    692                }
    693 #endif
    694 #ifdef INTERP_ATTRIBS
    695                {
    696                   const GLuint attr = FRAG_ATTRIB_WPOS;
    697                   wLeft = vLower->attrib[FRAG_ATTRIB_WPOS][3]
    698                         + (span.attrStepX[attr][3] * adjx
    699                            + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE);
    700                   dwOuter = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3];
    701                }
    702                ATTRIB_LOOP_BEGIN
    703                   const GLfloat invW = vLower->attrib[FRAG_ATTRIB_WPOS][3];
    704                   if (swrast->_InterpMode[attr] == GL_FLAT) {
    705                      GLuint c;
    706                      for (c = 0; c < 4; c++) {
    707                         attrLeft[attr][c] = v2->attrib[attr][c] * invW;
    708                         daOuter[attr][c] = 0.0;
    709                      }
    710                   }
    711                   else {
    712                      GLuint c;
    713                      for (c = 0; c < 4; c++) {
    714                         const GLfloat a = vLower->attrib[attr][c] * invW;
    715                         attrLeft[attr][c] = a + (  span.attrStepX[attr][c] * adjx
    716                                                  + span.attrStepY[attr][c] * adjy) * (1.0F/FIXED_SCALE);
    717                         daOuter[attr][c] = span.attrStepY[attr][c] + dxOuter * span.attrStepX[attr][c];
    718                      }
    719                   }
    720                ATTRIB_LOOP_END
    721 #endif
    722             } /*if setupLeft*/
    723 
    724 
    725             if (setupRight && eRight->lines>0) {
    726                fxRightEdge = eRight->fsx - FIXED_EPSILON;
    727                fdxRightEdge = eRight->fdxdy;
    728             }
    729 
    730             if (lines==0) {
    731                continue;
    732             }
    733 
    734 
    735             /* Rasterize setup */
    736 #ifdef PIXEL_ADDRESS
    737             dPRowInner = dPRowOuter + sizeof(PIXEL_TYPE);
    738 #endif
    739 #ifdef INTERP_Z
    740 #  ifdef DEPTH_TYPE
    741             dZRowInner = dZRowOuter + sizeof(DEPTH_TYPE);
    742 #  endif
    743             fdzInner = fdzOuter + span.zStep;
    744 #endif
    745 #ifdef INTERP_RGB
    746             fdrInner = fdrOuter + span.redStep;
    747             fdgInner = fdgOuter + span.greenStep;
    748             fdbInner = fdbOuter + span.blueStep;
    749 #endif
    750 #ifdef INTERP_ALPHA
    751             fdaInner = fdaOuter + span.alphaStep;
    752 #endif
    753 #ifdef INTERP_INT_TEX
    754             dsInner = dsOuter + span.intTexStep[0];
    755             dtInner = dtOuter + span.intTexStep[1];
    756 #endif
    757 #ifdef INTERP_ATTRIBS
    758             dwInner = dwOuter + span.attrStepX[FRAG_ATTRIB_WPOS][3];
    759             ATTRIB_LOOP_BEGIN
    760                GLuint c;
    761                for (c = 0; c < 4; c++) {
    762                   daInner[attr][c] = daOuter[attr][c] + span.attrStepX[attr][c];
    763                }
    764             ATTRIB_LOOP_END
    765 #endif
    766 
    767             while (lines > 0) {
    768                /* initialize the span interpolants to the leftmost value */
    769                /* ff = fixed-pt fragment */
    770                const GLint right = FixedToInt(fxRightEdge);
    771                span.x = FixedToInt(fxLeftEdge);
    772                if (right <= span.x)
    773                   span.end = 0;
    774                else
    775                   span.end = right - span.x;
    776 
    777 #ifdef INTERP_Z
    778                span.z = zLeft;
    779 #endif
    780 #ifdef INTERP_RGB
    781                span.red = rLeft;
    782                span.green = gLeft;
    783                span.blue = bLeft;
    784 #endif
    785 #ifdef INTERP_ALPHA
    786                span.alpha = aLeft;
    787 #endif
    788 #ifdef INTERP_INT_TEX
    789                span.intTex[0] = sLeft;
    790                span.intTex[1] = tLeft;
    791 #endif
    792 
    793 #ifdef INTERP_ATTRIBS
    794                span.attrStart[FRAG_ATTRIB_WPOS][3] = wLeft;
    795                ATTRIB_LOOP_BEGIN
    796                   GLuint c;
    797                   for (c = 0; c < 4; c++) {
    798                      span.attrStart[attr][c] = attrLeft[attr][c];
    799                   }
    800                ATTRIB_LOOP_END
    801 #endif
    802 
    803                /* This is where we actually generate fragments */
    804                /* XXX the test for span.y > 0 _shouldn't_ be needed but
    805                 * it fixes a problem on 64-bit Opterons (bug 4842).
    806                 */
    807                if (span.end > 0 && span.y >= 0) {
    808                   const GLint len = span.end - 1;
    809                   (void) len;
    810 #ifdef INTERP_RGB
    811                   CLAMP_INTERPOLANT(red, redStep, len);
    812                   CLAMP_INTERPOLANT(green, greenStep, len);
    813                   CLAMP_INTERPOLANT(blue, blueStep, len);
    814 #endif
    815 #ifdef INTERP_ALPHA
    816                   CLAMP_INTERPOLANT(alpha, alphaStep, len);
    817 #endif
    818                   {
    819                      RENDER_SPAN( span );
    820                   }
    821                }
    822 
    823                /*
    824                 * Advance to the next scan line.  Compute the
    825                 * new edge coordinates, and adjust the
    826                 * pixel-center x coordinate so that it stays
    827                 * on or inside the major edge.
    828                 */
    829                span.y++;
    830                lines--;
    831 
    832                fxLeftEdge += fdxLeftEdge;
    833                fxRightEdge += fdxRightEdge;
    834 
    835                fError += fdError;
    836                if (fError >= 0) {
    837                   fError -= FIXED_ONE;
    838 
    839 #ifdef PIXEL_ADDRESS
    840                   pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter);
    841 #endif
    842 #ifdef INTERP_Z
    843 #  ifdef DEPTH_TYPE
    844                   zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowOuter);
    845 #  endif
    846                   zLeft += fdzOuter;
    847 #endif
    848 #ifdef INTERP_RGB
    849                   rLeft += fdrOuter;
    850                   gLeft += fdgOuter;
    851                   bLeft += fdbOuter;
    852 #endif
    853 #ifdef INTERP_ALPHA
    854                   aLeft += fdaOuter;
    855 #endif
    856 #ifdef INTERP_INT_TEX
    857                   sLeft += dsOuter;
    858                   tLeft += dtOuter;
    859 #endif
    860 #ifdef INTERP_ATTRIBS
    861                   wLeft += dwOuter;
    862                   ATTRIB_LOOP_BEGIN
    863                      GLuint c;
    864                      for (c = 0; c < 4; c++) {
    865                         attrLeft[attr][c] += daOuter[attr][c];
    866                      }
    867                   ATTRIB_LOOP_END
    868 #endif
    869                }
    870                else {
    871 #ifdef PIXEL_ADDRESS
    872                   pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowInner);
    873 #endif
    874 #ifdef INTERP_Z
    875 #  ifdef DEPTH_TYPE
    876                   zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowInner);
    877 #  endif
    878                   zLeft += fdzInner;
    879 #endif
    880 #ifdef INTERP_RGB
    881                   rLeft += fdrInner;
    882                   gLeft += fdgInner;
    883                   bLeft += fdbInner;
    884 #endif
    885 #ifdef INTERP_ALPHA
    886                   aLeft += fdaInner;
    887 #endif
    888 #ifdef INTERP_INT_TEX
    889                   sLeft += dsInner;
    890                   tLeft += dtInner;
    891 #endif
    892 #ifdef INTERP_ATTRIBS
    893                   wLeft += dwInner;
    894                   ATTRIB_LOOP_BEGIN
    895                      GLuint c;
    896                      for (c = 0; c < 4; c++) {
    897                         attrLeft[attr][c] += daInner[attr][c];
    898                      }
    899                   ATTRIB_LOOP_END
    900 #endif
    901                }
    902             } /*while lines>0*/
    903 
    904          } /* for subTriangle */
    905 
    906       }
    907    }
    908 }
    909 
    910 #undef SETUP_CODE
    911 #undef RENDER_SPAN
    912 
    913 #undef PIXEL_TYPE
    914 #undef BYTES_PER_ROW
    915 #undef PIXEL_ADDRESS
    916 #undef DEPTH_TYPE
    917 
    918 #undef INTERP_Z
    919 #undef INTERP_RGB
    920 #undef INTERP_ALPHA
    921 #undef INTERP_INT_TEX
    922 #undef INTERP_ATTRIBS
    923 
    924 #undef S_SCALE
    925 #undef T_SCALE
    926 
    927 #undef FixedToDepth
    928 
    929 #undef NAME
    930