Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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