home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / swrast / s_triangle.cpp < prev    next >
C/C++ Source or Header  |  2003-01-02  |  365KB  |  7,552 lines

  1. /* $Id: s_triangle.c,v 1.65 2002/11/13 16:51:01 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  5.1
  6.  *
  7.  * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  8.  *
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27.  
  28. /*
  29.  * When the device driver doesn't implement triangle rasterization it
  30.  * can hook in _swrast_Triangle, which eventually calls one of these
  31.  * functions to draw triangles.
  32.  */
  33.  
  34. #include "glheader.h"
  35. #include "context.h"
  36. #include "colormac.h"
  37. #include "imports.h"
  38. #include "macros.h"
  39. #include "mmath.h"
  40. #include "texformat.h"
  41. #include "teximage.h"
  42. #include "texstate.h"
  43.  
  44. #include "s_aatriangle.h"
  45. #include "s_context.h"
  46. #include "s_depth.h"
  47. #include "s_feedback.h"
  48. #include "s_span.h"
  49. #include "s_triangle.h"
  50.  
  51. #define FIST_MAGIC ((((65536.0 * 65536.0 * 16)+(65536.0 * 0.5))* 65536.0))
  52.  
  53. /*
  54.  * Just used for feedback mode.
  55.  */
  56. GLboolean _mesa_cull_triangle( GLcontext *ctx,
  57.                            const SWvertex *v0,
  58.                            const SWvertex *v1,
  59.                            const SWvertex *v2 )
  60. {
  61.    GLfloat ex = v1->win[0] - v0->win[0];
  62.    GLfloat ey = v1->win[1] - v0->win[1];
  63.    GLfloat fx = v2->win[0] - v0->win[0];
  64.    GLfloat fy = v2->win[1] - v0->win[1];
  65.    GLfloat c = ex*fy-ey*fx;
  66.  
  67.    if (c * ((SWcontext *)ctx->swrast_context)->_backface_sign > 0)
  68.       return 0;
  69.  
  70.    return 1;
  71. }
  72.  
  73.  
  74.  
  75. /*
  76.  * Render a flat-shaded color index triangle.
  77.  */
  78.  
  79. /*
  80.  * Triangle Rasterizer Template
  81.  *
  82.  * This file is #include'd to generate custom triangle rasterizers.
  83.  *
  84.  * The following macros may be defined to indicate what auxillary information
  85.  * must be interplated across the triangle:
  86.  *    INTERP_Z        - if defined, interpolate Z values
  87.  *    INTERP_FOG      - if defined, interpolate fog values
  88.  *    INTERP_RGB      - if defined, interpolate RGB values
  89.  *    INTERP_ALPHA    - if defined, interpolate Alpha values (req's INTERP_RGB)
  90.  *    INTERP_SPEC     - if defined, interpolate specular RGB values
  91.  *    INTERP_INDEX    - if defined, interpolate color index values
  92.  *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
  93.  *                         (fast, simple 2-D texture mapping)
  94.  *    INTERP_TEX      - if defined, interpolate set 0 float STRQ texcoords
  95.  *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
  96.  *    INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
  97.  *    INTERP_FLOAT_RGBA - if defined, interpolate RGBA with floating point
  98.  *    INTERP_FLOAT_SPEC - if defined, interpolate specular with floating point
  99.  *
  100.  * When one can directly address pixels in the color buffer the following
  101.  * macros can be defined and used to compute pixel addresses during
  102.  * rasterization (see pRow):
  103.  *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
  104.  *    BYTES_PER_ROW       - number of bytes per row in the color buffer
  105.  *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
  106.  *                          Y==0 at bottom of screen and increases upward.
  107.  *
  108.  * Similarly, for direct depth buffer access, this type is used for depth
  109.  * buffer addressing:
  110.  *    DEPTH_TYPE          - either GLushort or GLuint
  111.  *
  112.  * Optionally, one may provide one-time setup code per triangle:
  113.  *    SETUP_CODE    - code which is to be executed once per triangle
  114.  *    CLEANUP_CODE    - code to execute at end of triangle
  115.  *
  116.  * The following macro MUST be defined:
  117.  *    RENDER_SPAN(span) - code to write a span of pixels.
  118.  *
  119.  * This code was designed for the origin to be in the lower-left corner.
  120.  *
  121.  * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
  122.  */
  123.  
  124.  
  125. /*
  126.  * This is a bit of a hack, but it's a centralized place to enable floating-
  127.  * point color interpolation when GLchan is actually floating point.
  128.  */
  129.  
  130.  
  131.  
  132. static void flat_ci_triangle(GLcontext *ctx, const SWvertex *v0,
  133.                                  const SWvertex *v1,
  134.                                  const SWvertex *v2 )
  135. {
  136.    typedef struct {
  137.         const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
  138.         GLfloat dx;    /* X(v1) - X(v0) */
  139.         GLfloat dy;    /* Y(v1) - Y(v0) */
  140.         GLfixed fdxdy; /* dx/dy in fixed-point */
  141.         GLfixed fsx;   /* first sample point x coord */
  142.         GLfixed fsy;
  143.         GLfloat adjy;  /* adjust from v[0]->fy to fsy, scaled */
  144.         GLint lines;   /* number of lines to be sampled on this edge */
  145.         GLfixed fx0;   /* fixed pt X of lower endpoint */
  146.    } EdgeT;
  147.  
  148.    const GLint depthBits = ctx->Visual.depthBits;
  149.    const GLfloat maxDepth = ctx->DepthMaxF;
  150.    EdgeT eMaj, eTop, eBot;
  151.    GLfloat oneOverArea;
  152.    const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
  153.    float bf = ((SWcontext *)ctx->swrast_context)->_backface_sign;
  154.    const GLint snapMask = ~((0x00000800 / (1 << 4)) - 1); /* for x/y coord snapping */
  155.    GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
  156.  
  157.    struct sw_span span;
  158.  
  159.      (span).primitive = (0x0009);
  160.      (span).interpMask = (0);
  161.      (span).arrayMask = (0);
  162.      (span).start = 0;
  163.      (span).end = (0);
  164.      (span).facing = 0;
  165.      (span).array = ((SWcontext *)ctx->swrast_context)->SpanArrays;
  166.  
  167.  
  168.    printf("%s()\n", __FUNCTION__);
  169.    /*
  170.    printf("  %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
  171.    printf("  %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
  172.    printf("  %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
  173.     */
  174.  
  175.    /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
  176.     * And find the order of the 3 vertices along the Y axis.
  177.     */
  178.    {
  179.       const GLfixed fy0 = FloatToFixed(v0->win[1] - 0.5F) & snapMask;
  180.       const GLfixed fy1 = FloatToFixed(v1->win[1] - 0.5F) & snapMask;
  181.       const GLfixed fy2 = FloatToFixed(v2->win[1] - 0.5F) & snapMask;
  182.  
  183.       if (fy0 <= fy1) {
  184.          if (fy1 <= fy2) {
  185.             /* y0 <= y1 <= y2 */
  186.             vMin = v0;   vMid = v1;   vMax = v2;
  187.             vMin_fy = fy0;  vMid_fy = fy1;  vMax_fy = fy2;
  188.          }
  189.          else if (fy2 <= fy0) {
  190.             /* y2 <= y0 <= y1 */
  191.             vMin = v2;   vMid = v0;   vMax = v1;
  192.             vMin_fy = fy2;  vMid_fy = fy0;  vMax_fy = fy1;
  193.          }
  194.          else {
  195.             /* y0 <= y2 <= y1 */
  196.             vMin = v0;   vMid = v2;   vMax = v1;
  197.             vMin_fy = fy0;  vMid_fy = fy2;  vMax_fy = fy1;
  198.             bf = -bf;
  199.          }
  200.       }
  201.       else {
  202.          if (fy0 <= fy2) {
  203.             /* y1 <= y0 <= y2 */
  204.             vMin = v1;   vMid = v0;   vMax = v2;
  205.             vMin_fy = fy1;  vMid_fy = fy0;  vMax_fy = fy2;
  206.             bf = -bf;
  207.          }
  208.          else if (fy2 <= fy1) {
  209.             /* y2 <= y1 <= y0 */
  210.             vMin = v2;   vMid = v1;   vMax = v0;
  211.             vMin_fy = fy2;  vMid_fy = fy1;  vMax_fy = fy0;
  212.             bf = -bf;
  213.          }
  214.          else {
  215.             /* y1 <= y2 <= y0 */
  216.             vMin = v1;   vMid = v2;   vMax = v0;
  217.             vMin_fy = fy1;  vMid_fy = fy2;  vMax_fy = fy0;
  218.          }
  219.       }
  220.  
  221.       /* fixed point X coords */
  222.       vMin_fx = (((int) ((((vMin->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMin->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMin->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  223.       vMid_fx = (((int) ((((vMid->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMid->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMid->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  224.       vMax_fx = (((int) ((((vMax->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMax->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMax->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  225.    }
  226.  
  227.    /* vertex/edge relationship */
  228.    eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
  229.    eTop.v0 = vMid;   eTop.v1 = vMax;
  230.    eBot.v0 = vMin;   eBot.v1 = vMid;
  231.  
  232.    /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
  233.    eMaj.dx = ((vMax_fx - vMin_fx) * (1.0F / 2048.0f));
  234.    eMaj.dy = ((vMax_fy - vMin_fy) * (1.0F / 2048.0f));
  235.    eTop.dx = ((vMax_fx - vMid_fx) * (1.0F / 2048.0f));
  236.    eTop.dy = ((vMax_fy - vMid_fy) * (1.0F / 2048.0f));
  237.    eBot.dx = ((vMid_fx - vMin_fx) * (1.0F / 2048.0f));
  238.    eBot.dy = ((vMid_fy - vMin_fy) * (1.0F / 2048.0f));
  239.  
  240.    /* compute area, oneOverArea and perform backface culling */
  241.    {
  242.       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
  243.  
  244.       /* Do backface culling */
  245.       if (area * bf < 0.0)
  246.          return;
  247.  
  248.       if (IS_INF_OR_NAN(area) || area == 0.0F)
  249.          return;
  250.  
  251.       oneOverArea = 1.0F / area;
  252.    }
  253.  
  254.    ctx->OcclusionResult = 0x1;
  255.    span.facing = ctx->_Facing; /* for 2-sided stencil test */
  256.  
  257.    /* Edge setup.  For a triangle strip these could be reused... */
  258.    {
  259.       eMaj.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  260.       eMaj.lines = (((((vMax_fy - eMaj.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  261.       if (eMaj.lines > 0) {
  262.          GLfloat dxdy = eMaj.dx / eMaj.dy;
  263.          eMaj.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  264.          eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
  265.          eMaj.fx0 = vMin_fx;
  266.          eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy);
  267.       }
  268.       else {
  269.          return;  /*CULLED*/
  270.       }
  271.  
  272.       eTop.fsy = (((vMid_fy) + 0x00000800 - 1) & (~0x000007FF));
  273.       eTop.lines = (((((vMax_fy - eTop.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  274.       if (eTop.lines > 0) {
  275.          GLfloat dxdy = eTop.dx / eTop.dy;
  276.          eTop.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  277.          eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
  278.          eTop.fx0 = vMid_fx;
  279.          eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy);
  280.       }
  281.  
  282.       eBot.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  283.       eBot.lines = (((((vMid_fy - eBot.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  284.       if (eBot.lines > 0) {
  285.          GLfloat dxdy = eBot.dx / eBot.dy;
  286.          eBot.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  287.          eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
  288.          eBot.fx0 = vMin_fx;
  289.          eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy);
  290.       }
  291.    }
  292.  
  293.    /*
  294.     * Conceptually, we view a triangle as two subtriangles
  295.     * separated by a perfectly horizontal line.  The edge that is
  296.     * intersected by this line is one with maximal absolute dy; we
  297.     * call it a ``major'' edge.  The other two edges are the
  298.     * ``top'' edge (for the upper subtriangle) and the ``bottom''
  299.     * edge (for the lower subtriangle).  If either of these two
  300.     * edges is horizontal or very close to horizontal, the
  301.     * corresponding subtriangle might cover zero sample points;
  302.     * we take care to handle such cases, for performance as well
  303.     * as correctness.
  304.     *
  305.     * By stepping rasterization parameters along the major edge,
  306.     * we can avoid recomputing them at the discontinuity where
  307.     * the top and bottom edges meet.  However, this forces us to
  308.     * be able to scan both left-to-right and right-to-left.
  309.     * Also, we must determine whether the major edge is at the
  310.     * left or right side of the triangle.  We do this by
  311.     * computing the magnitude of the cross-product of the major
  312.     * and top edges.  Since this magnitude depends on the sine of
  313.     * the angle between the two edges, its sign tells us whether
  314.     * we turn to the left or to the right when travelling along
  315.     * the major edge to the top edge, and from this we infer
  316.     * whether the major edge is on the left or the right.
  317.     *
  318.     * Serendipitously, this cross-product magnitude is also a
  319.     * value we need to compute the iteration parameter
  320.     * derivatives for the triangle, and it can be used to perform
  321.     * backface culling because its sign tells us whether the
  322.     * triangle is clockwise or counterclockwise.  In this code we
  323.     * refer to it as ``area'' because it's also proportional to
  324.     * the pixel area of the triangle.
  325.     */
  326.  
  327.    {
  328.       GLint scan_from_left_to_right;  /* true if scanning left-to-right */
  329.       GLfloat dzdx, dzdy;
  330.       GLfloat dfogdy;
  331.  
  332.       /*
  333.        * Execute user-supplied setup code
  334.        */
  335.       span.interpMask |= 0x004; span.index = ((v2->index) << 11); span.indexStep = 0;
  336.  
  337.       scan_from_left_to_right = (oneOverArea < 0.0F);
  338.  
  339.  
  340.       /* compute d?/dx and d?/dy derivatives */
  341.       span.interpMask |= 0x008;
  342.       {
  343.          GLfloat eMaj_dz, eBot_dz;
  344.          eMaj_dz = vMax->win[2] - vMin->win[2];
  345.          eBot_dz = vMid->win[2] - vMin->win[2];
  346.          dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
  347.          if (dzdx > maxDepth || dzdx < -maxDepth) {
  348.             /* probably a sliver triangle */
  349.             dzdx = 0.0;
  350.             dzdy = 0.0;
  351.          }
  352.          else {
  353.             dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
  354.          }
  355.          if (depthBits <= 16)
  356.             span.zStep = (((int) ((((dzdx) * 2048.0f) >= 0.0F) ? (((dzdx) * 2048.0f) + 0.5F) : (((dzdx) * 2048.0f) - 0.5F))));
  357.          else
  358.             span.zStep = (GLint) dzdx;
  359.       }
  360.       span.interpMask |= 0x010;
  361.       {
  362.          const GLfloat eMaj_dfog = vMax->fog - vMin->fog;
  363.          const GLfloat eBot_dfog = vMid->fog - vMin->fog;
  364.          span.fogStep = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
  365.          dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
  366.       }
  367.  
  368.       /*
  369.        * We always sample at pixel centers.  However, we avoid
  370.        * explicit half-pixel offsets in this code by incorporating
  371.        * the proper offset in each of x and y during the
  372.        * transformation to window coordinates.
  373.        *
  374.        * We also apply the usual rasterization rules to prevent
  375.        * cracks and overlaps.  A pixel is considered inside a
  376.        * subtriangle if it meets all of four conditions: it is on or
  377.        * to the right of the left edge, strictly to the left of the
  378.        * right edge, on or below the top edge, and strictly above
  379.        * the bottom edge.  (Some edges may be degenerate.)
  380.        *
  381.        * The following discussion assumes left-to-right scanning
  382.        * (that is, the major edge is on the left); the right-to-left
  383.        * case is a straightforward variation.
  384.        *
  385.        * We start by finding the half-integral y coordinate that is
  386.        * at or below the top of the triangle.  This gives us the
  387.        * first scan line that could possibly contain pixels that are
  388.        * inside the triangle.
  389.        *
  390.        * Next we creep down the major edge until we reach that y,
  391.        * and compute the corresponding x coordinate on the edge.
  392.        * Then we find the half-integral x that lies on or just
  393.        * inside the edge.  This is the first pixel that might lie in
  394.        * the interior of the triangle.  (We won't know for sure
  395.        * until we check the other edges.)
  396.        *
  397.        * As we rasterize the triangle, we'll step down the major
  398.        * edge.  For each step in y, we'll move an integer number
  399.        * of steps in x.  There are two possible x step sizes, which
  400.        * we'll call the ``inner'' step (guaranteed to land on the
  401.        * edge or inside it) and the ``outer'' step (guaranteed to
  402.        * land on the edge or outside it).  The inner and outer steps
  403.        * differ by one.  During rasterization we maintain an error
  404.        * term that indicates our distance from the true edge, and
  405.        * select either the inner step or the outer step, whichever
  406.        * gets us to the first pixel that falls inside the triangle.
  407.        *
  408.        * All parameters (z, red, etc.) as well as the buffer
  409.        * addresses for color and z have inner and outer step values,
  410.        * so that we can increment them appropriately.  This method
  411.        * eliminates the need to adjust parameters by creeping a
  412.        * sub-pixel amount into the triangle at each scanline.
  413.        */
  414.  
  415.       {
  416.          int subTriangle;
  417.          GLfixed fx;
  418.          GLfixed fxLeftEdge = 0, fxRightEdge = 0;
  419.          GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
  420.          GLfixed fdxOuter;
  421.          int idxOuter;
  422.          float dxOuter;
  423.          GLfixed fError = 0, fdError = 0;
  424.          float adjx, adjy;
  425.          GLfixed fy;
  426.          GLfixed fz = 0, fdzOuter = 0, fdzInner;
  427.          GLfloat fogLeft = 0, dfogOuter = 0, dfogInner;
  428.  
  429.          for (subTriangle=0; subTriangle<=1; subTriangle++) {
  430.             EdgeT *eLeft, *eRight;
  431.             int setupLeft, setupRight;
  432.             int lines;
  433.  
  434.             if (subTriangle==0) {
  435.                /* bottom half */
  436.                if (scan_from_left_to_right) {
  437.                   eLeft = &eMaj;
  438.                   eRight = &eBot;
  439.                   lines = eRight->lines;
  440.                   setupLeft = 1;
  441.                   setupRight = 1;
  442.                }
  443.                else {
  444.                   eLeft = &eBot;
  445.                   eRight = &eMaj;
  446.                   lines = eLeft->lines;
  447.                   setupLeft = 1;
  448.                   setupRight = 1;
  449.                }
  450.             }
  451.             else {
  452.                /* top half */
  453.                if (scan_from_left_to_right) {
  454.                   eLeft = &eMaj;
  455.                   eRight = &eTop;
  456.                   lines = eRight->lines;
  457.                   setupLeft = 0;
  458.                   setupRight = 1;
  459.                }
  460.                else {
  461.                   eLeft = &eTop;
  462.                   eRight = &eMaj;
  463.                   lines = eLeft->lines;
  464.                   setupLeft = 1;
  465.                   setupRight = 0;
  466.                }
  467.                if (lines == 0)
  468.                   return;
  469.             }
  470.  
  471.             if (setupLeft && eLeft->lines > 0) {
  472.                const SWvertex *vLower;
  473.                GLfixed fsx = eLeft->fsx;
  474.                fx = (((fsx) + 0x00000800 - 1) & (~0x000007FF));
  475.                fError = fx - fsx - 0x00000800;
  476.                fxLeftEdge = fsx - 1;
  477.                fdxLeftEdge = eLeft->fdxdy;
  478.                fdxOuter = ((fdxLeftEdge - 1) & (~0x000007FF));
  479.                fdError = fdxOuter - fdxLeftEdge + 0x00000800;
  480.                idxOuter = ((fdxOuter) >> 11);
  481.                dxOuter = (float) idxOuter;
  482.                (void) dxOuter;
  483.  
  484.                fy = eLeft->fsy;
  485.                span.y = ((fy) >> 11);
  486.  
  487.                adjx = (float)(fx - eLeft->fx0);  /* SCALED! */
  488.                adjy = eLeft->adjy;              /* SCALED! */
  489.                vLower = eLeft->v0;
  490.  
  491.                /*
  492.                 * Now we need the set of parameter (z, color, etc.) values at
  493.                 * the point (fx, fy).  This gives us properly-sampled parameter
  494.                 * values that we can step from pixel to pixel.  Furthermore,
  495.                 * although we might have intermediate results that overflow
  496.                 * the normal parameter range when we step temporarily outside
  497.                 * the triangle, we shouldn't overflow or underflow for any
  498.                 * pixel that's actually inside the triangle.
  499.                 */
  500.  
  501.                {
  502.                   GLfloat z0 = vLower->win[2];
  503.                   if (depthBits <= 16) {
  504.                      /* interpolate fixed-pt values */
  505.                      GLfloat tmp = (z0 * 2048.0f +
  506.                                     dzdx * adjx + dzdy * adjy) + 0x00000400;
  507.                      if (tmp < 0xffffffff / 2)
  508.                         fz = (GLfixed) tmp;
  509.                      else
  510.                         fz = 0xffffffff / 2;
  511.                      fdzOuter = (((int) ((((dzdy + dxOuter * dzdx) * 2048.0f) >= 0.0F) ? (((dzdy + dxOuter * dzdx) * 2048.0f) + 0.5F) : (((dzdy + dxOuter * dzdx) * 2048.0f) - 0.5F))));
  512.                   }
  513.                   else {
  514.                      /* interpolate depth values exactly */
  515.                      fz = (GLint) (z0 + dzdx * ((adjx) * (1.0F / 2048.0f))
  516.                                    + dzdy * ((adjy) * (1.0F / 2048.0f)));
  517.                      fdzOuter = (GLint) (dzdy + dxOuter * dzdx);
  518.                   }
  519.                }
  520.                fogLeft = vLower->fog + (span.fogStep * adjx + dfogdy * adjy)
  521.                                        * (1.0F/2048.0f);
  522.                dfogOuter = dfogdy + dxOuter * span.fogStep;
  523.  
  524.             } /*if setupLeft*/
  525.  
  526.  
  527.             if (setupRight && eRight->lines>0) {
  528.                fxRightEdge = eRight->fsx - 1;
  529.                fdxRightEdge = eRight->fdxdy;
  530.             }
  531.  
  532.             if (lines==0) {
  533.                continue;
  534.             }
  535.  
  536.  
  537.             /* Rasterize setup */
  538.             fdzInner = fdzOuter + span.zStep;
  539.             dfogInner = dfogOuter + span.fogStep;
  540.  
  541.             while (lines > 0) {
  542.                /* initialize the span interpolants to the leftmost value */
  543.                /* ff = fixed-pt fragment */
  544.                const GLint right = ((fxRightEdge) >> 11);
  545.  
  546.                span.x = ((fxLeftEdge) >> 11);
  547.  
  548.                if (right <= span.x)
  549.                   span.end = 0;
  550.                else
  551.                   span.end = right - span.x;
  552.  
  553.                span.z = fz;
  554.                span.fog = fogLeft;
  555.  
  556.  
  557.  
  558.  
  559.                /* This is where we actually generate fragments */
  560.                if (span.end > 0) {
  561.                   _mesa_write_index_span(ctx, &span);;
  562.                }
  563.  
  564.                /*
  565.                 * Advance to the next scan line.  Compute the
  566.                 * new edge coordinates, and adjust the
  567.                 * pixel-center x coordinate so that it stays
  568.                 * on or inside the major edge.
  569.                 */
  570.                (span.y)++;
  571.                lines--;
  572.  
  573.                fxLeftEdge += fdxLeftEdge;
  574.                fxRightEdge += fdxRightEdge;
  575.  
  576.  
  577.                fError += fdError;
  578.                if (fError >= 0) {
  579.                   fError -= 0x00000800;
  580.                   fz += fdzOuter;
  581.                   fogLeft += dfogOuter;
  582.                }
  583.                else {
  584.                   fz += fdzInner;
  585.                   fogLeft += dfogInner;
  586.                }
  587.             } /*while lines>0*/
  588.  
  589.          } /* for subTriangle */
  590.  
  591.       }
  592.    }
  593. }
  594.  
  595.  
  596. /*
  597.  * Render a smooth-shaded color index triangle.
  598.  */
  599. /*
  600.  * Triangle Rasterizer Template
  601.  *
  602.  * This file is #include'd to generate custom triangle rasterizers.
  603.  *
  604.  * The following macros may be defined to indicate what auxillary information
  605.  * must be interplated across the triangle:
  606.  *    INTERP_Z        - if defined, interpolate Z values
  607.  *    INTERP_FOG      - if defined, interpolate fog values
  608.  *    INTERP_RGB      - if defined, interpolate RGB values
  609.  *    INTERP_ALPHA    - if defined, interpolate Alpha values (req's INTERP_RGB)
  610.  *    INTERP_SPEC     - if defined, interpolate specular RGB values
  611.  *    INTERP_INDEX    - if defined, interpolate color index values
  612.  *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
  613.  *                         (fast, simple 2-D texture mapping)
  614.  *    INTERP_TEX      - if defined, interpolate set 0 float STRQ texcoords
  615.  *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
  616.  *    INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
  617.  *    INTERP_FLOAT_RGBA - if defined, interpolate RGBA with floating point
  618.  *    INTERP_FLOAT_SPEC - if defined, interpolate specular with floating point
  619.  *
  620.  * When one can directly address pixels in the color buffer the following
  621.  * macros can be defined and used to compute pixel addresses during
  622.  * rasterization (see pRow):
  623.  *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
  624.  *    BYTES_PER_ROW       - number of bytes per row in the color buffer
  625.  *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
  626.  *                          Y==0 at bottom of screen and increases upward.
  627.  *
  628.  * Similarly, for direct depth buffer access, this type is used for depth
  629.  * buffer addressing:
  630.  *    DEPTH_TYPE          - either GLushort or GLuint
  631.  *
  632.  * Optionally, one may provide one-time setup code per triangle:
  633.  *    SETUP_CODE    - code which is to be executed once per triangle
  634.  *    CLEANUP_CODE    - code to execute at end of triangle
  635.  *
  636.  * The following macro MUST be defined:
  637.  *    RENDER_SPAN(span) - code to write a span of pixels.
  638.  *
  639.  * This code was designed for the origin to be in the lower-left corner.
  640.  *
  641.  * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
  642.  */
  643.  
  644.  
  645. /*
  646.  * This is a bit of a hack, but it's a centralized place to enable floating-
  647.  * point color interpolation when GLchan is actually floating point.
  648.  */
  649.  
  650.  
  651.  
  652. static void smooth_ci_triangle(GLcontext *ctx, const SWvertex *v0,
  653.                                  const SWvertex *v1,
  654.                                  const SWvertex *v2 )
  655. {
  656.    typedef struct {
  657.         const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
  658.         GLfloat dx;    /* X(v1) - X(v0) */
  659.         GLfloat dy;    /* Y(v1) - Y(v0) */
  660.         GLfixed fdxdy; /* dx/dy in fixed-point */
  661.         GLfixed fsx;   /* first sample point x coord */
  662.         GLfixed fsy;
  663.         GLfloat adjy;  /* adjust from v[0]->fy to fsy, scaled */
  664.         GLint lines;   /* number of lines to be sampled on this edge */
  665.         GLfixed fx0;   /* fixed pt X of lower endpoint */
  666.    } EdgeT;
  667.  
  668.    const GLint depthBits = ctx->Visual.depthBits;
  669.    const GLfloat maxDepth = ctx->DepthMaxF;
  670.    EdgeT eMaj, eTop, eBot;
  671.    GLfloat oneOverArea;
  672.    const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
  673.    float bf = ((SWcontext *)ctx->swrast_context)->_backface_sign;
  674.    const GLint snapMask = ~((0x00000800 / (1 << 4)) - 1); /* for x/y coord snapping */
  675.    GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
  676.  
  677.    struct sw_span span;
  678.  
  679.    (span).primitive = (0x0009);
  680.    (span).interpMask = (0);
  681.    (span).arrayMask = (0);
  682.    (span).start = 0;
  683.    (span).end = (0);
  684.    (span).facing = 0;
  685.    (span).array = ((SWcontext *)ctx->swrast_context)->SpanArrays;
  686.  
  687.  
  688.    printf("%s()\n", __FUNCTION__);
  689.    /*
  690.    printf("  %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
  691.    printf("  %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
  692.    printf("  %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
  693.     */
  694.  
  695.    /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
  696.     * And find the order of the 3 vertices along the Y axis.
  697.     */
  698.    {
  699.       const GLfixed fy0 = FloatToFixed(v0->win[1] - 0.5F) & snapMask;
  700.       const GLfixed fy1 = FloatToFixed(v1->win[1] - 0.5F) & snapMask;
  701.       const GLfixed fy2 = FloatToFixed(v2->win[1] - 0.5F) & snapMask;
  702.  
  703.       if (fy0 <= fy1) {
  704.          if (fy1 <= fy2) {
  705.             /* y0 <= y1 <= y2 */
  706.             vMin = v0;   vMid = v1;   vMax = v2;
  707.             vMin_fy = fy0;  vMid_fy = fy1;  vMax_fy = fy2;
  708.          }
  709.          else if (fy2 <= fy0) {
  710.             /* y2 <= y0 <= y1 */
  711.             vMin = v2;   vMid = v0;   vMax = v1;
  712.             vMin_fy = fy2;  vMid_fy = fy0;  vMax_fy = fy1;
  713.          }
  714.          else {
  715.             /* y0 <= y2 <= y1 */
  716.             vMin = v0;   vMid = v2;   vMax = v1;
  717.             vMin_fy = fy0;  vMid_fy = fy2;  vMax_fy = fy1;
  718.             bf = -bf;
  719.          }
  720.       }
  721.       else {
  722.          if (fy0 <= fy2) {
  723.             /* y1 <= y0 <= y2 */
  724.             vMin = v1;   vMid = v0;   vMax = v2;
  725.             vMin_fy = fy1;  vMid_fy = fy0;  vMax_fy = fy2;
  726.             bf = -bf;
  727.          }
  728.          else if (fy2 <= fy1) {
  729.             /* y2 <= y1 <= y0 */
  730.             vMin = v2;   vMid = v1;   vMax = v0;
  731.             vMin_fy = fy2;  vMid_fy = fy1;  vMax_fy = fy0;
  732.             bf = -bf;
  733.          }
  734.          else {
  735.             /* y1 <= y2 <= y0 */
  736.             vMin = v1;   vMid = v2;   vMax = v0;
  737.             vMin_fy = fy1;  vMid_fy = fy2;  vMax_fy = fy0;
  738.          }
  739.       }
  740.  
  741.       /* fixed point X coords */
  742.       vMin_fx = (((int) ((((vMin->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMin->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMin->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  743.       vMid_fx = (((int) ((((vMid->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMid->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMid->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  744.       vMax_fx = (((int) ((((vMax->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMax->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMax->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  745.    }
  746.  
  747.    /* vertex/edge relationship */
  748.    eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
  749.    eTop.v0 = vMid;   eTop.v1 = vMax;
  750.    eBot.v0 = vMin;   eBot.v1 = vMid;
  751.  
  752.    /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
  753.    eMaj.dx = ((vMax_fx - vMin_fx) * (1.0F / 2048.0f));
  754.    eMaj.dy = ((vMax_fy - vMin_fy) * (1.0F / 2048.0f));
  755.    eTop.dx = ((vMax_fx - vMid_fx) * (1.0F / 2048.0f));
  756.    eTop.dy = ((vMax_fy - vMid_fy) * (1.0F / 2048.0f));
  757.    eBot.dx = ((vMid_fx - vMin_fx) * (1.0F / 2048.0f));
  758.    eBot.dy = ((vMid_fy - vMin_fy) * (1.0F / 2048.0f));
  759.  
  760.    /* compute area, oneOverArea and perform backface culling */
  761.    {
  762.       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
  763.  
  764.       /* Do backface culling */
  765.       if (area * bf < 0.0)
  766.          return;
  767.  
  768.       if (IS_INF_OR_NAN(area) || area == 0.0F)
  769.          return;
  770.  
  771.       oneOverArea = 1.0F / area;
  772.    }
  773.  
  774.    ctx->OcclusionResult = 0x1;
  775.    span.facing = ctx->_Facing; /* for 2-sided stencil test */
  776.  
  777.    /* Edge setup.  For a triangle strip these could be reused... */
  778.    {
  779.       eMaj.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  780.       eMaj.lines = (((((vMax_fy - eMaj.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  781.       if (eMaj.lines > 0) {
  782.          GLfloat dxdy = eMaj.dx / eMaj.dy;
  783.          eMaj.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  784.          eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
  785.          eMaj.fx0 = vMin_fx;
  786.          eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy);
  787.       }
  788.       else {
  789.          return;  /*CULLED*/
  790.       }
  791.  
  792.       eTop.fsy = (((vMid_fy) + 0x00000800 - 1) & (~0x000007FF));
  793.       eTop.lines = (((((vMax_fy - eTop.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  794.       if (eTop.lines > 0) {
  795.          GLfloat dxdy = eTop.dx / eTop.dy;
  796.          eTop.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  797.          eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
  798.          eTop.fx0 = vMid_fx;
  799.          eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy);
  800.       }
  801.  
  802.       eBot.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  803.       eBot.lines = (((((vMid_fy - eBot.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  804.       if (eBot.lines > 0) {
  805.          GLfloat dxdy = eBot.dx / eBot.dy;
  806.          eBot.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  807.          eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
  808.          eBot.fx0 = vMin_fx;
  809.          eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy);
  810.       }
  811.    }
  812.  
  813.    /*
  814.     * Conceptually, we view a triangle as two subtriangles
  815.     * separated by a perfectly horizontal line.  The edge that is
  816.     * intersected by this line is one with maximal absolute dy; we
  817.     * call it a ``major'' edge.  The other two edges are the
  818.     * ``top'' edge (for the upper subtriangle) and the ``bottom''
  819.     * edge (for the lower subtriangle).  If either of these two
  820.     * edges is horizontal or very close to horizontal, the
  821.     * corresponding subtriangle might cover zero sample points;
  822.     * we take care to handle such cases, for performance as well
  823.     * as correctness.
  824.     *
  825.     * By stepping rasterization parameters along the major edge,
  826.     * we can avoid recomputing them at the discontinuity where
  827.     * the top and bottom edges meet.  However, this forces us to
  828.     * be able to scan both left-to-right and right-to-left.
  829.     * Also, we must determine whether the major edge is at the
  830.     * left or right side of the triangle.  We do this by
  831.     * computing the magnitude of the cross-product of the major
  832.     * and top edges.  Since this magnitude depends on the sine of
  833.     * the angle between the two edges, its sign tells us whether
  834.     * we turn to the left or to the right when travelling along
  835.     * the major edge to the top edge, and from this we infer
  836.     * whether the major edge is on the left or the right.
  837.     *
  838.     * Serendipitously, this cross-product magnitude is also a
  839.     * value we need to compute the iteration parameter
  840.     * derivatives for the triangle, and it can be used to perform
  841.     * backface culling because its sign tells us whether the
  842.     * triangle is clockwise or counterclockwise.  In this code we
  843.     * refer to it as ``area'' because it's also proportional to
  844.     * the pixel area of the triangle.
  845.     */
  846.  
  847.    {
  848.       GLint scan_from_left_to_right;  /* true if scanning left-to-right */
  849.       GLfloat dzdx, dzdy;
  850.       GLfloat dfogdy;
  851.       GLfloat didx, didy;
  852.  
  853.       /*
  854.        * Execute user-supplied setup code
  855.        */
  856.  
  857.       scan_from_left_to_right = (oneOverArea < 0.0F);
  858.  
  859.  
  860.       /* compute d?/dx and d?/dy derivatives */
  861.       span.interpMask |= 0x008;
  862.       {
  863.          GLfloat eMaj_dz, eBot_dz;
  864.          eMaj_dz = vMax->win[2] - vMin->win[2];
  865.          eBot_dz = vMid->win[2] - vMin->win[2];
  866.          dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
  867.          if (dzdx > maxDepth || dzdx < -maxDepth) {
  868.             /* probably a sliver triangle */
  869.             dzdx = 0.0;
  870.             dzdy = 0.0;
  871.          }
  872.          else {
  873.             dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
  874.          }
  875.          if (depthBits <= 16)
  876.             span.zStep = (((int) ((((dzdx) * 2048.0f) >= 0.0F) ? (((dzdx) * 2048.0f) + 0.5F) : (((dzdx) * 2048.0f) - 0.5F))));
  877.          else
  878.             span.zStep = (GLint) dzdx;
  879.       }
  880.       span.interpMask |= 0x010;
  881.       {
  882.          const GLfloat eMaj_dfog = vMax->fog - vMin->fog;
  883.          const GLfloat eBot_dfog = vMid->fog - vMin->fog;
  884.          span.fogStep = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
  885.          dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
  886.       }
  887.       span.interpMask |= 0x004;
  888.       if (ctx->Light.ShadeModel == 0x1D01) {
  889.          GLfloat eMaj_di, eBot_di;
  890.          eMaj_di = (GLfloat) ((GLint) vMax->index - (GLint) vMin->index);
  891.          eBot_di = (GLfloat) ((GLint) vMid->index - (GLint) vMin->index);
  892.          didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di);
  893.          span.indexStep = (((int) ((((didx) * 2048.0f) >= 0.0F) ? (((didx) * 2048.0f) + 0.5F) : (((didx) * 2048.0f) - 0.5F))));
  894.          didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx);
  895.       }
  896.       else {
  897.          span.interpMask |= 0x200;
  898.          didx = didy = 0.0F;
  899.          span.indexStep = 0;
  900.       }
  901.  
  902.       /*
  903.        * We always sample at pixel centers.  However, we avoid
  904.        * explicit half-pixel offsets in this code by incorporating
  905.        * the proper offset in each of x and y during the
  906.        * transformation to window coordinates.
  907.        *
  908.        * We also apply the usual rasterization rules to prevent
  909.        * cracks and overlaps.  A pixel is considered inside a
  910.        * subtriangle if it meets all of four conditions: it is on or
  911.        * to the right of the left edge, strictly to the left of the
  912.        * right edge, on or below the top edge, and strictly above
  913.        * the bottom edge.  (Some edges may be degenerate.)
  914.        *
  915.        * The following discussion assumes left-to-right scanning
  916.        * (that is, the major edge is on the left); the right-to-left
  917.        * case is a straightforward variation.
  918.        *
  919.        * We start by finding the half-integral y coordinate that is
  920.        * at or below the top of the triangle.  This gives us the
  921.        * first scan line that could possibly contain pixels that are
  922.        * inside the triangle.
  923.        *
  924.        * Next we creep down the major edge until we reach that y,
  925.        * and compute the corresponding x coordinate on the edge.
  926.        * Then we find the half-integral x that lies on or just
  927.        * inside the edge.  This is the first pixel that might lie in
  928.        * the interior of the triangle.  (We won't know for sure
  929.        * until we check the other edges.)
  930.        *
  931.        * As we rasterize the triangle, we'll step down the major
  932.        * edge.  For each step in y, we'll move an integer number
  933.        * of steps in x.  There are two possible x step sizes, which
  934.        * we'll call the ``inner'' step (guaranteed to land on the
  935.        * edge or inside it) and the ``outer'' step (guaranteed to
  936.        * land on the edge or outside it).  The inner and outer steps
  937.        * differ by one.  During rasterization we maintain an error
  938.        * term that indicates our distance from the true edge, and
  939.        * select either the inner step or the outer step, whichever
  940.        * gets us to the first pixel that falls inside the triangle.
  941.        *
  942.        * All parameters (z, red, etc.) as well as the buffer
  943.        * addresses for color and z have inner and outer step values,
  944.        * so that we can increment them appropriately.  This method
  945.        * eliminates the need to adjust parameters by creeping a
  946.        * sub-pixel amount into the triangle at each scanline.
  947.        */
  948.  
  949.       {
  950.          int subTriangle;
  951.          GLfixed fx;
  952.          GLfixed fxLeftEdge = 0, fxRightEdge = 0;
  953.          GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
  954.          GLfixed fdxOuter;
  955.          int idxOuter;
  956.          float dxOuter;
  957.          GLfixed fError = 0, fdError = 0;
  958.          float adjx, adjy;
  959.          GLfixed fy;
  960.          GLfixed fz = 0, fdzOuter = 0, fdzInner;
  961.          GLfloat fogLeft = 0, dfogOuter = 0, dfogInner;
  962.          GLfixed fi=0, fdiOuter=0, fdiInner;
  963.  
  964.          for (subTriangle=0; subTriangle<=1; subTriangle++) {
  965.             EdgeT *eLeft, *eRight;
  966.             int setupLeft, setupRight;
  967.             int lines;
  968.  
  969.             if (subTriangle==0) {
  970.                /* bottom half */
  971.                if (scan_from_left_to_right) {
  972.                   eLeft = &eMaj;
  973.                   eRight = &eBot;
  974.                   lines = eRight->lines;
  975.                   setupLeft = 1;
  976.                   setupRight = 1;
  977.                }
  978.                else {
  979.                   eLeft = &eBot;
  980.                   eRight = &eMaj;
  981.                   lines = eLeft->lines;
  982.                   setupLeft = 1;
  983.                   setupRight = 1;
  984.                }
  985.             }
  986.             else {
  987.                /* top half */
  988.                if (scan_from_left_to_right) {
  989.                   eLeft = &eMaj;
  990.                   eRight = &eTop;
  991.                   lines = eRight->lines;
  992.                   setupLeft = 0;
  993.                   setupRight = 1;
  994.                }
  995.                else {
  996.                   eLeft = &eTop;
  997.                   eRight = &eMaj;
  998.                   lines = eLeft->lines;
  999.                   setupLeft = 1;
  1000.                   setupRight = 0;
  1001.                }
  1002.                if (lines == 0)
  1003.                   return;
  1004.             }
  1005.  
  1006.             if (setupLeft && eLeft->lines > 0) {
  1007.                const SWvertex *vLower;
  1008.                GLfixed fsx = eLeft->fsx;
  1009.                fx = (((fsx) + 0x00000800 - 1) & (~0x000007FF));
  1010.                fError = fx - fsx - 0x00000800;
  1011.                fxLeftEdge = fsx - 1;
  1012.                fdxLeftEdge = eLeft->fdxdy;
  1013.                fdxOuter = ((fdxLeftEdge - 1) & (~0x000007FF));
  1014.                fdError = fdxOuter - fdxLeftEdge + 0x00000800;
  1015.                idxOuter = ((fdxOuter) >> 11);
  1016.                dxOuter = (float) idxOuter;
  1017.                (void) dxOuter;
  1018.  
  1019.                fy = eLeft->fsy;
  1020.                span.y = ((fy) >> 11);
  1021.  
  1022.                adjx = (float)(fx - eLeft->fx0);  /* SCALED! */
  1023.                adjy = eLeft->adjy;              /* SCALED! */
  1024.                vLower = eLeft->v0;
  1025.  
  1026.                /*
  1027.                 * Now we need the set of parameter (z, color, etc.) values at
  1028.                 * the point (fx, fy).  This gives us properly-sampled parameter
  1029.                 * values that we can step from pixel to pixel.  Furthermore,
  1030.                 * although we might have intermediate results that overflow
  1031.                 * the normal parameter range when we step temporarily outside
  1032.                 * the triangle, we shouldn't overflow or underflow for any
  1033.                 * pixel that's actually inside the triangle.
  1034.                 */
  1035.  
  1036.                {
  1037.                   GLfloat z0 = vLower->win[2];
  1038.                   if (depthBits <= 16) {
  1039.                      /* interpolate fixed-pt values */
  1040.                      GLfloat tmp = (z0 * 2048.0f +
  1041.                                     dzdx * adjx + dzdy * adjy) + 0x00000400;
  1042.                      if (tmp < 0xffffffff / 2)
  1043.                         fz = (GLfixed) tmp;
  1044.                      else
  1045.                         fz = 0xffffffff / 2;
  1046.                      fdzOuter = (((int) ((((dzdy + dxOuter * dzdx) * 2048.0f) >= 0.0F) ? (((dzdy + dxOuter * dzdx) * 2048.0f) + 0.5F) : (((dzdy + dxOuter * dzdx) * 2048.0f) - 0.5F))));
  1047.                   }
  1048.                   else {
  1049.                      /* interpolate depth values exactly */
  1050.                      fz = (GLint) (z0 + dzdx * ((adjx) * (1.0F / 2048.0f))
  1051.                                    + dzdy * ((adjy) * (1.0F / 2048.0f)));
  1052.                      fdzOuter = (GLint) (dzdy + dxOuter * dzdx);
  1053.                   }
  1054.                }
  1055.                fogLeft = vLower->fog + (span.fogStep * adjx + dfogdy * adjy)
  1056.                                        * (1.0F/2048.0f);
  1057.                dfogOuter = dfogdy + dxOuter * span.fogStep;
  1058.                if (ctx->Light.ShadeModel == 0x1D01) {
  1059.                   fi = (GLfixed)(vLower->index * 2048.0f
  1060.                                  + didx * adjx + didy * adjy) + 0x00000400;
  1061.                   fdiOuter = (((int) ((((didy + dxOuter * didx) * 2048.0f) >= 0.0F) ? (((didy + dxOuter * didx) * 2048.0f) + 0.5F) : (((didy + dxOuter * didx) * 2048.0f) - 0.5F))));
  1062.                }
  1063.                else {
  1064.                   fi = (GLfixed) (v2->index * 2048.0f);
  1065.                   fdiOuter = 0;
  1066.                }
  1067.  
  1068.             } /*if setupLeft*/
  1069.  
  1070.  
  1071.             if (setupRight && eRight->lines>0) {
  1072.                fxRightEdge = eRight->fsx - 1;
  1073.                fdxRightEdge = eRight->fdxdy;
  1074.             }
  1075.  
  1076.             if (lines==0) {
  1077.                continue;
  1078.             }
  1079.  
  1080.  
  1081.             /* Rasterize setup */
  1082.             fdzInner = fdzOuter + span.zStep;
  1083.             dfogInner = dfogOuter + span.fogStep;
  1084.             fdiInner = fdiOuter + span.indexStep;
  1085.  
  1086.             while (lines > 0) {
  1087.                /* initialize the span interpolants to the leftmost value */
  1088.                /* ff = fixed-pt fragment */
  1089.                const GLint right = ((fxRightEdge) >> 11);
  1090.  
  1091.                span.x = ((fxLeftEdge) >> 11);
  1092.  
  1093.                if (right <= span.x)
  1094.                   span.end = 0;
  1095.                else
  1096.                   span.end = right - span.x;
  1097.  
  1098.                span.z = fz;
  1099.                span.fog = fogLeft;
  1100.                span.index = fi;
  1101.  
  1102.  
  1103.  
  1104.                if (span.index < 0)  span.index = 0;
  1105.  
  1106.                /* This is where we actually generate fragments */
  1107.                if (span.end > 0) {
  1108.                   _mesa_write_index_span(ctx, &span);;
  1109.                }
  1110.  
  1111.                /*
  1112.                 * Advance to the next scan line.  Compute the
  1113.                 * new edge coordinates, and adjust the
  1114.                 * pixel-center x coordinate so that it stays
  1115.                 * on or inside the major edge.
  1116.                 */
  1117.                (span.y)++;
  1118.                lines--;
  1119.  
  1120.                fxLeftEdge += fdxLeftEdge;
  1121.                fxRightEdge += fdxRightEdge;
  1122.  
  1123.  
  1124.                fError += fdError;
  1125.                if (fError >= 0) {
  1126.                   fError -= 0x00000800;
  1127.                   fz += fdzOuter;
  1128.                   fogLeft += dfogOuter;
  1129.                   fi += fdiOuter;
  1130.                }
  1131.                else {
  1132.                   fz += fdzInner;
  1133.                   fogLeft += dfogInner;
  1134.                   fi += fdiInner;
  1135.                }
  1136.             } /*while lines>0*/
  1137.  
  1138.          } /* for subTriangle */
  1139.  
  1140.       }
  1141.    }
  1142. }
  1143.  
  1144. /*
  1145.  * Render a flat-shaded RGBA triangle.
  1146.  */
  1147.  
  1148. /*
  1149.  * Triangle Rasterizer Template
  1150.  *
  1151.  * This file is #include'd to generate custom triangle rasterizers.
  1152.  *
  1153.  * The following macros may be defined to indicate what auxillary information
  1154.  * must be interplated across the triangle:
  1155.  *    INTERP_Z        - if defined, interpolate Z values
  1156.  *    INTERP_FOG      - if defined, interpolate fog values
  1157.  *    INTERP_RGB      - if defined, interpolate RGB values
  1158.  *    INTERP_ALPHA    - if defined, interpolate Alpha values (req's INTERP_RGB)
  1159.  *    INTERP_SPEC     - if defined, interpolate specular RGB values
  1160.  *    INTERP_INDEX    - if defined, interpolate color index values
  1161.  *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
  1162.  *                         (fast, simple 2-D texture mapping)
  1163.  *    INTERP_TEX      - if defined, interpolate set 0 float STRQ texcoords
  1164.  *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
  1165.  *    INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
  1166.  *    INTERP_FLOAT_RGBA - if defined, interpolate RGBA with floating point
  1167.  *    INTERP_FLOAT_SPEC - if defined, interpolate specular with floating point
  1168.  *
  1169.  * When one can directly address pixels in the color buffer the following
  1170.  * macros can be defined and used to compute pixel addresses during
  1171.  * rasterization (see pRow):
  1172.  *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
  1173.  *    BYTES_PER_ROW       - number of bytes per row in the color buffer
  1174.  *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
  1175.  *                          Y==0 at bottom of screen and increases upward.
  1176.  *
  1177.  * Similarly, for direct depth buffer access, this type is used for depth
  1178.  * buffer addressing:
  1179.  *    DEPTH_TYPE          - either GLushort or GLuint
  1180.  *
  1181.  * Optionally, one may provide one-time setup code per triangle:
  1182.  *    SETUP_CODE    - code which is to be executed once per triangle
  1183.  *    CLEANUP_CODE    - code to execute at end of triangle
  1184.  *
  1185.  * The following macro MUST be defined:
  1186.  *    RENDER_SPAN(span) - code to write a span of pixels.
  1187.  *
  1188.  * This code was designed for the origin to be in the lower-left corner.
  1189.  *
  1190.  * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
  1191.  */
  1192.  
  1193.  
  1194. /*
  1195.  * This is a bit of a hack, but it's a centralized place to enable floating-
  1196.  * point color interpolation when GLchan is actually floating point.
  1197.  */
  1198.  
  1199.  
  1200.  
  1201. static void flat_rgba_triangle(GLcontext *ctx, const SWvertex *v0,
  1202.                                  const SWvertex *v1,
  1203.                                  const SWvertex *v2 )
  1204. {
  1205.    typedef struct {
  1206.         const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
  1207.         GLfloat dx;    /* X(v1) - X(v0) */
  1208.         GLfloat dy;    /* Y(v1) - Y(v0) */
  1209.         GLfixed fdxdy; /* dx/dy in fixed-point */
  1210.         GLfixed fsx;   /* first sample point x coord */
  1211.         GLfixed fsy;
  1212.         GLfloat adjy;  /* adjust from v[0]->fy to fsy, scaled */
  1213.         GLint lines;   /* number of lines to be sampled on this edge */
  1214.         GLfixed fx0;   /* fixed pt X of lower endpoint */
  1215.    } EdgeT;
  1216.  
  1217.    const GLint depthBits = ctx->Visual.depthBits;
  1218.    const GLfloat maxDepth = ctx->DepthMaxF;
  1219.    EdgeT eMaj, eTop, eBot;
  1220.    GLfloat oneOverArea;
  1221.    const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
  1222.    float bf = ((SWcontext *)ctx->swrast_context)->_backface_sign;
  1223.    const GLint snapMask = ~((0x00000800 / (1 << 4)) - 1); /* for x/y coord snapping */
  1224.    GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
  1225.  
  1226.    struct sw_span span;
  1227.  
  1228.    (span).primitive = (0x0009);
  1229.    (span).interpMask = (0);
  1230.    (span).arrayMask = (0);
  1231.    (span).start = 0;
  1232.    (span).end = (0);
  1233.    (span).facing = 0;
  1234.    (span).array = ((SWcontext *)ctx->swrast_context)->SpanArrays;
  1235.  
  1236.  
  1237.    /*
  1238.    printf("%s()\n", __FUNCTION__);
  1239.    printf("  %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
  1240.    printf("  %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
  1241.    printf("  %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
  1242.     */
  1243.  
  1244.    /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
  1245.     * And find the order of the 3 vertices along the Y axis.
  1246.     */
  1247.    {
  1248.       const GLfixed fy0 = FloatToFixed(v0->win[1] - 0.5F) & snapMask;
  1249.       const GLfixed fy1 = FloatToFixed(v1->win[1] - 0.5F) & snapMask;
  1250.       const GLfixed fy2 = FloatToFixed(v2->win[1] - 0.5F) & snapMask;
  1251.  
  1252.       if (fy0 <= fy1) {
  1253.          if (fy1 <= fy2) {
  1254.             /* y0 <= y1 <= y2 */
  1255.             vMin = v0;   vMid = v1;   vMax = v2;
  1256.             vMin_fy = fy0;  vMid_fy = fy1;  vMax_fy = fy2;
  1257.          }
  1258.          else if (fy2 <= fy0) {
  1259.             /* y2 <= y0 <= y1 */
  1260.             vMin = v2;   vMid = v0;   vMax = v1;
  1261.             vMin_fy = fy2;  vMid_fy = fy0;  vMax_fy = fy1;
  1262.          }
  1263.          else {
  1264.             /* y0 <= y2 <= y1 */
  1265.             vMin = v0;   vMid = v2;   vMax = v1;
  1266.             vMin_fy = fy0;  vMid_fy = fy2;  vMax_fy = fy1;
  1267.             bf = -bf;
  1268.          }
  1269.       }
  1270.       else {
  1271.          if (fy0 <= fy2) {
  1272.             /* y1 <= y0 <= y2 */
  1273.             vMin = v1;   vMid = v0;   vMax = v2;
  1274.             vMin_fy = fy1;  vMid_fy = fy0;  vMax_fy = fy2;
  1275.             bf = -bf;
  1276.          }
  1277.          else if (fy2 <= fy1) {
  1278.             /* y2 <= y1 <= y0 */
  1279.             vMin = v2;   vMid = v1;   vMax = v0;
  1280.             vMin_fy = fy2;  vMid_fy = fy1;  vMax_fy = fy0;
  1281.             bf = -bf;
  1282.          }
  1283.          else {
  1284.             /* y1 <= y2 <= y0 */
  1285.             vMin = v1;   vMid = v2;   vMax = v0;
  1286.             vMin_fy = fy1;  vMid_fy = fy2;  vMax_fy = fy0;
  1287.          }
  1288.       }
  1289.  
  1290.       /* fixed point X coords */
  1291.       vMin_fx = FloatToFixed(vMin->win[0] + 0.5F) & snapMask;
  1292.       vMid_fx = FloatToFixed(vMid->win[0] + 0.5F) & snapMask;
  1293.       vMax_fx = FloatToFixed(vMax->win[0] + 0.5F) & snapMask;
  1294.    }
  1295.  
  1296.    /* vertex/edge relationship */
  1297.    eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
  1298.    eTop.v0 = vMid;   eTop.v1 = vMax;
  1299.    eBot.v0 = vMin;   eBot.v1 = vMid;
  1300.  
  1301.    /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
  1302.    eMaj.dx = FixedToFloat(vMax_fx - vMin_fx);
  1303.    eMaj.dy = FixedToFloat(vMax_fy - vMin_fy);
  1304.    eTop.dx = FixedToFloat(vMax_fx - vMid_fx);
  1305.    eTop.dy = FixedToFloat(vMax_fy - vMid_fy);
  1306.    eBot.dx = FixedToFloat(vMid_fx - vMin_fx);
  1307.    eBot.dy = FixedToFloat(vMid_fy - vMin_fy);
  1308.  
  1309.    /* compute area, oneOverArea and perform backface culling */
  1310.    {
  1311.       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
  1312.  
  1313.       /* Do backface culling */
  1314.       if (area * bf < 0.0)
  1315.          return;
  1316.  
  1317.       if (IS_INF_OR_NAN(area) || area == 0.0F)
  1318.          return;
  1319.  
  1320.       oneOverArea = 1.0F / area;
  1321.    }
  1322.  
  1323.    ctx->OcclusionResult = GL_TRUE;
  1324.    span.facing = ctx->_Facing; /* for 2-sided stencil test */
  1325.  
  1326.    /* Edge setup.  For a triangle strip these could be reused... */
  1327.    {
  1328.       eMaj.fsy =  FixedCeil(vMin_fy);
  1329.       eMaj.lines =  FixedToInt(FixedCeil(vMax_fy - eMaj.fsy));
  1330.       if (eMaj.lines > 0) {
  1331.          GLfloat dxdy = eMaj.dx / eMaj.dy;
  1332.          eMaj.fdxdy = SignedFloatToFixed(dxdy);
  1333.          eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
  1334.          eMaj.fx0 = vMin_fx;
  1335.          eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy);
  1336.       }
  1337.       else {
  1338.          return;  /*CULLED*/
  1339.       }
  1340.  
  1341.       eTop.fsy = FixedCeil(vMid_fy);
  1342.       eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy));
  1343.       if (eTop.lines > 0) {
  1344.          GLfloat dxdy = eTop.dx / eTop.dy;
  1345.          eTop.fdxdy = SignedFloatToFixed(dxdy);
  1346.          eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
  1347.          eTop.fx0 = vMid_fx;
  1348.          eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy);
  1349.       }
  1350.  
  1351.       eBot.fsy = FixedCeil(vMin_fy);
  1352.       eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy));
  1353.       if (eBot.lines > 0) {
  1354.          GLfloat dxdy = eBot.dx / eBot.dy;
  1355.          eBot.fdxdy = SignedFloatToFixed(dxdy);
  1356.          eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
  1357.          eBot.fx0 = vMin_fx;
  1358.          eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy);
  1359.       }
  1360.    }
  1361.  
  1362.    /*
  1363.     * Conceptually, we view a triangle as two subtriangles
  1364.     * separated by a perfectly horizontal line.  The edge that is
  1365.     * intersected by this line is one with maximal absolute dy; we
  1366.     * call it a ``major'' edge.  The other two edges are the
  1367.     * ``top'' edge (for the upper subtriangle) and the ``bottom''
  1368.     * edge (for the lower subtriangle).  If either of these two
  1369.     * edges is horizontal or very close to horizontal, the
  1370.     * corresponding subtriangle might cover zero sample points;
  1371.     * we take care to handle such cases, for performance as well
  1372.     * as correctness.
  1373.     *
  1374.     * By stepping rasterization parameters along the major edge,
  1375.     * we can avoid recomputing them at the discontinuity where
  1376.     * the top and bottom edges meet.  However, this forces us to
  1377.     * be able to scan both left-to-right and right-to-left.
  1378.     * Also, we must determine whether the major edge is at the
  1379.     * left or right side of the triangle.  We do this by
  1380.     * computing the magnitude of the cross-product of the major
  1381.     * and top edges.  Since this magnitude depends on the sine of
  1382.     * the angle between the two edges, its sign tells us whether
  1383.     * we turn to the left or to the right when travelling along
  1384.     * the major edge to the top edge, and from this we infer
  1385.     * whether the major edge is on the left or the right.
  1386.     *
  1387.     * Serendipitously, this cross-product magnitude is also a
  1388.     * value we need to compute the iteration parameter
  1389.     * derivatives for the triangle, and it can be used to perform
  1390.     * backface culling because its sign tells us whether the
  1391.     * triangle is clockwise or counterclockwise.  In this code we
  1392.     * refer to it as ``area'' because it's also proportional to
  1393.     * the pixel area of the triangle.
  1394.     */
  1395.  
  1396.    {
  1397.       GLint scan_from_left_to_right;  /* true if scanning left-to-right */
  1398.       GLfloat dzdx, dzdy;
  1399.       GLfloat dfogdy;
  1400.  
  1401.       /*
  1402.        * Execute user-supplied setup code
  1403.        */
  1404.        span.interpMask |= 0x001;
  1405.        span.red = ((v2->color[0]) << 11);
  1406.        span.green = ((v2->color[1]) << 11);
  1407.        span.blue = ((v2->color[2]) << 11);
  1408.        span.alpha = ((v2->color[3]) << 11);
  1409.        span.redStep = 0; span.greenStep = 0; span.blueStep = 0; span.alphaStep = 0;
  1410.  
  1411.       scan_from_left_to_right = (oneOverArea < 0.0F);
  1412.  
  1413.  
  1414.       /* compute d?/dx and d?/dy derivatives */
  1415.       span.interpMask |=  SPAN_Z;
  1416.       {
  1417.          GLfloat eMaj_dz, eBot_dz;
  1418.          eMaj_dz = vMax->win[2] - vMin->win[2];
  1419.          eBot_dz = vMid->win[2] - vMin->win[2];
  1420.          dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
  1421.          if (dzdx > maxDepth || dzdx < -maxDepth) {
  1422.             /* probably a sliver triangle */
  1423.             dzdx = 0.0;
  1424.             dzdy = 0.0;
  1425.          }
  1426.          else {
  1427.             dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
  1428.          }
  1429.          if (depthBits <= 16)
  1430.             span.zStep = SignedFloatToFixed(dzdx);
  1431.          else
  1432.             span.zStep = (GLint) dzdx;
  1433.       }
  1434.       span.interpMask |=  SPAN_FOG;
  1435.       {
  1436.          const GLfloat eMaj_dfog = vMax->fog - vMin->fog;
  1437.          const GLfloat eBot_dfog = vMid->fog - vMin->fog;
  1438.          span.fogStep = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
  1439.          dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
  1440.       }
  1441.  
  1442.       /*
  1443.        * We always sample at pixel centers.  However, we avoid
  1444.        * explicit half-pixel offsets in this code by incorporating
  1445.        * the proper offset in each of x and y during the
  1446.        * transformation to window coordinates.
  1447.        *
  1448.        * We also apply the usual rasterization rules to prevent
  1449.        * cracks and overlaps.  A pixel is considered inside a
  1450.        * subtriangle if it meets all of four conditions: it is on or
  1451.        * to the right of the left edge, strictly to the left of the
  1452.        * right edge, on or below the top edge, and strictly above
  1453.        * the bottom edge.  (Some edges may be degenerate.)
  1454.        *
  1455.        * The following discussion assumes left-to-right scanning
  1456.        * (that is, the major edge is on the left); the right-to-left
  1457.        * case is a straightforward variation.
  1458.        *
  1459.        * We start by finding the half-integral y coordinate that is
  1460.        * at or below the top of the triangle.  This gives us the
  1461.        * first scan line that could possibly contain pixels that are
  1462.        * inside the triangle.
  1463.        *
  1464.        * Next we creep down the major edge until we reach that y,
  1465.        * and compute the corresponding x coordinate on the edge.
  1466.        * Then we find the half-integral x that lies on or just
  1467.        * inside the edge.  This is the first pixel that might lie in
  1468.        * the interior of the triangle.  (We won't know for sure
  1469.        * until we check the other edges.)
  1470.        *
  1471.        * As we rasterize the triangle, we'll step down the major
  1472.        * edge.  For each step in y, we'll move an integer number
  1473.        * of steps in x.  There are two possible x step sizes, which
  1474.        * we'll call the ``inner'' step (guaranteed to land on the
  1475.        * edge or inside it) and the ``outer'' step (guaranteed to
  1476.        * land on the edge or outside it).  The inner and outer steps
  1477.        * differ by one.  During rasterization we maintain an error
  1478.        * term that indicates our distance from the true edge, and
  1479.        * select either the inner step or the outer step, whichever
  1480.        * gets us to the first pixel that falls inside the triangle.
  1481.        *
  1482.        * All parameters (z, red, etc.) as well as the buffer
  1483.        * addresses for color and z have inner and outer step values,
  1484.        * so that we can increment them appropriately.  This method
  1485.        * eliminates the need to adjust parameters by creeping a
  1486.        * sub-pixel amount into the triangle at each scanline.
  1487.        */
  1488.  
  1489.       {
  1490.          int subTriangle;
  1491.          GLfixed fx;
  1492.          GLfixed fxLeftEdge = 0, fxRightEdge = 0;
  1493.          GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
  1494.          GLfixed fdxOuter;
  1495.          int idxOuter;
  1496.          float dxOuter;
  1497.          GLfixed fError = 0, fdError = 0;
  1498.          float adjx, adjy;
  1499.          GLfixed fy;
  1500.          GLushort *zRow = 0;
  1501.          int dZRowOuter = 0, dZRowInner;  /* offset in bytes */
  1502.          GLfixed fz = 0, fdzOuter = 0, fdzInner;
  1503.          GLfloat fogLeft = 0, dfogOuter = 0, dfogInner;
  1504.  
  1505.          for (subTriangle=0; subTriangle<=1; subTriangle++) {
  1506.             EdgeT *eLeft, *eRight;
  1507.             int setupLeft, setupRight;
  1508.             int lines;
  1509.  
  1510.             if (subTriangle==0) {
  1511.                /* bottom half */
  1512.                if (scan_from_left_to_right) {
  1513.                   eLeft = &eMaj;
  1514.                   eRight = &eBot;
  1515.                   lines = eRight->lines;
  1516.                   setupLeft = 1;
  1517.                   setupRight = 1;
  1518.                }
  1519.                else {
  1520.                   eLeft = &eBot;
  1521.                   eRight = &eMaj;
  1522.                   lines = eLeft->lines;
  1523.                   setupLeft = 1;
  1524.                   setupRight = 1;
  1525.                }
  1526.             }
  1527.             else {
  1528.                /* top half */
  1529.                if (scan_from_left_to_right) {
  1530.                   eLeft = &eMaj;
  1531.                   eRight = &eTop;
  1532.                   lines = eRight->lines;
  1533.                   setupLeft = 0;
  1534.                   setupRight = 1;
  1535.                }
  1536.                else {
  1537.                   eLeft = &eTop;
  1538.                   eRight = &eMaj;
  1539.                   lines = eLeft->lines;
  1540.                   setupLeft = 1;
  1541.                   setupRight = 0;
  1542.                }
  1543.                if (lines == 0)
  1544.                   return;
  1545.             }
  1546.  
  1547.             if (setupLeft && eLeft->lines > 0) {
  1548.                const SWvertex *vLower;
  1549.                GLfixed fsx = eLeft->fsx;
  1550.                fx = (((fsx) + 0x00000800 - 1) & (~0x000007FF));
  1551.                fError = fx - fsx - 0x00000800;
  1552.                fxLeftEdge = fsx - 1;
  1553.                fdxLeftEdge = eLeft->fdxdy;
  1554.                fdxOuter = ((fdxLeftEdge - 1) & (~0x000007FF));
  1555.                fdError = fdxOuter - fdxLeftEdge + 0x00000800;
  1556.                idxOuter = ((fdxOuter) >> 11);
  1557.                dxOuter = (float) idxOuter;
  1558.                (void) dxOuter;
  1559.  
  1560.                fy = eLeft->fsy;
  1561.                span.y = ((fy) >> 11);
  1562.  
  1563.                adjx = (float)(fx - eLeft->fx0);  /* SCALED! */
  1564.                adjy = eLeft->adjy;              /* SCALED! */
  1565.                vLower = eLeft->v0;
  1566.  
  1567.                /*
  1568.                 * Now we need the set of parameter (z, color, etc.) values at
  1569.                 * the point (fx, fy).  This gives us properly-sampled parameter
  1570.                 * values that we can step from pixel to pixel.  Furthermore,
  1571.                 * although we might have intermediate results that overflow
  1572.                 * the normal parameter range when we step temporarily outside
  1573.                 * the triangle, we shouldn't overflow or underflow for any
  1574.                 * pixel that's actually inside the triangle.
  1575.                 */
  1576.  
  1577.                {
  1578.                   GLfloat z0 = vLower->win[2];
  1579.                   if (depthBits <= 16) {
  1580.                      /* interpolate fixed-pt values */
  1581.                      GLfloat tmp = (z0 * FIXED_SCALE  +
  1582.                                     dzdx * adjx + dzdy * adjy) +  FIXED_HALF;
  1583.                      if (tmp < MAX_GLUINT / 2)
  1584.                         fz = (GLfixed) tmp;
  1585.                      else
  1586.                         fz = MAX_GLUINT / 2;
  1587.                      fdzOuter = SignedFloatToFixed(dzdy + dxOuter * dzdx);
  1588.                   }
  1589.                   else {
  1590.                      /* interpolate depth values exactly */
  1591.                      fz = (GLint) (z0 + dzdx * FixedToFloat(adjx)
  1592.                                    + dzdy * FixedToFloat(adjy));
  1593.                      fdzOuter = (GLint) (dzdy + dxOuter * dzdx);
  1594.                   }
  1595.  
  1596.                   zRow = (DEFAULT_SOFTWARE_DEPTH_TYPE *)
  1597.                     _mesa_zbuffer_address(ctx, FixedToInt(fxLeftEdge), span.y);
  1598.                   dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEFAULT_SOFTWARE_DEPTH_TYPE);
  1599.                }
  1600.                fogLeft = vLower->fog + (span.fogStep * adjx + dfogdy * adjy)
  1601.                                        * (1.0F/2048.0f);
  1602.                dfogOuter = dfogdy + dxOuter * span.fogStep;
  1603.  
  1604.             } /*if setupLeft*/
  1605.  
  1606.  
  1607.             if (setupRight && eRight->lines>0) {
  1608.                fxRightEdge = eRight->fsx - 1;
  1609.                fdxRightEdge = eRight->fdxdy;
  1610.             }
  1611.  
  1612.             if (lines==0) {
  1613.                continue;
  1614.             }
  1615.  
  1616.  
  1617.             /* Rasterize setup */
  1618.             dZRowInner = dZRowOuter + sizeof(GLushort);
  1619.             fdzInner = fdzOuter + span.zStep;
  1620.             dfogInner = dfogOuter + span.fogStep;
  1621.  
  1622.             while (lines > 0) {
  1623.                /* initialize the span interpolants to the leftmost value */
  1624.                /* ff = fixed-pt fragment */
  1625.                const GLint right = ((fxRightEdge) >> 11);
  1626.  
  1627.                span.x = ((fxLeftEdge) >> 11);
  1628.  
  1629.                if (right <= span.x)
  1630.                   span.end = 0;
  1631.                else
  1632.                   span.end = right - span.x;
  1633.  
  1634.                span.z = fz;
  1635.                span.fog = fogLeft;
  1636.  
  1637.  
  1638.  
  1639.  
  1640.                /* This is where we actually generate fragments */
  1641.                if (span.end > 0) {
  1642.                   _mesa_write_rgba_span(ctx, &span);;
  1643.                }
  1644.  
  1645.                /*
  1646.                 * Advance to the next scan line.  Compute the
  1647.                 * new edge coordinates, and adjust the
  1648.                 * pixel-center x coordinate so that it stays
  1649.                 * on or inside the major edge.
  1650.                 */
  1651.                (span.y)++;
  1652.                lines--;
  1653.  
  1654.                fxLeftEdge += fdxLeftEdge;
  1655.                fxRightEdge += fdxRightEdge;
  1656.  
  1657.  
  1658.                fError += fdError;
  1659.                if (fError >= 0) {
  1660.                   fError -= 0x00000800;
  1661.                   zRow = (GLushort *) ((GLubyte *) zRow + dZRowOuter);
  1662.                   fz += fdzOuter;
  1663.                   fogLeft += dfogOuter;
  1664.                }
  1665.                else {
  1666.                   zRow = (GLushort *) ((GLubyte *) zRow + dZRowInner);
  1667.                   fz += fdzInner;
  1668.                   fogLeft += dfogInner;
  1669.                }
  1670.             } /*while lines>0*/
  1671.  
  1672.          } /* for subTriangle */
  1673.  
  1674.       }
  1675.    }
  1676. }
  1677.  
  1678. /*
  1679.  * Render a smooth-shaded RGBA triangle.
  1680.  */
  1681.  
  1682. /*
  1683.  * Triangle Rasterizer Template
  1684.  *
  1685.  * This file is #include'd to generate custom triangle rasterizers.
  1686.  *
  1687.  * The following macros may be defined to indicate what auxillary information
  1688.  * must be interplated across the triangle:
  1689.  *    INTERP_Z        - if defined, interpolate Z values
  1690.  *    INTERP_FOG      - if defined, interpolate fog values
  1691.  *    INTERP_RGB      - if defined, interpolate RGB values
  1692.  *    INTERP_ALPHA    - if defined, interpolate Alpha values (req's INTERP_RGB)
  1693.  *    INTERP_SPEC     - if defined, interpolate specular RGB values
  1694.  *    INTERP_INDEX    - if defined, interpolate color index values
  1695.  *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
  1696.  *                         (fast, simple 2-D texture mapping)
  1697.  *    INTERP_TEX      - if defined, interpolate set 0 float STRQ texcoords
  1698.  *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
  1699.  *    INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
  1700.  *    INTERP_FLOAT_RGBA - if defined, interpolate RGBA with floating point
  1701.  *    INTERP_FLOAT_SPEC - if defined, interpolate specular with floating point
  1702.  *
  1703.  * When one can directly address pixels in the color buffer the following
  1704.  * macros can be defined and used to compute pixel addresses during
  1705.  * rasterization (see pRow):
  1706.  *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
  1707.  *    BYTES_PER_ROW       - number of bytes per row in the color buffer
  1708.  *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
  1709.  *                          Y==0 at bottom of screen and increases upward.
  1710.  *
  1711.  * Similarly, for direct depth buffer access, this type is used for depth
  1712.  * buffer addressing:
  1713.  *    DEPTH_TYPE          - either GLushort or GLuint
  1714.  *
  1715.  * Optionally, one may provide one-time setup code per triangle:
  1716.  *    SETUP_CODE    - code which is to be executed once per triangle
  1717.  *    CLEANUP_CODE    - code to execute at end of triangle
  1718.  *
  1719.  * The following macro MUST be defined:
  1720.  *    RENDER_SPAN(span) - code to write a span of pixels.
  1721.  *
  1722.  * This code was designed for the origin to be in the lower-left corner.
  1723.  *
  1724.  * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
  1725.  */
  1726.  
  1727.  
  1728. /*
  1729.  * This is a bit of a hack, but it's a centralized place to enable floating-
  1730.  * point color interpolation when GLchan is actually floating point.
  1731.  */
  1732.  
  1733.  
  1734.  
  1735. static void smooth_rgba_triangle(GLcontext *ctx, const SWvertex *v0,
  1736.                                  const SWvertex *v1,
  1737.                                  const SWvertex *v2 )
  1738. {
  1739.    typedef struct {
  1740.         const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
  1741.         GLfloat dx;    /* X(v1) - X(v0) */
  1742.         GLfloat dy;    /* Y(v1) - Y(v0) */
  1743.         GLfixed fdxdy; /* dx/dy in fixed-point */
  1744.         GLfixed fsx;   /* first sample point x coord */
  1745.         GLfixed fsy;
  1746.         GLfloat adjy;  /* adjust from v[0]->fy to fsy, scaled */
  1747.         GLint lines;   /* number of lines to be sampled on this edge */
  1748.         GLfixed fx0;   /* fixed pt X of lower endpoint */
  1749.    } EdgeT;
  1750.  
  1751.    const GLint depthBits = ctx->Visual.depthBits;
  1752.    const GLfloat maxDepth = ctx->DepthMaxF;
  1753.    EdgeT eMaj, eTop, eBot;
  1754.    GLfloat oneOverArea;
  1755.    const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
  1756.    float bf = ((SWcontext *)ctx->swrast_context)->_backface_sign;
  1757.    const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */
  1758.  
  1759.    GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
  1760.  
  1761.    struct sw_span span;
  1762.  
  1763.     (span).primitive = (0x0009);
  1764.     (span).interpMask = (0);
  1765.     (span).arrayMask = (0);
  1766.     (span).start = 0;
  1767.     (span).end = (0);
  1768.     (span).facing = 0;
  1769.     (span).array = ((SWcontext *)ctx->swrast_context)->SpanArrays;
  1770.  
  1771.  
  1772.    /*
  1773.    printf("%s()\n", __FUNCTION__);
  1774.    printf("  %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
  1775.    printf("  %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
  1776.    printf("  %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
  1777.     */
  1778.  
  1779.    /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
  1780.     * And find the order of the 3 vertices along the Y axis.
  1781.     */
  1782.    {
  1783.       const GLfixed fy0 = FloatToFixed(v0->win[1] - 0.5F) & snapMask;
  1784.       const GLfixed fy1 = FloatToFixed(v1->win[1] - 0.5F) & snapMask;
  1785.       const GLfixed fy2 = FloatToFixed(v2->win[1] - 0.5F) & snapMask;
  1786.  
  1787.       if (fy0 <= fy1) {
  1788.          if (fy1 <= fy2) {
  1789.             /* y0 <= y1 <= y2 */
  1790.             vMin = v0;   vMid = v1;   vMax = v2;
  1791.             vMin_fy = fy0;  vMid_fy = fy1;  vMax_fy = fy2;
  1792.          }
  1793.          else if (fy2 <= fy0) {
  1794.             /* y2 <= y0 <= y1 */
  1795.             vMin = v2;   vMid = v0;   vMax = v1;
  1796.             vMin_fy = fy2;  vMid_fy = fy0;  vMax_fy = fy1;
  1797.          }
  1798.          else {
  1799.             /* y0 <= y2 <= y1 */
  1800.             vMin = v0;   vMid = v2;   vMax = v1;
  1801.             vMin_fy = fy0;  vMid_fy = fy2;  vMax_fy = fy1;
  1802.             bf = -bf;
  1803.          }
  1804.       }
  1805.       else {
  1806.          if (fy0 <= fy2) {
  1807.             /* y1 <= y0 <= y2 */
  1808.             vMin = v1;   vMid = v0;   vMax = v2;
  1809.             vMin_fy = fy1;  vMid_fy = fy0;  vMax_fy = fy2;
  1810.             bf = -bf;
  1811.          }
  1812.          else if (fy2 <= fy1) {
  1813.             /* y2 <= y1 <= y0 */
  1814.             vMin = v2;   vMid = v1;   vMax = v0;
  1815.             vMin_fy = fy2;  vMid_fy = fy1;  vMax_fy = fy0;
  1816.             bf = -bf;
  1817.          }
  1818.          else {
  1819.             /* y1 <= y2 <= y0 */
  1820.             vMin = v1;   vMid = v2;   vMax = v0;
  1821.             vMin_fy = fy1;  vMid_fy = fy2;  vMax_fy = fy0;
  1822.          }
  1823.       }
  1824.  
  1825.       /* fixed point X coords */
  1826.       vMin_fx = FloatToFixed(vMin->win[0] + 0.5F) & snapMask;
  1827.       vMid_fx = FloatToFixed(vMid->win[0] + 0.5F) & snapMask;
  1828.       vMax_fx = FloatToFixed(vMax->win[0] + 0.5F) & snapMask;
  1829.    }
  1830.  
  1831.  
  1832.    /* vertex/edge relationship */
  1833.    eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
  1834.    eTop.v0 = vMid;   eTop.v1 = vMax;
  1835.    eBot.v0 = vMin;   eBot.v1 = vMid;
  1836.  
  1837.    /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
  1838.    eMaj.dx = FixedToFloat(vMax_fx - vMin_fx);
  1839.    eMaj.dy = FixedToFloat(vMax_fy - vMin_fy);
  1840.    eTop.dx = FixedToFloat(vMax_fx - vMid_fx);
  1841.    eTop.dy = FixedToFloat(vMax_fy - vMid_fy);
  1842.    eBot.dx = FixedToFloat(vMid_fx - vMin_fx);
  1843.    eBot.dy = FixedToFloat(vMid_fy - vMin_fy);
  1844.  
  1845.    /* compute area, oneOverArea and perform backface culling */
  1846.    {
  1847.       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
  1848.  
  1849.       /* Do backface culling */
  1850.       if (area * bf < 0.0)
  1851.          return;
  1852.  
  1853.       if (IS_INF_OR_NAN(area) || area == 0.0F)
  1854.          return;
  1855.  
  1856.       oneOverArea = 1.0F / area;
  1857.    }
  1858.  
  1859.    ctx->OcclusionResult = 0x1;
  1860.    span.facing = ctx->_Facing; /* for 2-sided stencil test */
  1861.  
  1862.    /* Edge setup.  For a triangle strip these could be reused... */
  1863.    {
  1864.       eMaj.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  1865.       eMaj.lines = (((((vMax_fy - eMaj.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  1866.       if (eMaj.lines > 0) {
  1867.          GLfloat dxdy = eMaj.dx / eMaj.dy;
  1868.          eMaj.fdxdy = SignedFloatToFixed(dxdy);
  1869.          eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
  1870.          eMaj.fx0 = vMin_fx;
  1871.          eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy);
  1872.       }
  1873.       else {
  1874.          return;  /*CULLED*/
  1875.       }
  1876.  
  1877.       eTop.fsy = (((vMid_fy) + 0x00000800 - 1) & (~0x000007FF));
  1878.       eTop.lines = (((((vMax_fy - eTop.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  1879.       if (eTop.lines > 0) {
  1880.          GLfloat dxdy = eTop.dx / eTop.dy;
  1881.          eTop.fdxdy = SignedFloatToFixed(dxdy);
  1882.          eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
  1883.          eTop.fx0 = vMid_fx;
  1884.          eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy);
  1885.       }
  1886.  
  1887.       eBot.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  1888.       eBot.lines = (((((vMid_fy - eBot.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  1889.       if (eBot.lines > 0) {
  1890.          GLfloat dxdy = eBot.dx / eBot.dy;
  1891.          eBot.fdxdy = SignedFloatToFixed(dxdy);
  1892.          eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
  1893.          eBot.fx0 = vMin_fx;
  1894.          eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy);
  1895.       }
  1896.    }
  1897.  
  1898.    /*
  1899.     * Conceptually, we view a triangle as two subtriangles
  1900.     * separated by a perfectly horizontal line.  The edge that is
  1901.     * intersected by this line is one with maximal absolute dy; we
  1902.     * call it a ``major'' edge.  The other two edges are the
  1903.     * ``top'' edge (for the upper subtriangle) and the ``bottom''
  1904.     * edge (for the lower subtriangle).  If either of these two
  1905.     * edges is horizontal or very close to horizontal, the
  1906.     * corresponding subtriangle might cover zero sample points;
  1907.     * we take care to handle such cases, for performance as well
  1908.     * as correctness.
  1909.     *
  1910.     * By stepping rasterization parameters along the major edge,
  1911.     * we can avoid recomputing them at the discontinuity where
  1912.     * the top and bottom edges meet.  However, this forces us to
  1913.     * be able to scan both left-to-right and right-to-left.
  1914.     * Also, we must determine whether the major edge is at the
  1915.     * left or right side of the triangle.  We do this by
  1916.     * computing the magnitude of the cross-product of the major
  1917.     * and top edges.  Since this magnitude depends on the sine of
  1918.     * the angle between the two edges, its sign tells us whether
  1919.     * we turn to the left or to the right when travelling along
  1920.     * the major edge to the top edge, and from this we infer
  1921.     * whether the major edge is on the left or the right.
  1922.     *
  1923.     * Serendipitously, this cross-product magnitude is also a
  1924.     * value we need to compute the iteration parameter
  1925.     * derivatives for the triangle, and it can be used to perform
  1926.     * backface culling because its sign tells us whether the
  1927.     * triangle is clockwise or counterclockwise.  In this code we
  1928.     * refer to it as ``area'' because it's also proportional to
  1929.     * the pixel area of the triangle.
  1930.     */
  1931.  
  1932.    {
  1933.       GLint scan_from_left_to_right;  /* true if scanning left-to-right */
  1934.       GLfloat dzdx, dzdy;
  1935.       GLfloat dfogdy;
  1936.       GLfloat drdx, drdy;
  1937.       GLfloat dgdx, dgdy;
  1938.       GLfloat dbdx, dbdy;
  1939.       GLfloat dadx, dady;
  1940.  
  1941.       /*
  1942.        * Execute user-supplied setup code
  1943.        */
  1944. /* ..... */
  1945.       scan_from_left_to_right = (oneOverArea < 0.0F);
  1946.  
  1947.  
  1948.       /* compute d?/dx and d?/dy derivatives */
  1949.       span.interpMask |= SPAN_Z;
  1950.       {
  1951.          GLfloat eMaj_dz, eBot_dz;
  1952.          eMaj_dz = vMax->win[2] - vMin->win[2];
  1953.          eBot_dz = vMid->win[2] - vMin->win[2];
  1954.          dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
  1955.          if (dzdx > maxDepth || dzdx < -maxDepth) {
  1956.             /* probably a sliver triangle */
  1957.             dzdx = 0.0;
  1958.             dzdy = 0.0;
  1959.          }
  1960.          else {
  1961.             dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
  1962.          }
  1963.          if (depthBits <= 16)
  1964.             span.zStep = SignedFloatToFixed(dzdx);
  1965.          else
  1966.             span.zStep = (GLint) dzdx;
  1967.       }
  1968.       span.interpMask |= SPAN_FOG;
  1969.       {
  1970.          const GLfloat eMaj_dfog = vMax->fog - vMin->fog;
  1971.          const GLfloat eBot_dfog = vMid->fog - vMin->fog;
  1972.          span.fogStep = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
  1973.          dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
  1974.       }
  1975.       span.interpMask |= SPAN_RGBA;
  1976.       if (ctx->Light.ShadeModel == GL_SMOOTH) {
  1977.          GLfloat eMaj_dr, eBot_dr;
  1978.          GLfloat eMaj_dg, eBot_dg;
  1979.          GLfloat eMaj_db, eBot_db;
  1980.          GLfloat eMaj_da, eBot_da;
  1981.          eMaj_dr = (GLfloat) ((GLint) vMax->color[RCOMP] -
  1982.                              (GLint) vMin->color[RCOMP]);
  1983.          eBot_dr = (GLfloat) ((GLint) vMid->color[RCOMP] -
  1984.                              (GLint) vMin->color[RCOMP]);
  1985.          drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
  1986.          span.redStep = SignedFloatToFixed(drdx);
  1987.          drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
  1988.          eMaj_dg = (GLfloat) ((GLint) vMax->color[GCOMP] -
  1989.                              (GLint) vMin->color[GCOMP]);
  1990.          eBot_dg = (GLfloat) ((GLint) vMid->color[GCOMP] -
  1991.                              (GLint) vMin->color[GCOMP]);
  1992.          dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
  1993.          span.greenStep = SignedFloatToFixed(dgdx);
  1994.          dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
  1995.          eMaj_db = (GLfloat) ((GLint) vMax->color[BCOMP] -
  1996.                              (GLint) vMin->color[BCOMP]);
  1997.          eBot_db = (GLfloat) ((GLint) vMid->color[BCOMP] -
  1998.                              (GLint) vMin->color[BCOMP]);
  1999.          dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
  2000.          span.blueStep = SignedFloatToFixed(dbdx);
  2001.          dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
  2002.          eMaj_da = (GLfloat) ((GLint) vMax->color[ACOMP] -
  2003.                              (GLint) vMin->color[ACOMP]);
  2004.          eBot_da = (GLfloat) ((GLint) vMid->color[ACOMP] -
  2005.                              (GLint) vMin->color[ACOMP]);
  2006.          dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
  2007.          span.alphaStep = SignedFloatToFixed(dadx);
  2008.          dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
  2009.       }
  2010.       else {
  2011.          span.interpMask |= SPAN_FLAT;
  2012.          drdx = drdy = 0.0F;
  2013.          dgdx = dgdy = 0.0F;
  2014.          dbdx = dbdy = 0.0F;
  2015.          span.redStep = 0;
  2016.          span.greenStep = 0;
  2017.          span.blueStep = 0;
  2018.          dadx = dady = 0.0F;
  2019.          span.alphaStep = 0;
  2020.       }
  2021.  
  2022.       /*
  2023.        * We always sample at pixel centers.  However, we avoid
  2024.        * explicit half-pixel offsets in this code by incorporating
  2025.        * the proper offset in each of x and y during the
  2026.        * transformation to window coordinates.
  2027.        *
  2028.        * We also apply the usual rasterization rules to prevent
  2029.        * cracks and overlaps.  A pixel is considered inside a
  2030.        * subtriangle if it meets all of four conditions: it is on or
  2031.        * to the right of the left edge, strictly to the left of the
  2032.        * right edge, on or below the top edge, and strictly above
  2033.        * the bottom edge.  (Some edges may be degenerate.)
  2034.        *
  2035.        * The following discussion assumes left-to-right scanning
  2036.        * (that is, the major edge is on the left); the right-to-left
  2037.        * case is a straightforward variation.
  2038.        *
  2039.        * We start by finding the half-integral y coordinate that is
  2040.        * at or below the top of the triangle.  This gives us the
  2041.        * first scan line that could possibly contain pixels that are
  2042.        * inside the triangle.
  2043.        *
  2044.        * Next we creep down the major edge until we reach that y,
  2045.        * and compute the corresponding x coordinate on the edge.
  2046.        * Then we find the half-integral x that lies on or just
  2047.        * inside the edge.  This is the first pixel that might lie in
  2048.        * the interior of the triangle.  (We won't know for sure
  2049.        * until we check the other edges.)
  2050.        *
  2051.        * As we rasterize the triangle, we'll step down the major
  2052.        * edge.  For each step in y, we'll move an integer number
  2053.        * of steps in x.  There are two possible x step sizes, which
  2054.        * we'll call the ``inner'' step (guaranteed to land on the
  2055.        * edge or inside it) and the ``outer'' step (guaranteed to
  2056.        * land on the edge or outside it).  The inner and outer steps
  2057.        * differ by one.  During rasterization we maintain an error
  2058.        * term that indicates our distance from the true edge, and
  2059.        * select either the inner step or the outer step, whichever
  2060.        * gets us to the first pixel that falls inside the triangle.
  2061.        *
  2062.        * All parameters (z, red, etc.) as well as the buffer
  2063.        * addresses for color and z have inner and outer step values,
  2064.        * so that we can increment them appropriately.  This method
  2065.        * eliminates the need to adjust parameters by creeping a
  2066.        * sub-pixel amount into the triangle at each scanline.
  2067.        */
  2068.  
  2069.       {
  2070.          int subTriangle;
  2071.          GLfixed fx;
  2072.          GLfixed fxLeftEdge = 0, fxRightEdge = 0;
  2073.          GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
  2074.          GLfixed fdxOuter;
  2075.          int idxOuter;
  2076.          float dxOuter;
  2077.          GLfixed fError = 0, fdError = 0;
  2078.          float adjx, adjy;
  2079.          GLfixed fy;
  2080.          GLushort *zRow = 0;
  2081.          int dZRowOuter = 0, dZRowInner;  /* offset in bytes */
  2082.          GLfixed fz = 0, fdzOuter = 0, fdzInner;
  2083.          GLfloat fogLeft = 0, dfogOuter = 0, dfogInner;
  2084.          GLfixed fr = 0, fdrOuter = 0, fdrInner;
  2085.          GLfixed fg = 0, fdgOuter = 0, fdgInner;
  2086.          GLfixed fb = 0, fdbOuter = 0, fdbInner;
  2087.          GLfixed fa = 0, fdaOuter = 0, fdaInner;
  2088.  
  2089.          for (subTriangle=0; subTriangle<=1; subTriangle++) {
  2090.             EdgeT *eLeft, *eRight;
  2091.             int setupLeft, setupRight;
  2092.             int lines;
  2093.  
  2094.             if (subTriangle==0) {
  2095.                /* bottom half */
  2096.                if (scan_from_left_to_right) {
  2097.                   eLeft = &eMaj;
  2098.                   eRight = &eBot;
  2099.                   lines = eRight->lines;
  2100.                   setupLeft = 1;
  2101.                   setupRight = 1;
  2102.                }
  2103.                else {
  2104.                   eLeft = &eBot;
  2105.                   eRight = &eMaj;
  2106.                   lines = eLeft->lines;
  2107.                   setupLeft = 1;
  2108.                   setupRight = 1;
  2109.                }
  2110.             }
  2111.             else {
  2112.                /* top half */
  2113.                if (scan_from_left_to_right) {
  2114.                   eLeft = &eMaj;
  2115.                   eRight = &eTop;
  2116.                   lines = eRight->lines;
  2117.                   setupLeft = 0;
  2118.                   setupRight = 1;
  2119.                }
  2120.                else {
  2121.                   eLeft = &eTop;
  2122.                   eRight = &eMaj;
  2123.                   lines = eLeft->lines;
  2124.                   setupLeft = 1;
  2125.                   setupRight = 0;
  2126.                }
  2127.                if (lines == 0)
  2128.                   return;
  2129.             }
  2130.  
  2131.             if (setupLeft && eLeft->lines > 0) {
  2132.                const SWvertex *vLower;
  2133.                GLfixed fsx = eLeft->fsx;
  2134.                fx = (((fsx) + 0x00000800 - 1) & (~0x000007FF));
  2135.                fError = fx - fsx - 0x00000800;
  2136.                fxLeftEdge = fsx - 1;
  2137.                fdxLeftEdge = eLeft->fdxdy;
  2138.                fdxOuter = ((fdxLeftEdge - 1) & (~0x000007FF));
  2139.                fdError = fdxOuter - fdxLeftEdge + 0x00000800;
  2140.                idxOuter = ((fdxOuter) >> 11);
  2141.                dxOuter = (float) idxOuter;
  2142.                (void) dxOuter;
  2143.  
  2144.                fy = eLeft->fsy;
  2145.                span.y = ((fy) >> 11);
  2146.  
  2147.                adjx = (float)(fx - eLeft->fx0);  /* SCALED! */
  2148.                adjy = eLeft->adjy;              /* SCALED! */
  2149.                vLower = eLeft->v0;
  2150.  
  2151.                /*
  2152.                 * Now we need the set of parameter (z, color, etc.) values at
  2153.                 * the point (fx, fy).  This gives us properly-sampled parameter
  2154.                 * values that we can step from pixel to pixel.  Furthermore,
  2155.                 * although we might have intermediate results that overflow
  2156.                 * the normal parameter range when we step temporarily outside
  2157.                 * the triangle, we shouldn't overflow or underflow for any
  2158.                 * pixel that's actually inside the triangle.
  2159.                 */
  2160.  
  2161.                {
  2162.                   GLfloat z0 = vLower->win[2];
  2163.                   if (depthBits <= 16) {
  2164.                      /* interpolate fixed-pt values */
  2165.                      GLfloat tmp = (z0 * 2048.0f +
  2166.                                     dzdx * adjx + dzdy * adjy) + 0x00000400;
  2167.                      if (tmp < MAX_GLUINT / 2)
  2168.                         fz = (GLfixed) tmp;
  2169.                      else
  2170.                         fz = MAX_GLUINT / 2;
  2171.                      fdzOuter = SignedFloatToFixed(dzdy + dxOuter * dzdx);
  2172.                   }
  2173.                   else {
  2174.                      /* interpolate depth values exactly */
  2175.                      fz = (GLint) (z0 + dzdx * FixedToFloat(adjx)
  2176.                                    + dzdy * FixedToFloat(adjy));
  2177.                      fdzOuter = (GLint) (dzdy + dxOuter * dzdx);
  2178.                   }
  2179.                   zRow = (GLushort *)
  2180.                     _mesa_zbuffer_address(ctx, ((fxLeftEdge) >> 11), span.y);
  2181.                   dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(GLushort);
  2182.                }
  2183.                fogLeft = vLower->fog + (span.fogStep * adjx + dfogdy * adjy)
  2184.                                        * (1.0F/2048.0f);
  2185.                dfogOuter = dfogdy + dxOuter * span.fogStep;
  2186.                if (ctx->Light.ShadeModel == GL_SMOOTH) {
  2187.                   fr = (GLfixed) (ChanToFixed(vLower->color[RCOMP])
  2188.                                    + drdx * adjx + drdy * adjy) + FIXED_HALF;
  2189.                   fdrOuter = SignedFloatToFixed(drdy + dxOuter * drdx);
  2190.                   fg = (GLfixed) (ChanToFixed(vLower->color[GCOMP])
  2191.                                    + dgdx * adjx + dgdy * adjy) + FIXED_HALF;
  2192.                   fdgOuter = SignedFloatToFixed(dgdy + dxOuter * dgdx);
  2193.                   fb = (GLfixed) (ChanToFixed(vLower->color[BCOMP])
  2194.                                     + dbdx * adjx + dbdy * adjy) + FIXED_HALF;
  2195.                   fdbOuter = SignedFloatToFixed(dbdy + dxOuter * dbdx);
  2196.                   fa = (GLfixed) (ChanToFixed(vLower->color[ACOMP])
  2197.                                    + dadx * adjx + dady * adjy) + FIXED_HALF;
  2198.                   fdaOuter = SignedFloatToFixed(dady + dxOuter * dadx);
  2199.                }
  2200.                else {
  2201.                   fr = ChanToFixed(v2->color[RCOMP]);
  2202.                   fg = ChanToFixed(v2->color[GCOMP]);
  2203.                   fdrOuter = fdgOuter = fdbOuter = 0;
  2204.                   fa =  ChanToFixed(v2->color[ACOMP]);
  2205.                   fdaOuter = 0;
  2206.                }
  2207.  
  2208.             } /*if setupLeft*/
  2209.  
  2210.  
  2211.             if (setupRight && eRight->lines>0) {
  2212.                fxRightEdge = eRight->fsx - 1;
  2213.                fdxRightEdge = eRight->fdxdy;
  2214.             }
  2215.  
  2216.             if (lines==0) {
  2217.                continue;
  2218.             }
  2219.  
  2220.  
  2221.             /* Rasterize setup */
  2222.             dZRowInner = dZRowOuter + sizeof(GLushort);
  2223.             fdzInner = fdzOuter + span.zStep;
  2224.             dfogInner = dfogOuter + span.fogStep;
  2225.             fdrInner = fdrOuter + span.redStep;
  2226.             fdgInner = fdgOuter + span.greenStep;
  2227.             fdbInner = fdbOuter + span.blueStep;
  2228.             fdaInner = fdaOuter + span.alphaStep;
  2229.  
  2230.             while (lines > 0) {
  2231.                /* initialize the span interpolants to the leftmost value */
  2232.                /* ff = fixed-pt fragment */
  2233.                const GLint right = ((fxRightEdge) >> 11);
  2234.  
  2235.                span.x = ((fxLeftEdge) >> 11);
  2236.  
  2237.                if (right <= span.x)
  2238.                   span.end = 0;
  2239.                else
  2240.                   span.end = right - span.x;
  2241.  
  2242.                span.z = fz;
  2243.                span.fog = fogLeft;
  2244.                span.red = fr;
  2245.                span.green = fg;
  2246.                span.blue = fb;
  2247.                span.alpha = fa;
  2248.  
  2249.  
  2250.                {
  2251.                   /* need this to accomodate round-off errors */
  2252.                   const GLint len = right - span.x - 1;
  2253.                   GLfixed ffrend = span.red + len * span.redStep;
  2254.                   GLfixed ffgend = span.green + len * span.greenStep;
  2255.                   GLfixed ffbend = span.blue + len * span.blueStep;
  2256.                   if (ffrend < 0) {
  2257.                      span.red -= ffrend;
  2258.                      if (span.red < 0)
  2259.                         span.red = 0;
  2260.                   }
  2261.                   if (ffgend < 0) {
  2262.                      span.green -= ffgend;
  2263.                      if (span.green < 0)
  2264.                         span.green = 0;
  2265.                   }
  2266.                   if (ffbend < 0) {
  2267.                      span.blue -= ffbend;
  2268.                      if (span.blue < 0)
  2269.                         span.blue = 0;
  2270.                   }
  2271.                }
  2272.                {
  2273.                   const GLint len = right - span.x - 1;
  2274.                   GLfixed ffaend = span.alpha + len * span.alphaStep;
  2275.                   if (ffaend < 0) {
  2276.                      span.alpha -= ffaend;
  2277.                      if (span.alpha < 0)
  2278.                         span.alpha = 0;
  2279.                   }
  2280.                }
  2281.  
  2282.                /* This is where we actually generate fragments */
  2283.                if (span.end > 0) {
  2284.                   _mesa_write_rgba_span(ctx, &span);
  2285.                }
  2286.  
  2287.                /*
  2288.                 * Advance to the next scan line.  Compute the
  2289.                 * new edge coordinates, and adjust the
  2290.                 * pixel-center x coordinate so that it stays
  2291.                 * on or inside the major edge.
  2292.                 */
  2293.                (span.y)++;
  2294.                lines--;
  2295.  
  2296.                fxLeftEdge += fdxLeftEdge;
  2297.                fxRightEdge += fdxRightEdge;
  2298.  
  2299.  
  2300.                fError += fdError;
  2301.                if (fError >= 0) {
  2302.                   fError -= 0x00000800;
  2303.                   zRow = (GLushort *) ((GLubyte *) zRow + dZRowOuter);
  2304.                   fz += fdzOuter;
  2305.                   fogLeft += dfogOuter;
  2306.                   fr += fdrOuter;
  2307.                   fg += fdgOuter;
  2308.                   fb += fdbOuter;
  2309.                   fa += fdaOuter;
  2310.                }
  2311.                else {
  2312.                   zRow = (GLushort *) ((GLubyte *) zRow + dZRowInner);
  2313.                   fz += fdzInner;
  2314.                   fogLeft += dfogInner;
  2315.                   fr += fdrInner;
  2316.                   fg += fdgInner;
  2317.                   fb += fdbInner;
  2318.                   fa += fdaInner;
  2319.                }
  2320.             } /*while lines>0*/
  2321.  
  2322.          } /* for subTriangle */
  2323.  
  2324.       }
  2325.    }
  2326. }
  2327.  
  2328. /*
  2329.  * Render an RGB, GL_DECAL, textured triangle.
  2330.  * Interpolate S,T only w/out mipmapping or perspective correction.
  2331.  *
  2332.  * No fog.
  2333.  */
  2334.  
  2335. /*
  2336.  * Triangle Rasterizer Template
  2337.  *
  2338.  * This file is #include'd to generate custom triangle rasterizers.
  2339.  *
  2340.  * The following macros may be defined to indicate what auxillary information
  2341.  * must be interplated across the triangle:
  2342.  *    INTERP_Z        - if defined, interpolate Z values
  2343.  *    INTERP_FOG      - if defined, interpolate fog values
  2344.  *    INTERP_RGB      - if defined, interpolate RGB values
  2345.  *    INTERP_ALPHA    - if defined, interpolate Alpha values (req's INTERP_RGB)
  2346.  *    INTERP_SPEC     - if defined, interpolate specular RGB values
  2347.  *    INTERP_INDEX    - if defined, interpolate color index values
  2348.  *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
  2349.  *                         (fast, simple 2-D texture mapping)
  2350.  *    INTERP_TEX      - if defined, interpolate set 0 float STRQ texcoords
  2351.  *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
  2352.  *    INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
  2353.  *    INTERP_FLOAT_RGBA - if defined, interpolate RGBA with floating point
  2354.  *    INTERP_FLOAT_SPEC - if defined, interpolate specular with floating point
  2355.  *
  2356.  * When one can directly address pixels in the color buffer the following
  2357.  * macros can be defined and used to compute pixel addresses during
  2358.  * rasterization (see pRow):
  2359.  *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
  2360.  *    BYTES_PER_ROW       - number of bytes per row in the color buffer
  2361.  *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
  2362.  *                          Y==0 at bottom of screen and increases upward.
  2363.  *
  2364.  * Similarly, for direct depth buffer access, this type is used for depth
  2365.  * buffer addressing:
  2366.  *    DEPTH_TYPE          - either GLushort or GLuint
  2367.  *
  2368.  * Optionally, one may provide one-time setup code per triangle:
  2369.  *    SETUP_CODE    - code which is to be executed once per triangle
  2370.  *    CLEANUP_CODE    - code to execute at end of triangle
  2371.  *
  2372.  * The following macro MUST be defined:
  2373.  *    RENDER_SPAN(span) - code to write a span of pixels.
  2374.  *
  2375.  * This code was designed for the origin to be in the lower-left corner.
  2376.  *
  2377.  * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
  2378.  */
  2379.  
  2380.  
  2381. /*
  2382.  * This is a bit of a hack, but it's a centralized place to enable floating-
  2383.  * point color interpolation when GLchan is actually floating point.
  2384.  */
  2385.  
  2386.  
  2387.  
  2388. static void simple_textured_triangle(GLcontext *ctx, const SWvertex *v0,
  2389.                                  const SWvertex *v1,
  2390.                                  const SWvertex *v2 )
  2391. {
  2392.    typedef struct {
  2393.         const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
  2394.         GLfloat dx;    /* X(v1) - X(v0) */
  2395.         GLfloat dy;    /* Y(v1) - Y(v0) */
  2396.         GLfixed fdxdy; /* dx/dy in fixed-point */
  2397.         GLfixed fsx;   /* first sample point x coord */
  2398.         GLfixed fsy;
  2399.         GLfloat adjy;  /* adjust from v[0]->fy to fsy, scaled */
  2400.         GLint lines;   /* number of lines to be sampled on this edge */
  2401.         GLfixed fx0;   /* fixed pt X of lower endpoint */
  2402.    } EdgeT;
  2403.  
  2404.    EdgeT eMaj, eTop, eBot;
  2405.    GLfloat oneOverArea;
  2406.    const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
  2407.    float bf = ((SWcontext *)ctx->swrast_context)->_backface_sign;
  2408.    const GLint snapMask = ~((0x00000800 / (1 << 4)) - 1); /* for x/y coord snapping */
  2409.    GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
  2410.  
  2411.    struct sw_span span;
  2412.  
  2413.    do { (span).primitive = (0x0009); (span).interpMask = (0); (span).arrayMask = (0); (span).start = 0; (span).end = (0); (span).facing = 0; (span).array = ((SWcontext *)ctx->swrast_context)->SpanArrays; } while (0);
  2414.  
  2415.  
  2416.    printf("%s()\n", __FUNCTION__);
  2417.    /*
  2418.    printf("  %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
  2419.    printf("  %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
  2420.    printf("  %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
  2421.     */
  2422.  
  2423.    /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
  2424.     * And find the order of the 3 vertices along the Y axis.
  2425.     */
  2426.    {
  2427.       const GLfixed fy0 = (((int) ((((v0->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v0->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v0->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  2428.       const GLfixed fy1 = (((int) ((((v1->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v1->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v1->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  2429.       const GLfixed fy2 = (((int) ((((v2->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v2->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v2->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  2430.  
  2431.       if (fy0 <= fy1) {
  2432.          if (fy1 <= fy2) {
  2433.             /* y0 <= y1 <= y2 */
  2434.             vMin = v0;   vMid = v1;   vMax = v2;
  2435.             vMin_fy = fy0;  vMid_fy = fy1;  vMax_fy = fy2;
  2436.          }
  2437.          else if (fy2 <= fy0) {
  2438.             /* y2 <= y0 <= y1 */
  2439.             vMin = v2;   vMid = v0;   vMax = v1;
  2440.             vMin_fy = fy2;  vMid_fy = fy0;  vMax_fy = fy1;
  2441.          }
  2442.          else {
  2443.             /* y0 <= y2 <= y1 */
  2444.             vMin = v0;   vMid = v2;   vMax = v1;
  2445.             vMin_fy = fy0;  vMid_fy = fy2;  vMax_fy = fy1;
  2446.             bf = -bf;
  2447.          }
  2448.       }
  2449.       else {
  2450.          if (fy0 <= fy2) {
  2451.             /* y1 <= y0 <= y2 */
  2452.             vMin = v1;   vMid = v0;   vMax = v2;
  2453.             vMin_fy = fy1;  vMid_fy = fy0;  vMax_fy = fy2;
  2454.             bf = -bf;
  2455.          }
  2456.          else if (fy2 <= fy1) {
  2457.             /* y2 <= y1 <= y0 */
  2458.             vMin = v2;   vMid = v1;   vMax = v0;
  2459.             vMin_fy = fy2;  vMid_fy = fy1;  vMax_fy = fy0;
  2460.             bf = -bf;
  2461.          }
  2462.          else {
  2463.             /* y1 <= y2 <= y0 */
  2464.             vMin = v1;   vMid = v2;   vMax = v0;
  2465.             vMin_fy = fy1;  vMid_fy = fy2;  vMax_fy = fy0;
  2466.          }
  2467.       }
  2468.  
  2469.       /* fixed point X coords */
  2470.       vMin_fx = (((int) ((((vMin->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMin->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMin->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  2471.       vMid_fx = (((int) ((((vMid->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMid->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMid->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  2472.       vMax_fx = (((int) ((((vMax->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMax->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMax->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  2473.    }
  2474.  
  2475.    /* vertex/edge relationship */
  2476.    eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
  2477.    eTop.v0 = vMid;   eTop.v1 = vMax;
  2478.    eBot.v0 = vMin;   eBot.v1 = vMid;
  2479.  
  2480.    /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
  2481.    eMaj.dx = ((vMax_fx - vMin_fx) * (1.0F / 2048.0f));
  2482.    eMaj.dy = ((vMax_fy - vMin_fy) * (1.0F / 2048.0f));
  2483.    eTop.dx = ((vMax_fx - vMid_fx) * (1.0F / 2048.0f));
  2484.    eTop.dy = ((vMax_fy - vMid_fy) * (1.0F / 2048.0f));
  2485.    eBot.dx = ((vMid_fx - vMin_fx) * (1.0F / 2048.0f));
  2486.    eBot.dy = ((vMid_fy - vMin_fy) * (1.0F / 2048.0f));
  2487.  
  2488.    /* compute area, oneOverArea and perform backface culling */
  2489.    {
  2490.       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
  2491.  
  2492.       /* Do backface culling */
  2493.       if (area * bf < 0.0)
  2494.          return;
  2495.  
  2496.       if (IS_INF_OR_NAN(area) || area == 0.0F)
  2497.          return;
  2498.  
  2499.       oneOverArea = 1.0F / area;
  2500.    }
  2501.  
  2502.    ctx->OcclusionResult = 0x1;
  2503.    span.facing = ctx->_Facing; /* for 2-sided stencil test */
  2504.  
  2505.    /* Edge setup.  For a triangle strip these could be reused... */
  2506.    {
  2507.       eMaj.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  2508.       eMaj.lines = (((((vMax_fy - eMaj.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  2509.       if (eMaj.lines > 0) {
  2510.          GLfloat dxdy = eMaj.dx / eMaj.dy;
  2511.          eMaj.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  2512.          eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
  2513.          eMaj.fx0 = vMin_fx;
  2514.          eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy);
  2515.       }
  2516.       else {
  2517.          return;  /*CULLED*/
  2518.       }
  2519.  
  2520.       eTop.fsy = (((vMid_fy) + 0x00000800 - 1) & (~0x000007FF));
  2521.       eTop.lines = (((((vMax_fy - eTop.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  2522.       if (eTop.lines > 0) {
  2523.          GLfloat dxdy = eTop.dx / eTop.dy;
  2524.          eTop.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  2525.          eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
  2526.          eTop.fx0 = vMid_fx;
  2527.          eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy);
  2528.       }
  2529.  
  2530.       eBot.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  2531.       eBot.lines = (((((vMid_fy - eBot.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  2532.       if (eBot.lines > 0) {
  2533.          GLfloat dxdy = eBot.dx / eBot.dy;
  2534.          eBot.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  2535.          eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
  2536.          eBot.fx0 = vMin_fx;
  2537.          eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy);
  2538.       }
  2539.    }
  2540.  
  2541.    /*
  2542.     * Conceptually, we view a triangle as two subtriangles
  2543.     * separated by a perfectly horizontal line.  The edge that is
  2544.     * intersected by this line is one with maximal absolute dy; we
  2545.     * call it a ``major'' edge.  The other two edges are the
  2546.     * ``top'' edge (for the upper subtriangle) and the ``bottom''
  2547.     * edge (for the lower subtriangle).  If either of these two
  2548.     * edges is horizontal or very close to horizontal, the
  2549.     * corresponding subtriangle might cover zero sample points;
  2550.     * we take care to handle such cases, for performance as well
  2551.     * as correctness.
  2552.     *
  2553.     * By stepping rasterization parameters along the major edge,
  2554.     * we can avoid recomputing them at the discontinuity where
  2555.     * the top and bottom edges meet.  However, this forces us to
  2556.     * be able to scan both left-to-right and right-to-left.
  2557.     * Also, we must determine whether the major edge is at the
  2558.     * left or right side of the triangle.  We do this by
  2559.     * computing the magnitude of the cross-product of the major
  2560.     * and top edges.  Since this magnitude depends on the sine of
  2561.     * the angle between the two edges, its sign tells us whether
  2562.     * we turn to the left or to the right when travelling along
  2563.     * the major edge to the top edge, and from this we infer
  2564.     * whether the major edge is on the left or the right.
  2565.     *
  2566.     * Serendipitously, this cross-product magnitude is also a
  2567.     * value we need to compute the iteration parameter
  2568.     * derivatives for the triangle, and it can be used to perform
  2569.     * backface culling because its sign tells us whether the
  2570.     * triangle is clockwise or counterclockwise.  In this code we
  2571.     * refer to it as ``area'' because it's also proportional to
  2572.     * the pixel area of the triangle.
  2573.     */
  2574.  
  2575.    {
  2576.       GLint scan_from_left_to_right;  /* true if scanning left-to-right */
  2577.       GLfloat dsdx, dsdy;
  2578.       GLfloat dtdx, dtdy;
  2579.  
  2580.       /*
  2581.        * Execute user-supplied setup code
  2582.        */
  2583.       SWcontext *swrast = ((SWcontext *)ctx->swrast_context); struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; const GLint b = obj->BaseLevel; const GLfloat twidth = (GLfloat) obj->Image[b]->Width; const GLfloat theight = (GLfloat) obj->Image[b]->Height; const GLint twidth_log2 = obj->Image[b]->WidthLog2; const GLchan *texture = (const GLchan *) obj->Image[b]->Data; const GLint smask = obj->Image[b]->Width - 1; const GLint tmask = obj->Image[b]->Height - 1; if (!texture) { return; }
  2584.  
  2585.       scan_from_left_to_right = (oneOverArea < 0.0F);
  2586.  
  2587.  
  2588.       /* compute d?/dx and d?/dy derivatives */
  2589.       span.interpMask |= 0x040;
  2590.       {
  2591.          GLfloat eMaj_ds, eBot_ds;
  2592.          eMaj_ds = (vMax->texcoord[0][0] - vMin->texcoord[0][0]) * twidth;
  2593.          eBot_ds = (vMid->texcoord[0][0] - vMin->texcoord[0][0]) * twidth;
  2594.          dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
  2595.          span.intTexStep[0] = (((int) ((((dsdx) * 2048.0f) >= 0.0F) ? (((dsdx) * 2048.0f) + 0.5F) : (((dsdx) * 2048.0f) - 0.5F))));
  2596.          dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
  2597.       }
  2598.       {
  2599.          GLfloat eMaj_dt, eBot_dt;
  2600.          eMaj_dt = (vMax->texcoord[0][1] - vMin->texcoord[0][1]) * theight;
  2601.          eBot_dt = (vMid->texcoord[0][1] - vMin->texcoord[0][1]) * theight;
  2602.          dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
  2603.          span.intTexStep[1] = (((int) ((((dtdx) * 2048.0f) >= 0.0F) ? (((dtdx) * 2048.0f) + 0.5F) : (((dtdx) * 2048.0f) - 0.5F))));
  2604.          dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
  2605.       }
  2606.  
  2607.  
  2608.       /*
  2609.        * We always sample at pixel centers.  However, we avoid
  2610.        * explicit half-pixel offsets in this code by incorporating
  2611.        * the proper offset in each of x and y during the
  2612.        * transformation to window coordinates.
  2613.        *
  2614.        * We also apply the usual rasterization rules to prevent
  2615.        * cracks and overlaps.  A pixel is considered inside a
  2616.        * subtriangle if it meets all of four conditions: it is on or
  2617.        * to the right of the left edge, strictly to the left of the
  2618.        * right edge, on or below the top edge, and strictly above
  2619.        * the bottom edge.  (Some edges may be degenerate.)
  2620.        *
  2621.        * The following discussion assumes left-to-right scanning
  2622.        * (that is, the major edge is on the left); the right-to-left
  2623.        * case is a straightforward variation.
  2624.        *
  2625.        * We start by finding the half-integral y coordinate that is
  2626.        * at or below the top of the triangle.  This gives us the
  2627.        * first scan line that could possibly contain pixels that are
  2628.        * inside the triangle.
  2629.        *
  2630.        * Next we creep down the major edge until we reach that y,
  2631.        * and compute the corresponding x coordinate on the edge.
  2632.        * Then we find the half-integral x that lies on or just
  2633.        * inside the edge.  This is the first pixel that might lie in
  2634.        * the interior of the triangle.  (We won't know for sure
  2635.        * until we check the other edges.)
  2636.        *
  2637.        * As we rasterize the triangle, we'll step down the major
  2638.        * edge.  For each step in y, we'll move an integer number
  2639.        * of steps in x.  There are two possible x step sizes, which
  2640.        * we'll call the ``inner'' step (guaranteed to land on the
  2641.        * edge or inside it) and the ``outer'' step (guaranteed to
  2642.        * land on the edge or outside it).  The inner and outer steps
  2643.        * differ by one.  During rasterization we maintain an error
  2644.        * term that indicates our distance from the true edge, and
  2645.        * select either the inner step or the outer step, whichever
  2646.        * gets us to the first pixel that falls inside the triangle.
  2647.        *
  2648.        * All parameters (z, red, etc.) as well as the buffer
  2649.        * addresses for color and z have inner and outer step values,
  2650.        * so that we can increment them appropriately.  This method
  2651.        * eliminates the need to adjust parameters by creeping a
  2652.        * sub-pixel amount into the triangle at each scanline.
  2653.        */
  2654.  
  2655.       {
  2656.          int subTriangle;
  2657.          GLfixed fx;
  2658.          GLfixed fxLeftEdge = 0, fxRightEdge = 0;
  2659.          GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
  2660.          GLfixed fdxOuter;
  2661.          int idxOuter;
  2662.          float dxOuter;
  2663.          GLfixed fError = 0, fdError = 0;
  2664.          float adjx, adjy;
  2665.          GLfixed fy;
  2666.          GLfixed fs=0, fdsOuter=0, fdsInner;
  2667.          GLfixed ft=0, fdtOuter=0, fdtInner;
  2668.  
  2669.          for (subTriangle=0; subTriangle<=1; subTriangle++) {
  2670.             EdgeT *eLeft, *eRight;
  2671.             int setupLeft, setupRight;
  2672.             int lines;
  2673.  
  2674.             if (subTriangle==0) {
  2675.                /* bottom half */
  2676.                if (scan_from_left_to_right) {
  2677.                   eLeft = &eMaj;
  2678.                   eRight = &eBot;
  2679.                   lines = eRight->lines;
  2680.                   setupLeft = 1;
  2681.                   setupRight = 1;
  2682.                }
  2683.                else {
  2684.                   eLeft = &eBot;
  2685.                   eRight = &eMaj;
  2686.                   lines = eLeft->lines;
  2687.                   setupLeft = 1;
  2688.                   setupRight = 1;
  2689.                }
  2690.             }
  2691.             else {
  2692.                /* top half */
  2693.                if (scan_from_left_to_right) {
  2694.                   eLeft = &eMaj;
  2695.                   eRight = &eTop;
  2696.                   lines = eRight->lines;
  2697.                   setupLeft = 0;
  2698.                   setupRight = 1;
  2699.                }
  2700.                else {
  2701.                   eLeft = &eTop;
  2702.                   eRight = &eMaj;
  2703.                   lines = eLeft->lines;
  2704.                   setupLeft = 1;
  2705.                   setupRight = 0;
  2706.                }
  2707.                if (lines == 0)
  2708.                   return;
  2709.             }
  2710.  
  2711.             if (setupLeft && eLeft->lines > 0) {
  2712.                const SWvertex *vLower;
  2713.                GLfixed fsx = eLeft->fsx;
  2714.                fx = (((fsx) + 0x00000800 - 1) & (~0x000007FF));
  2715.                fError = fx - fsx - 0x00000800;
  2716.                fxLeftEdge = fsx - 1;
  2717.                fdxLeftEdge = eLeft->fdxdy;
  2718.                fdxOuter = ((fdxLeftEdge - 1) & (~0x000007FF));
  2719.                fdError = fdxOuter - fdxLeftEdge + 0x00000800;
  2720.                idxOuter = ((fdxOuter) >> 11);
  2721.                dxOuter = (float) idxOuter;
  2722.                (void) dxOuter;
  2723.  
  2724.                fy = eLeft->fsy;
  2725.                span.y = ((fy) >> 11);
  2726.  
  2727.                adjx = (float)(fx - eLeft->fx0);  /* SCALED! */
  2728.                adjy = eLeft->adjy;              /* SCALED! */
  2729.                vLower = eLeft->v0;
  2730.  
  2731.                /*
  2732.                 * Now we need the set of parameter (z, color, etc.) values at
  2733.                 * the point (fx, fy).  This gives us properly-sampled parameter
  2734.                 * values that we can step from pixel to pixel.  Furthermore,
  2735.                 * although we might have intermediate results that overflow
  2736.                 * the normal parameter range when we step temporarily outside
  2737.                 * the triangle, we shouldn't overflow or underflow for any
  2738.                 * pixel that's actually inside the triangle.
  2739.                 */
  2740.  
  2741.                {
  2742.                   GLfloat s0, t0;
  2743.                   s0 = vLower->texcoord[0][0] * twidth;
  2744.                   fs = (GLfixed)(s0 * 2048.0f + dsdx * adjx
  2745.                                  + dsdy * adjy) + 0x00000400;
  2746.                   fdsOuter = (((int) ((((dsdy + dxOuter * dsdx) * 2048.0f) >= 0.0F) ? (((dsdy + dxOuter * dsdx) * 2048.0f) + 0.5F) : (((dsdy + dxOuter * dsdx) * 2048.0f) - 0.5F))));
  2747.  
  2748.                   t0 = vLower->texcoord[0][1] * theight;
  2749.                   ft = (GLfixed)(t0 * 2048.0f + dtdx * adjx
  2750.                                  + dtdy * adjy) + 0x00000400;
  2751.                   fdtOuter = (((int) ((((dtdy + dxOuter * dtdx) * 2048.0f) >= 0.0F) ? (((dtdy + dxOuter * dtdx) * 2048.0f) + 0.5F) : (((dtdy + dxOuter * dtdx) * 2048.0f) - 0.5F))));
  2752.                }
  2753.  
  2754.             } /*if setupLeft*/
  2755.  
  2756.  
  2757.             if (setupRight && eRight->lines>0) {
  2758.                fxRightEdge = eRight->fsx - 1;
  2759.                fdxRightEdge = eRight->fdxdy;
  2760.             }
  2761.  
  2762.             if (lines==0) {
  2763.                continue;
  2764.             }
  2765.  
  2766.  
  2767.             /* Rasterize setup */
  2768.             fdsInner = fdsOuter + span.intTexStep[0];
  2769.             fdtInner = fdtOuter + span.intTexStep[1];
  2770.  
  2771.             while (lines > 0) {
  2772.                /* initialize the span interpolants to the leftmost value */
  2773.                /* ff = fixed-pt fragment */
  2774.                const GLint right = ((fxRightEdge) >> 11);
  2775.  
  2776.                span.x = ((fxLeftEdge) >> 11);
  2777.  
  2778.                if (right <= span.x)
  2779.                   span.end = 0;
  2780.                else
  2781.                   span.end = right - span.x;
  2782.  
  2783.                span.intTex[0] = fs;
  2784.                span.intTex[1] = ft;
  2785.  
  2786.  
  2787.  
  2788.  
  2789.                /* This is where we actually generate fragments */
  2790.                if (span.end > 0) {
  2791.                   GLuint i; span.intTex[0] -= 0x00000400; span.intTex[1] -= 0x00000400; for (i = 0; i < span.end; i++) { GLint s = ((span.intTex[0]) >> 11) & smask; GLint t = ((span.intTex[1]) >> 11) & tmask; GLint pos = (t << twidth_log2) + s; pos = pos + pos + pos; span.array->rgb[i][0] = texture[pos]; span.array->rgb[i][1] = texture[pos+1]; span.array->rgb[i][2] = texture[pos+2]; span.intTex[0] += span.intTexStep[0]; span.intTex[1] += span.intTexStep[1]; } (*swrast->Driver.WriteRGBSpan)(ctx, span.end, span.x, span.y, (const GLchan (*)[3]) span.array->rgb, 0 );;
  2792.                }
  2793.  
  2794.                /*
  2795.                 * Advance to the next scan line.  Compute the
  2796.                 * new edge coordinates, and adjust the
  2797.                 * pixel-center x coordinate so that it stays
  2798.                 * on or inside the major edge.
  2799.                 */
  2800.                (span.y)++;
  2801.                lines--;
  2802.  
  2803.                fxLeftEdge += fdxLeftEdge;
  2804.                fxRightEdge += fdxRightEdge;
  2805.  
  2806.  
  2807.                fError += fdError;
  2808.                if (fError >= 0) {
  2809.                   fError -= 0x00000800;
  2810.                   fs += fdsOuter;
  2811.                   ft += fdtOuter;
  2812.                }
  2813.                else {
  2814.                   fs += fdsInner;
  2815.                   ft += fdtInner;
  2816.                }
  2817.             } /*while lines>0*/
  2818.  
  2819.          } /* for subTriangle */
  2820.  
  2821.       }
  2822.    }
  2823. }
  2824.  
  2825. /*
  2826.  * Render an RGB, GL_DECAL, textured triangle.
  2827.  * Interpolate S,T, GL_LESS depth test, w/out mipmapping or
  2828.  * perspective correction.
  2829.  *
  2830.  * No fog.
  2831.  */
  2832.  
  2833. /*
  2834.  * Triangle Rasterizer Template
  2835.  *
  2836.  * This file is #include'd to generate custom triangle rasterizers.
  2837.  *
  2838.  * The following macros may be defined to indicate what auxillary information
  2839.  * must be interplated across the triangle:
  2840.  *    INTERP_Z        - if defined, interpolate Z values
  2841.  *    INTERP_FOG      - if defined, interpolate fog values
  2842.  *    INTERP_RGB      - if defined, interpolate RGB values
  2843.  *    INTERP_ALPHA    - if defined, interpolate Alpha values (req's INTERP_RGB)
  2844.  *    INTERP_SPEC     - if defined, interpolate specular RGB values
  2845.  *    INTERP_INDEX    - if defined, interpolate color index values
  2846.  *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
  2847.  *                         (fast, simple 2-D texture mapping)
  2848.  *    INTERP_TEX      - if defined, interpolate set 0 float STRQ texcoords
  2849.  *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
  2850.  *    INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
  2851.  *    INTERP_FLOAT_RGBA - if defined, interpolate RGBA with floating point
  2852.  *    INTERP_FLOAT_SPEC - if defined, interpolate specular with floating point
  2853.  *
  2854.  * When one can directly address pixels in the color buffer the following
  2855.  * macros can be defined and used to compute pixel addresses during
  2856.  * rasterization (see pRow):
  2857.  *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
  2858.  *    BYTES_PER_ROW       - number of bytes per row in the color buffer
  2859.  *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
  2860.  *                          Y==0 at bottom of screen and increases upward.
  2861.  *
  2862.  * Similarly, for direct depth buffer access, this type is used for depth
  2863.  * buffer addressing:
  2864.  *    DEPTH_TYPE          - either GLushort or GLuint
  2865.  *
  2866.  * Optionally, one may provide one-time setup code per triangle:
  2867.  *    SETUP_CODE    - code which is to be executed once per triangle
  2868.  *    CLEANUP_CODE    - code to execute at end of triangle
  2869.  *
  2870.  * The following macro MUST be defined:
  2871.  *    RENDER_SPAN(span) - code to write a span of pixels.
  2872.  *
  2873.  * This code was designed for the origin to be in the lower-left corner.
  2874.  *
  2875.  * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
  2876.  */
  2877.  
  2878.  
  2879. /*
  2880.  * This is a bit of a hack, but it's a centralized place to enable floating-
  2881.  * point color interpolation when GLchan is actually floating point.
  2882.  */
  2883.  
  2884.  
  2885.  
  2886. static void simple_z_textured_triangle(GLcontext *ctx, const SWvertex *v0,
  2887.                                  const SWvertex *v1,
  2888.                                  const SWvertex *v2 )
  2889. {
  2890.    typedef struct {
  2891.         const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
  2892.         GLfloat dx;    /* X(v1) - X(v0) */
  2893.         GLfloat dy;    /* Y(v1) - Y(v0) */
  2894.         GLfixed fdxdy; /* dx/dy in fixed-point */
  2895.         GLfixed fsx;   /* first sample point x coord */
  2896.         GLfixed fsy;
  2897.         GLfloat adjy;  /* adjust from v[0]->fy to fsy, scaled */
  2898.         GLint lines;   /* number of lines to be sampled on this edge */
  2899.         GLfixed fx0;   /* fixed pt X of lower endpoint */
  2900.    } EdgeT;
  2901.  
  2902.    const GLint depthBits = ctx->Visual.depthBits;
  2903.    const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0;
  2904.    const GLfloat maxDepth = ctx->DepthMaxF;
  2905.    EdgeT eMaj, eTop, eBot;
  2906.    GLfloat oneOverArea;
  2907.    const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
  2908.    float bf = ((SWcontext *)ctx->swrast_context)->_backface_sign;
  2909.    const GLint snapMask = ~((0x00000800 / (1 << 4)) - 1); /* for x/y coord snapping */
  2910.    GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
  2911.  
  2912.    struct sw_span span;
  2913.  
  2914.    do { (span).primitive = (0x0009); (span).interpMask = (0); (span).arrayMask = (0); (span).start = 0; (span).end = (0); (span).facing = 0; (span).array = ((SWcontext *)ctx->swrast_context)->SpanArrays; } while (0);
  2915.  
  2916.  
  2917.    printf("%s()\n", __FUNCTION__);
  2918.    /*
  2919.    printf("  %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
  2920.    printf("  %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
  2921.    printf("  %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
  2922.     */
  2923.  
  2924.    /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
  2925.     * And find the order of the 3 vertices along the Y axis.
  2926.     */
  2927.    {
  2928.       const GLfixed fy0 = (((int) ((((v0->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v0->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v0->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  2929.       const GLfixed fy1 = (((int) ((((v1->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v1->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v1->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  2930.       const GLfixed fy2 = (((int) ((((v2->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v2->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v2->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  2931.  
  2932.       if (fy0 <= fy1) {
  2933.          if (fy1 <= fy2) {
  2934.             /* y0 <= y1 <= y2 */
  2935.             vMin = v0;   vMid = v1;   vMax = v2;
  2936.             vMin_fy = fy0;  vMid_fy = fy1;  vMax_fy = fy2;
  2937.          }
  2938.          else if (fy2 <= fy0) {
  2939.             /* y2 <= y0 <= y1 */
  2940.             vMin = v2;   vMid = v0;   vMax = v1;
  2941.             vMin_fy = fy2;  vMid_fy = fy0;  vMax_fy = fy1;
  2942.          }
  2943.          else {
  2944.             /* y0 <= y2 <= y1 */
  2945.             vMin = v0;   vMid = v2;   vMax = v1;
  2946.             vMin_fy = fy0;  vMid_fy = fy2;  vMax_fy = fy1;
  2947.             bf = -bf;
  2948.          }
  2949.       }
  2950.       else {
  2951.          if (fy0 <= fy2) {
  2952.             /* y1 <= y0 <= y2 */
  2953.             vMin = v1;   vMid = v0;   vMax = v2;
  2954.             vMin_fy = fy1;  vMid_fy = fy0;  vMax_fy = fy2;
  2955.             bf = -bf;
  2956.          }
  2957.          else if (fy2 <= fy1) {
  2958.             /* y2 <= y1 <= y0 */
  2959.             vMin = v2;   vMid = v1;   vMax = v0;
  2960.             vMin_fy = fy2;  vMid_fy = fy1;  vMax_fy = fy0;
  2961.             bf = -bf;
  2962.          }
  2963.          else {
  2964.             /* y1 <= y2 <= y0 */
  2965.             vMin = v1;   vMid = v2;   vMax = v0;
  2966.             vMin_fy = fy1;  vMid_fy = fy2;  vMax_fy = fy0;
  2967.          }
  2968.       }
  2969.  
  2970.       /* fixed point X coords */
  2971.       vMin_fx = (((int) ((((vMin->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMin->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMin->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  2972.       vMid_fx = (((int) ((((vMid->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMid->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMid->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  2973.       vMax_fx = (((int) ((((vMax->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMax->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMax->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  2974.    }
  2975.  
  2976.    /* vertex/edge relationship */
  2977.    eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
  2978.    eTop.v0 = vMid;   eTop.v1 = vMax;
  2979.    eBot.v0 = vMin;   eBot.v1 = vMid;
  2980.  
  2981.    /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
  2982.    eMaj.dx = ((vMax_fx - vMin_fx) * (1.0F / 2048.0f));
  2983.    eMaj.dy = ((vMax_fy - vMin_fy) * (1.0F / 2048.0f));
  2984.    eTop.dx = ((vMax_fx - vMid_fx) * (1.0F / 2048.0f));
  2985.    eTop.dy = ((vMax_fy - vMid_fy) * (1.0F / 2048.0f));
  2986.    eBot.dx = ((vMid_fx - vMin_fx) * (1.0F / 2048.0f));
  2987.    eBot.dy = ((vMid_fy - vMin_fy) * (1.0F / 2048.0f));
  2988.  
  2989.    /* compute area, oneOverArea and perform backface culling */
  2990.    {
  2991.       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
  2992.  
  2993.       /* Do backface culling */
  2994.       if (area * bf < 0.0)
  2995.          return;
  2996.  
  2997.       if (IS_INF_OR_NAN(area) || area == 0.0F)
  2998.          return;
  2999.  
  3000.       oneOverArea = 1.0F / area;
  3001.    }
  3002.  
  3003.    ctx->OcclusionResult = 0x1;
  3004.    span.facing = ctx->_Facing; /* for 2-sided stencil test */
  3005.  
  3006.    /* Edge setup.  For a triangle strip these could be reused... */
  3007.    {
  3008.       eMaj.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  3009.       eMaj.lines = (((((vMax_fy - eMaj.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  3010.       if (eMaj.lines > 0) {
  3011.          GLfloat dxdy = eMaj.dx / eMaj.dy;
  3012.          eMaj.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  3013.          eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
  3014.          eMaj.fx0 = vMin_fx;
  3015.          eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy);
  3016.       }
  3017.       else {
  3018.          return;  /*CULLED*/
  3019.       }
  3020.  
  3021.       eTop.fsy = (((vMid_fy) + 0x00000800 - 1) & (~0x000007FF));
  3022.       eTop.lines = (((((vMax_fy - eTop.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  3023.       if (eTop.lines > 0) {
  3024.          GLfloat dxdy = eTop.dx / eTop.dy;
  3025.          eTop.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  3026.          eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
  3027.          eTop.fx0 = vMid_fx;
  3028.          eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy);
  3029.       }
  3030.  
  3031.       eBot.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  3032.       eBot.lines = (((((vMid_fy - eBot.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  3033.       if (eBot.lines > 0) {
  3034.          GLfloat dxdy = eBot.dx / eBot.dy;
  3035.          eBot.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  3036.          eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
  3037.          eBot.fx0 = vMin_fx;
  3038.          eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy);
  3039.       }
  3040.    }
  3041.  
  3042.    /*
  3043.     * Conceptually, we view a triangle as two subtriangles
  3044.     * separated by a perfectly horizontal line.  The edge that is
  3045.     * intersected by this line is one with maximal absolute dy; we
  3046.     * call it a ``major'' edge.  The other two edges are the
  3047.     * ``top'' edge (for the upper subtriangle) and the ``bottom''
  3048.     * edge (for the lower subtriangle).  If either of these two
  3049.     * edges is horizontal or very close to horizontal, the
  3050.     * corresponding subtriangle might cover zero sample points;
  3051.     * we take care to handle such cases, for performance as well
  3052.     * as correctness.
  3053.     *
  3054.     * By stepping rasterization parameters along the major edge,
  3055.     * we can avoid recomputing them at the discontinuity where
  3056.     * the top and bottom edges meet.  However, this forces us to
  3057.     * be able to scan both left-to-right and right-to-left.
  3058.     * Also, we must determine whether the major edge is at the
  3059.     * left or right side of the triangle.  We do this by
  3060.     * computing the magnitude of the cross-product of the major
  3061.     * and top edges.  Since this magnitude depends on the sine of
  3062.     * the angle between the two edges, its sign tells us whether
  3063.     * we turn to the left or to the right when travelling along
  3064.     * the major edge to the top edge, and from this we infer
  3065.     * whether the major edge is on the left or the right.
  3066.     *
  3067.     * Serendipitously, this cross-product magnitude is also a
  3068.     * value we need to compute the iteration parameter
  3069.     * derivatives for the triangle, and it can be used to perform
  3070.     * backface culling because its sign tells us whether the
  3071.     * triangle is clockwise or counterclockwise.  In this code we
  3072.     * refer to it as ``area'' because it's also proportional to
  3073.     * the pixel area of the triangle.
  3074.     */
  3075.  
  3076.    {
  3077.       GLint scan_from_left_to_right;  /* true if scanning left-to-right */
  3078.       GLfloat dzdx, dzdy;
  3079.       GLfloat dsdx, dsdy;
  3080.       GLfloat dtdx, dtdy;
  3081.  
  3082.       /*
  3083.        * Execute user-supplied setup code
  3084.        */
  3085.       SWcontext *swrast = ((SWcontext *)ctx->swrast_context); struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; const GLint b = obj->BaseLevel; const GLfloat twidth = (GLfloat) obj->Image[b]->Width; const GLfloat theight = (GLfloat) obj->Image[b]->Height; const GLint twidth_log2 = obj->Image[b]->WidthLog2; const GLchan *texture = (const GLchan *) obj->Image[b]->Data; const GLint smask = obj->Image[b]->Width - 1; const GLint tmask = obj->Image[b]->Height - 1; if (!texture) { return; }
  3086.  
  3087.       scan_from_left_to_right = (oneOverArea < 0.0F);
  3088.  
  3089.  
  3090.       /* compute d?/dx and d?/dy derivatives */
  3091.       span.interpMask |= 0x008;
  3092.       {
  3093.          GLfloat eMaj_dz, eBot_dz;
  3094.          eMaj_dz = vMax->win[2] - vMin->win[2];
  3095.          eBot_dz = vMid->win[2] - vMin->win[2];
  3096.          dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
  3097.          if (dzdx > maxDepth || dzdx < -maxDepth) {
  3098.             /* probably a sliver triangle */
  3099.             dzdx = 0.0;
  3100.             dzdy = 0.0;
  3101.          }
  3102.          else {
  3103.             dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
  3104.          }
  3105.          if (depthBits <= 16)
  3106.             span.zStep = (((int) ((((dzdx) * 2048.0f) >= 0.0F) ? (((dzdx) * 2048.0f) + 0.5F) : (((dzdx) * 2048.0f) - 0.5F))));
  3107.          else
  3108.             span.zStep = (GLint) dzdx;
  3109.       }
  3110.       span.interpMask |= 0x040;
  3111.       {
  3112.          GLfloat eMaj_ds, eBot_ds;
  3113.          eMaj_ds = (vMax->texcoord[0][0] - vMin->texcoord[0][0]) * twidth;
  3114.          eBot_ds = (vMid->texcoord[0][0] - vMin->texcoord[0][0]) * twidth;
  3115.          dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
  3116.          span.intTexStep[0] = (((int) ((((dsdx) * 2048.0f) >= 0.0F) ? (((dsdx) * 2048.0f) + 0.5F) : (((dsdx) * 2048.0f) - 0.5F))));
  3117.          dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
  3118.       }
  3119.       {
  3120.          GLfloat eMaj_dt, eBot_dt;
  3121.          eMaj_dt = (vMax->texcoord[0][1] - vMin->texcoord[0][1]) * theight;
  3122.          eBot_dt = (vMid->texcoord[0][1] - vMin->texcoord[0][1]) * theight;
  3123.          dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
  3124.          span.intTexStep[1] = (((int) ((((dtdx) * 2048.0f) >= 0.0F) ? (((dtdx) * 2048.0f) + 0.5F) : (((dtdx) * 2048.0f) - 0.5F))));
  3125.          dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
  3126.       }
  3127.  
  3128.  
  3129.       /*
  3130.        * We always sample at pixel centers.  However, we avoid
  3131.        * explicit half-pixel offsets in this code by incorporating
  3132.        * the proper offset in each of x and y during the
  3133.        * transformation to window coordinates.
  3134.        *
  3135.        * We also apply the usual rasterization rules to prevent
  3136.        * cracks and overlaps.  A pixel is considered inside a
  3137.        * subtriangle if it meets all of four conditions: it is on or
  3138.        * to the right of the left edge, strictly to the left of the
  3139.        * right edge, on or below the top edge, and strictly above
  3140.        * the bottom edge.  (Some edges may be degenerate.)
  3141.        *
  3142.        * The following discussion assumes left-to-right scanning
  3143.        * (that is, the major edge is on the left); the right-to-left
  3144.        * case is a straightforward variation.
  3145.        *
  3146.        * We start by finding the half-integral y coordinate that is
  3147.        * at or below the top of the triangle.  This gives us the
  3148.        * first scan line that could possibly contain pixels that are
  3149.        * inside the triangle.
  3150.        *
  3151.        * Next we creep down the major edge until we reach that y,
  3152.        * and compute the corresponding x coordinate on the edge.
  3153.        * Then we find the half-integral x that lies on or just
  3154.        * inside the edge.  This is the first pixel that might lie in
  3155.        * the interior of the triangle.  (We won't know for sure
  3156.        * until we check the other edges.)
  3157.        *
  3158.        * As we rasterize the triangle, we'll step down the major
  3159.        * edge.  For each step in y, we'll move an integer number
  3160.        * of steps in x.  There are two possible x step sizes, which
  3161.        * we'll call the ``inner'' step (guaranteed to land on the
  3162.        * edge or inside it) and the ``outer'' step (guaranteed to
  3163.        * land on the edge or outside it).  The inner and outer steps
  3164.        * differ by one.  During rasterization we maintain an error
  3165.        * term that indicates our distance from the true edge, and
  3166.        * select either the inner step or the outer step, whichever
  3167.        * gets us to the first pixel that falls inside the triangle.
  3168.        *
  3169.        * All parameters (z, red, etc.) as well as the buffer
  3170.        * addresses for color and z have inner and outer step values,
  3171.        * so that we can increment them appropriately.  This method
  3172.        * eliminates the need to adjust parameters by creeping a
  3173.        * sub-pixel amount into the triangle at each scanline.
  3174.        */
  3175.  
  3176.       {
  3177.          int subTriangle;
  3178.          GLfixed fx;
  3179.          GLfixed fxLeftEdge = 0, fxRightEdge = 0;
  3180.          GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
  3181.          GLfixed fdxOuter;
  3182.          int idxOuter;
  3183.          float dxOuter;
  3184.          GLfixed fError = 0, fdError = 0;
  3185.          float adjx, adjy;
  3186.          GLfixed fy;
  3187.          GLushort *zRow = 0;
  3188.          int dZRowOuter = 0, dZRowInner;  /* offset in bytes */
  3189.          GLfixed fz = 0, fdzOuter = 0, fdzInner;
  3190.          GLfixed fs=0, fdsOuter=0, fdsInner;
  3191.          GLfixed ft=0, fdtOuter=0, fdtInner;
  3192.  
  3193.          for (subTriangle=0; subTriangle<=1; subTriangle++) {
  3194.             EdgeT *eLeft, *eRight;
  3195.             int setupLeft, setupRight;
  3196.             int lines;
  3197.  
  3198.             if (subTriangle==0) {
  3199.                /* bottom half */
  3200.                if (scan_from_left_to_right) {
  3201.                   eLeft = &eMaj;
  3202.                   eRight = &eBot;
  3203.                   lines = eRight->lines;
  3204.                   setupLeft = 1;
  3205.                   setupRight = 1;
  3206.                }
  3207.                else {
  3208.                   eLeft = &eBot;
  3209.                   eRight = &eMaj;
  3210.                   lines = eLeft->lines;
  3211.                   setupLeft = 1;
  3212.                   setupRight = 1;
  3213.                }
  3214.             }
  3215.             else {
  3216.                /* top half */
  3217.                if (scan_from_left_to_right) {
  3218.                   eLeft = &eMaj;
  3219.                   eRight = &eTop;
  3220.                   lines = eRight->lines;
  3221.                   setupLeft = 0;
  3222.                   setupRight = 1;
  3223.                }
  3224.                else {
  3225.                   eLeft = &eTop;
  3226.                   eRight = &eMaj;
  3227.                   lines = eLeft->lines;
  3228.                   setupLeft = 1;
  3229.                   setupRight = 0;
  3230.                }
  3231.                if (lines == 0)
  3232.                   return;
  3233.             }
  3234.  
  3235.             if (setupLeft && eLeft->lines > 0) {
  3236.                const SWvertex *vLower;
  3237.                GLfixed fsx = eLeft->fsx;
  3238.                fx = (((fsx) + 0x00000800 - 1) & (~0x000007FF));
  3239.                fError = fx - fsx - 0x00000800;
  3240.                fxLeftEdge = fsx - 1;
  3241.                fdxLeftEdge = eLeft->fdxdy;
  3242.                fdxOuter = ((fdxLeftEdge - 1) & (~0x000007FF));
  3243.                fdError = fdxOuter - fdxLeftEdge + 0x00000800;
  3244.                idxOuter = ((fdxOuter) >> 11);
  3245.                dxOuter = (float) idxOuter;
  3246.                (void) dxOuter;
  3247.  
  3248.                fy = eLeft->fsy;
  3249.                span.y = ((fy) >> 11);
  3250.  
  3251.                adjx = (float)(fx - eLeft->fx0);  /* SCALED! */
  3252.                adjy = eLeft->adjy;              /* SCALED! */
  3253.                vLower = eLeft->v0;
  3254.  
  3255.                /*
  3256.                 * Now we need the set of parameter (z, color, etc.) values at
  3257.                 * the point (fx, fy).  This gives us properly-sampled parameter
  3258.                 * values that we can step from pixel to pixel.  Furthermore,
  3259.                 * although we might have intermediate results that overflow
  3260.                 * the normal parameter range when we step temporarily outside
  3261.                 * the triangle, we shouldn't overflow or underflow for any
  3262.                 * pixel that's actually inside the triangle.
  3263.                 */
  3264.  
  3265.                {
  3266.                   GLfloat z0 = vLower->win[2];
  3267.                   if (depthBits <= 16) {
  3268.                      /* interpolate fixed-pt values */
  3269.                      GLfloat tmp = (z0 * 2048.0f +
  3270.                                     dzdx * adjx + dzdy * adjy) + 0x00000400;
  3271.                      if (tmp < 0xffffffff / 2)
  3272.                         fz = (GLfixed) tmp;
  3273.                      else
  3274.                         fz = 0xffffffff / 2;
  3275.                      fdzOuter = (((int) ((((dzdy + dxOuter * dzdx) * 2048.0f) >= 0.0F) ? (((dzdy + dxOuter * dzdx) * 2048.0f) + 0.5F) : (((dzdy + dxOuter * dzdx) * 2048.0f) - 0.5F))));
  3276.                   }
  3277.                   else {
  3278.                      /* interpolate depth values exactly */
  3279.                      fz = (GLint) (z0 + dzdx * ((adjx) * (1.0F / 2048.0f))
  3280.                                    + dzdy * ((adjy) * (1.0F / 2048.0f)));
  3281.                      fdzOuter = (GLint) (dzdy + dxOuter * dzdx);
  3282.                   }
  3283.                   zRow = (GLushort *)
  3284.                     _mesa_zbuffer_address(ctx, ((fxLeftEdge) >> 11), span.y);
  3285.                   dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(GLushort);
  3286.                }
  3287.                {
  3288.                   GLfloat s0, t0;
  3289.                   s0 = vLower->texcoord[0][0] * twidth;
  3290.                   fs = (GLfixed)(s0 * 2048.0f + dsdx * adjx
  3291.                                  + dsdy * adjy) + 0x00000400;
  3292.                   fdsOuter = (((int) ((((dsdy + dxOuter * dsdx) * 2048.0f) >= 0.0F) ? (((dsdy + dxOuter * dsdx) * 2048.0f) + 0.5F) : (((dsdy + dxOuter * dsdx) * 2048.0f) - 0.5F))));
  3293.  
  3294.                   t0 = vLower->texcoord[0][1] * theight;
  3295.                   ft = (GLfixed)(t0 * 2048.0f + dtdx * adjx
  3296.                                  + dtdy * adjy) + 0x00000400;
  3297.                   fdtOuter = (((int) ((((dtdy + dxOuter * dtdx) * 2048.0f) >= 0.0F) ? (((dtdy + dxOuter * dtdx) * 2048.0f) + 0.5F) : (((dtdy + dxOuter * dtdx) * 2048.0f) - 0.5F))));
  3298.                }
  3299.  
  3300.             } /*if setupLeft*/
  3301.  
  3302.  
  3303.             if (setupRight && eRight->lines>0) {
  3304.                fxRightEdge = eRight->fsx - 1;
  3305.                fdxRightEdge = eRight->fdxdy;
  3306.             }
  3307.  
  3308.             if (lines==0) {
  3309.                continue;
  3310.             }
  3311.  
  3312.  
  3313.             /* Rasterize setup */
  3314.             dZRowInner = dZRowOuter + sizeof(GLushort);
  3315.             fdzInner = fdzOuter + span.zStep;
  3316.             fdsInner = fdsOuter + span.intTexStep[0];
  3317.             fdtInner = fdtOuter + span.intTexStep[1];
  3318.  
  3319.             while (lines > 0) {
  3320.                /* initialize the span interpolants to the leftmost value */
  3321.                /* ff = fixed-pt fragment */
  3322.                const GLint right = ((fxRightEdge) >> 11);
  3323.  
  3324.                span.x = ((fxLeftEdge) >> 11);
  3325.  
  3326.                if (right <= span.x)
  3327.                   span.end = 0;
  3328.                else
  3329.                   span.end = right - span.x;
  3330.  
  3331.                span.z = fz;
  3332.                span.intTex[0] = fs;
  3333.                span.intTex[1] = ft;
  3334.  
  3335.  
  3336.  
  3337.  
  3338.                /* This is where we actually generate fragments */
  3339.                if (span.end > 0) {
  3340.                   GLuint i; span.intTex[0] -= 0x00000400; span.intTex[1] -= 0x00000400; for (i = 0; i < span.end; i++) { const GLdepth z = ((span.z) >> fixedToDepthShift); if (z < zRow[i]) { GLint s = ((span.intTex[0]) >> 11) & smask; GLint t = ((span.intTex[1]) >> 11) & tmask; GLint pos = (t << twidth_log2) + s; pos = pos + pos + pos; span.array->rgb[i][0] = texture[pos]; span.array->rgb[i][1] = texture[pos+1]; span.array->rgb[i][2] = texture[pos+2]; zRow[i] = z; span.array->mask[i] = 1; } else { span.array->mask[i] = 0; } span.intTex[0] += span.intTexStep[0]; span.intTex[1] += span.intTexStep[1]; span.z += span.zStep; } (*swrast->Driver.WriteRGBSpan)(ctx, span.end, span.x, span.y, (const GLchan (*)[3]) span.array->rgb, span.array->mask );;
  3341.                }
  3342.  
  3343.                /*
  3344.                 * Advance to the next scan line.  Compute the
  3345.                 * new edge coordinates, and adjust the
  3346.                 * pixel-center x coordinate so that it stays
  3347.                 * on or inside the major edge.
  3348.                 */
  3349.                (span.y)++;
  3350.                lines--;
  3351.  
  3352.                fxLeftEdge += fdxLeftEdge;
  3353.                fxRightEdge += fdxRightEdge;
  3354.  
  3355.  
  3356.                fError += fdError;
  3357.                if (fError >= 0) {
  3358.                   fError -= 0x00000800;
  3359.                   zRow = (GLushort *) ((GLubyte *) zRow + dZRowOuter);
  3360.                   fz += fdzOuter;
  3361.                   fs += fdsOuter;
  3362.                   ft += fdtOuter;
  3363.                }
  3364.                else {
  3365.                   zRow = (GLushort *) ((GLubyte *) zRow + dZRowInner);
  3366.                   fz += fdzInner;
  3367.                   fs += fdsInner;
  3368.                   ft += fdtInner;
  3369.                }
  3370.             } /*while lines>0*/
  3371.  
  3372.          } /* for subTriangle */
  3373.  
  3374.       }
  3375.    }
  3376. }
  3377.  
  3378.  
  3379.  
  3380.  
  3381.  
  3382.  
  3383.  
  3384.  
  3385.  
  3386.  
  3387. struct affine_info
  3388. {
  3389.    GLenum filter;
  3390.    GLenum format;
  3391.    GLenum envmode;
  3392.    GLint smask, tmask;
  3393.    GLint twidth_log2;
  3394.    const GLchan *texture;
  3395.    GLfixed er, eg, eb, ea;
  3396.    GLint tbytesline, tsize;
  3397. };
  3398.  
  3399.  
  3400. /* This function can handle GL_NEAREST or GL_LINEAR sampling of 2D RGB or RGBA
  3401.  * textures with GL_REPLACE, GL_MODULATE, GL_BLEND, GL_DECAL or GL_ADD
  3402.  * texture env modes.
  3403.  */
  3404. static inline void
  3405. affine_span(GLcontext *ctx, struct sw_span *span,
  3406.             struct affine_info *info)
  3407. {
  3408.    GLchan sample[4];  /* the filtered texture sample */
  3409.  
  3410.    /* Instead of defining a function for each mode, a test is done
  3411.     * between the outer and inner loops. This is to reduce code size
  3412.     * and complexity. Observe that an optimizing compiler kills
  3413.     * unused variables (for instance tf,sf,ti,si in case of GL_NEAREST).
  3414.     */
  3415.  
  3416.  
  3417.  
  3418.  
  3419.  
  3420.  
  3421.  
  3422.  
  3423.  
  3424.  
  3425. /* shortcuts */
  3426.  
  3427.  
  3428.  
  3429.  
  3430.  
  3431.  
  3432.    GLuint i;
  3433.    GLchan *dest = span->array->rgba[0];
  3434.  
  3435.    span->intTex[0] -= 0x00000400;
  3436.    span->intTex[1] -= 0x00000400;
  3437.    switch (info->filter) {
  3438.    case 0x2600:
  3439.       switch (info->format) {
  3440.       case 0x1907:
  3441.          switch (info->envmode) {
  3442.          case 0x2100:
  3443.             for (i = 0; i < span->end; i++) { GLint s = ((span->intTex[0]) >> 11) & info->smask; GLint t = ((span->intTex[1]) >> 11) & info->tmask; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 3 * pos; sample[0] = tex00[0]; sample[1] = tex00[1]; sample[2] = tex00[2]; sample[3] = 255;dest[0] = span->red * (sample[0] + 1u) >> (11 + 8); dest[1] = span->green * (sample[1] + 1u) >> (11 + 8); dest[2] = span->blue * (sample[2] + 1u) >> (11 + 8); dest[3] = span->alpha * (sample[3] + 1u) >> (11 + 8); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; span->intTex[0] += span->intTexStep[0]; span->intTex[1] += span->intTexStep[1]; dest += 4; };
  3444.             break;
  3445.          case 0x2101:
  3446.          case 0x1E01:
  3447.             for (i = 0; i < span->end; i++) { GLint s = ((span->intTex[0]) >> 11) & info->smask; GLint t = ((span->intTex[1]) >> 11) & info->tmask; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 3 * pos; sample[0] = tex00[0]; sample[1] = tex00[1]; sample[2] = tex00[2]; sample[3] = 255; dest[0] = sample[0]; dest[1] = sample[1]; dest[2] = sample[2]; dest[3] = ((span->alpha) >> 11);; span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; span->intTex[0] += span->intTexStep[0]; span->intTex[1] += span->intTexStep[1]; dest += 4; };
  3448.             break;
  3449.          case 0x0BE2:
  3450.             for (i = 0; i < span->end; i++) { GLint s = ((span->intTex[0]) >> 11) & info->smask; GLint t = ((span->intTex[1]) >> 11) & info->tmask; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 3 * pos; sample[0] = tex00[0]; sample[1] = tex00[1]; sample[2] = tex00[2]; sample[3] = 255;dest[0] = ((255 - sample[0]) * span->red + (sample[0] + 1) * info->er) >> (11 + 8); dest[1] = ((255 - sample[1]) * span->green + (sample[1] + 1) * info->eg) >> (11 + 8); dest[2] = ((255 - sample[2]) * span->blue + (sample[2] + 1) * info->eb) >> (11 + 8); dest[3] = span->alpha * (sample[3] + 1) >> (11 + 8); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; span->intTex[0] += span->intTexStep[0]; span->intTex[1] += span->intTexStep[1]; dest += 4; };
  3451.             break;
  3452.          case 0x0104:
  3453.             for (i = 0; i < span->end; i++) { GLint s = ((span->intTex[0]) >> 11) & info->smask; GLint t = ((span->intTex[1]) >> 11) & info->tmask; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 3 * pos; sample[0] = tex00[0]; sample[1] = tex00[1]; sample[2] = tex00[2]; sample[3] = 255;{ GLint rSum = ((span->red) >> 11) + (GLint) sample[0]; GLint gSum = ((span->green) >> 11) + (GLint) sample[1]; GLint bSum = ((span->blue) >> 11) + (GLint) sample[2]; dest[0] = ( (rSum)<(255) ? (rSum) : (255) ); dest[1] = ( (gSum)<(255) ? (gSum) : (255) ); dest[2] = ( (bSum)<(255) ? (bSum) : (255) ); dest[3] = span->alpha * (sample[3] + 1) >> (11 + 8); }; span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; span->intTex[0] += span->intTexStep[0]; span->intTex[1] += span->intTexStep[1]; dest += 4; };
  3454.             break;
  3455.          default:
  3456.             _mesa_problem(ctx, "bad tex env mode in SPAN_LINEAR");
  3457.             return;
  3458.          }
  3459.          break;
  3460.       case 0x1908:
  3461.          switch(info->envmode) {
  3462.          case 0x2100:
  3463.             for (i = 0; i < span->end; i++) { GLint s = ((span->intTex[0]) >> 11) & info->smask; GLint t = ((span->intTex[1]) >> 11) & info->tmask; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; { (sample)[0] = (tex00)[0]; (sample)[1] = (tex00)[1]; (sample)[2] = (tex00)[2]; (sample)[3] = (tex00)[3]; };dest[0] = span->red * (sample[0] + 1u) >> (11 + 8); dest[1] = span->green * (sample[1] + 1u) >> (11 + 8); dest[2] = span->blue * (sample[2] + 1u) >> (11 + 8); dest[3] = span->alpha * (sample[3] + 1u) >> (11 + 8); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; span->intTex[0] += span->intTexStep[0]; span->intTex[1] += span->intTexStep[1]; dest += 4; };
  3464.             break;
  3465.          case 0x2101:
  3466.             for (i = 0; i < span->end; i++) { GLint s = ((span->intTex[0]) >> 11) & info->smask; GLint t = ((span->intTex[1]) >> 11) & info->tmask; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; { (sample)[0] = (tex00)[0]; (sample)[1] = (tex00)[1]; (sample)[2] = (tex00)[2]; (sample)[3] = (tex00)[3]; };dest[0] = ((255 - sample[3]) * span->red + ((sample[3] + 1) * sample[0] << 11)) >> (11 + 8); dest[1] = ((255 - sample[3]) * span->green + ((sample[3] + 1) * sample[1] << 11)) >> (11 + 8); dest[2] = ((255 - sample[3]) * span->blue + ((sample[3] + 1) * sample[2] << 11)) >> (11 + 8); dest[3] = ((span->alpha) >> 11); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; span->intTex[0] += span->intTexStep[0]; span->intTex[1] += span->intTexStep[1]; dest += 4; };
  3467.             break;
  3468.          case 0x0BE2:
  3469.             for (i = 0; i < span->end; i++) { GLint s = ((span->intTex[0]) >> 11) & info->smask; GLint t = ((span->intTex[1]) >> 11) & info->tmask; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; { (sample)[0] = (tex00)[0]; (sample)[1] = (tex00)[1]; (sample)[2] = (tex00)[2]; (sample)[3] = (tex00)[3]; };dest[0] = ((255 - sample[0]) * span->red + (sample[0] + 1) * info->er) >> (11 + 8); dest[1] = ((255 - sample[1]) * span->green + (sample[1] + 1) * info->eg) >> (11 + 8); dest[2] = ((255 - sample[2]) * span->blue + (sample[2] + 1) * info->eb) >> (11 + 8); dest[3] = span->alpha * (sample[3] + 1) >> (11 + 8); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; span->intTex[0] += span->intTexStep[0]; span->intTex[1] += span->intTexStep[1]; dest += 4; };
  3470.             break;
  3471.          case 0x0104:
  3472.             for (i = 0; i < span->end; i++) { GLint s = ((span->intTex[0]) >> 11) & info->smask; GLint t = ((span->intTex[1]) >> 11) & info->tmask; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; { (sample)[0] = (tex00)[0]; (sample)[1] = (tex00)[1]; (sample)[2] = (tex00)[2]; (sample)[3] = (tex00)[3]; };{ GLint rSum = ((span->red) >> 11) + (GLint) sample[0]; GLint gSum = ((span->green) >> 11) + (GLint) sample[1]; GLint bSum = ((span->blue) >> 11) + (GLint) sample[2]; dest[0] = ( (rSum)<(255) ? (rSum) : (255) ); dest[1] = ( (gSum)<(255) ? (gSum) : (255) ); dest[2] = ( (bSum)<(255) ? (bSum) : (255) ); dest[3] = span->alpha * (sample[3] + 1) >> (11 + 8); }; span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; span->intTex[0] += span->intTexStep[0]; span->intTex[1] += span->intTexStep[1]; dest += 4; };
  3473.             break;
  3474.          case 0x1E01:
  3475.             for (i = 0; i < span->end; i++) { GLint s = ((span->intTex[0]) >> 11) & info->smask; GLint t = ((span->intTex[1]) >> 11) & info->tmask; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; { (dest)[0] = (tex00)[0]; (dest)[1] = (tex00)[1]; (dest)[2] = (tex00)[2]; (dest)[3] = (tex00)[3]; }; span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; span->intTex[0] += span->intTexStep[0]; span->intTex[1] += span->intTexStep[1]; dest += 4; };
  3476.             break;
  3477.          default:
  3478.             _mesa_problem(ctx, "bad tex env mode (2) in SPAN_LINEAR");
  3479.             return;
  3480.          }
  3481.          break;
  3482.       }
  3483.       break;
  3484.  
  3485.    case 0x2601:
  3486.       span->intTex[0] -= 0x00000400;
  3487.       span->intTex[1] -= 0x00000400;
  3488.       switch (info->format) {
  3489.       case 0x1907:
  3490.          switch (info->envmode) {
  3491.          case 0x2100:
  3492.             for (i = 0; i < span->end; i++) { GLint s = ((span->intTex[0]) >> 11) & info->smask; GLint t = ((span->intTex[1]) >> 11) & info->tmask; GLfixed sf = span->intTex[0] & 0x000007FF; GLfixed tf = span->intTex[1] & 0x000007FF; GLfixed si = 0x000007FF - sf; GLfixed ti = 0x000007FF - tf; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 3 * pos; const GLchan *tex10 = tex00 + info->tbytesline; const GLchan *tex01 = tex00 + 3; const GLchan *tex11 = tex10 + 3; (void) ti; (void) si; if (t == info->tmask) { tex10 -= info->tsize; tex11 -= info->tsize; } if (s == info->smask) { tex01 -= info->tbytesline; tex11 -= info->tbytesline; } sample[0] = (ti * (si * tex00[0] + sf * tex01[0]) + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * 11; sample[1] = (ti * (si * tex00[1] + sf * tex01[1]) + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * 11; sample[2] = (ti * (si * tex00[2] + sf * tex01[2]) + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * 11; sample[3] = 255;dest[0] = span->red * (sample[0] + 1u) >> (11 + 8); dest[1] = span->green * (sample[1] + 1u) >> (11 + 8); dest[2] = span->blue * (sample[2] + 1u) >> (11 + 8); dest[3] = span->alpha * (sample[3] + 1u) >> (11 + 8); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; span->intTex[0] += span->intTexStep[0]; span->intTex[1] += span->intTexStep[1]; dest += 4; };
  3493.             break;
  3494.          case 0x2101:
  3495.          case 0x1E01:
  3496.             for (i = 0; i < span->end; i++) { GLint s = ((span->intTex[0]) >> 11) & info->smask; GLint t = ((span->intTex[1]) >> 11) & info->tmask; GLfixed sf = span->intTex[0] & 0x000007FF; GLfixed tf = span->intTex[1] & 0x000007FF; GLfixed si = 0x000007FF - sf; GLfixed ti = 0x000007FF - tf; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 3 * pos; const GLchan *tex10 = tex00 + info->tbytesline; const GLchan *tex01 = tex00 + 3; const GLchan *tex11 = tex10 + 3; (void) ti; (void) si; if (t == info->tmask) { tex10 -= info->tsize; tex11 -= info->tsize; } if (s == info->smask) { tex01 -= info->tbytesline; tex11 -= info->tbytesline; } sample[0] = (ti * (si * tex00[0] + sf * tex01[0]) + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * 11; sample[1] = (ti * (si * tex00[1] + sf * tex01[1]) + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * 11; sample[2] = (ti * (si * tex00[2] + sf * tex01[2]) + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * 11; sample[3] = 255;{ (dest)[0] = (sample)[0]; (dest)[1] = (sample)[1]; (dest)[2] = (sample)[2]; (dest)[3] = (sample)[3]; }; span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; span->intTex[0] += span->intTexStep[0]; span->intTex[1] += span->intTexStep[1]; dest += 4; };
  3497.             break;
  3498.          case 0x0BE2:
  3499.             for (i = 0; i < span->end; i++) { GLint s = ((span->intTex[0]) >> 11) & info->smask; GLint t = ((span->intTex[1]) >> 11) & info->tmask; GLfixed sf = span->intTex[0] & 0x000007FF; GLfixed tf = span->intTex[1] & 0x000007FF; GLfixed si = 0x000007FF - sf; GLfixed ti = 0x000007FF - tf; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 3 * pos; const GLchan *tex10 = tex00 + info->tbytesline; const GLchan *tex01 = tex00 + 3; const GLchan *tex11 = tex10 + 3; (void) ti; (void) si; if (t == info->tmask) { tex10 -= info->tsize; tex11 -= info->tsize; } if (s == info->smask) { tex01 -= info->tbytesline; tex11 -= info->tbytesline; } sample[0] = (ti * (si * tex00[0] + sf * tex01[0]) + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * 11; sample[1] = (ti * (si * tex00[1] + sf * tex01[1]) + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * 11; sample[2] = (ti * (si * tex00[2] + sf * tex01[2]) + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * 11; sample[3] = 255;dest[0] = ((255 - sample[0]) * span->red + (sample[0] + 1) * info->er) >> (11 + 8); dest[1] = ((255 - sample[1]) * span->green + (sample[1] + 1) * info->eg) >> (11 + 8); dest[2] = ((255 - sample[2]) * span->blue + (sample[2] + 1) * info->eb) >> (11 + 8); dest[3] = span->alpha * (sample[3] + 1) >> (11 + 8); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; span->intTex[0] += span->intTexStep[0]; span->intTex[1] += span->intTexStep[1]; dest += 4; };
  3500.             break;
  3501.          case 0x0104:
  3502.             for (i = 0; i < span->end; i++) { GLint s = ((span->intTex[0]) >> 11) & info->smask; GLint t = ((span->intTex[1]) >> 11) & info->tmask; GLfixed sf = span->intTex[0] & 0x000007FF; GLfixed tf = span->intTex[1] & 0x000007FF; GLfixed si = 0x000007FF - sf; GLfixed ti = 0x000007FF - tf; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 3 * pos; const GLchan *tex10 = tex00 + info->tbytesline; const GLchan *tex01 = tex00 + 3; const GLchan *tex11 = tex10 + 3; (void) ti; (void) si; if (t == info->tmask) { tex10 -= info->tsize; tex11 -= info->tsize; } if (s == info->smask) { tex01 -= info->tbytesline; tex11 -= info->tbytesline; } sample[0] = (ti * (si * tex00[0] + sf * tex01[0]) + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * 11; sample[1] = (ti * (si * tex00[1] + sf * tex01[1]) + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * 11; sample[2] = (ti * (si * tex00[2] + sf * tex01[2]) + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * 11; sample[3] = 255;{ GLint rSum = ((span->red) >> 11) + (GLint) sample[0]; GLint gSum = ((span->green) >> 11) + (GLint) sample[1]; GLint bSum = ((span->blue) >> 11) + (GLint) sample[2]; dest[0] = ( (rSum)<(255) ? (rSum) : (255) ); dest[1] = ( (gSum)<(255) ? (gSum) : (255) ); dest[2] = ( (bSum)<(255) ? (bSum) : (255) ); dest[3] = span->alpha * (sample[3] + 1) >> (11 + 8); }; span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; span->intTex[0] += span->intTexStep[0]; span->intTex[1] += span->intTexStep[1]; dest += 4; };
  3503.             break;
  3504.          default:
  3505.             _mesa_problem(ctx, "bad tex env mode (3) in SPAN_LINEAR");
  3506.             return;
  3507.          }
  3508.          break;
  3509.       case 0x1908:
  3510.          switch (info->envmode) {
  3511.          case 0x2100:
  3512.             for (i = 0; i < span->end; i++) { GLint s = ((span->intTex[0]) >> 11) & info->smask; GLint t = ((span->intTex[1]) >> 11) & info->tmask; GLfixed sf = span->intTex[0] & 0x000007FF; GLfixed tf = span->intTex[1] & 0x000007FF; GLfixed si = 0x000007FF - sf; GLfixed ti = 0x000007FF - tf; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; const GLchan *tex10 = tex00 + info->tbytesline; const GLchan *tex01 = tex00 + 4; const GLchan *tex11 = tex10 + 4; (void) ti; (void) si; if (t == info->tmask) { tex10 -= info->tsize; tex11 -= info->tsize; } if (s == info->smask) { tex01 -= info->tbytesline; tex11 -= info->tbytesline; } sample[0] = (ti * (si * tex00[0] + sf * tex01[0]) + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * 11; sample[1] = (ti * (si * tex00[1] + sf * tex01[1]) + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * 11; sample[2] = (ti * (si * tex00[2] + sf * tex01[2]) + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * 11; sample[3] = (ti * (si * tex00[3] + sf * tex01[3]) + tf * (si * tex10[3] + sf * tex11[3])) >> 2 * 11;dest[0] = span->red * (sample[0] + 1u) >> (11 + 8); dest[1] = span->green * (sample[1] + 1u) >> (11 + 8); dest[2] = span->blue * (sample[2] + 1u) >> (11 + 8); dest[3] = span->alpha * (sample[3] + 1u) >> (11 + 8); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; span->intTex[0] += span->intTexStep[0]; span->intTex[1] += span->intTexStep[1]; dest += 4; };
  3513.             break;
  3514.          case 0x2101:
  3515.             for (i = 0; i < span->end; i++) { GLint s = ((span->intTex[0]) >> 11) & info->smask; GLint t = ((span->intTex[1]) >> 11) & info->tmask; GLfixed sf = span->intTex[0] & 0x000007FF; GLfixed tf = span->intTex[1] & 0x000007FF; GLfixed si = 0x000007FF - sf; GLfixed ti = 0x000007FF - tf; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; const GLchan *tex10 = tex00 + info->tbytesline; const GLchan *tex01 = tex00 + 4; const GLchan *tex11 = tex10 + 4; (void) ti; (void) si; if (t == info->tmask) { tex10 -= info->tsize; tex11 -= info->tsize; } if (s == info->smask) { tex01 -= info->tbytesline; tex11 -= info->tbytesline; } sample[0] = (ti * (si * tex00[0] + sf * tex01[0]) + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * 11; sample[1] = (ti * (si * tex00[1] + sf * tex01[1]) + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * 11; sample[2] = (ti * (si * tex00[2] + sf * tex01[2]) + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * 11; sample[3] = (ti * (si * tex00[3] + sf * tex01[3]) + tf * (si * tex10[3] + sf * tex11[3])) >> 2 * 11;dest[0] = ((255 - sample[3]) * span->red + ((sample[3] + 1) * sample[0] << 11)) >> (11 + 8); dest[1] = ((255 - sample[3]) * span->green + ((sample[3] + 1) * sample[1] << 11)) >> (11 + 8); dest[2] = ((255 - sample[3]) * span->blue + ((sample[3] + 1) * sample[2] << 11)) >> (11 + 8); dest[3] = ((span->alpha) >> 11); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; span->intTex[0] += span->intTexStep[0]; span->intTex[1] += span->intTexStep[1]; dest += 4; };
  3516.             break;
  3517.          case 0x0BE2:
  3518.             for (i = 0; i < span->end; i++) { GLint s = ((span->intTex[0]) >> 11) & info->smask; GLint t = ((span->intTex[1]) >> 11) & info->tmask; GLfixed sf = span->intTex[0] & 0x000007FF; GLfixed tf = span->intTex[1] & 0x000007FF; GLfixed si = 0x000007FF - sf; GLfixed ti = 0x000007FF - tf; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; const GLchan *tex10 = tex00 + info->tbytesline; const GLchan *tex01 = tex00 + 4; const GLchan *tex11 = tex10 + 4; (void) ti; (void) si; if (t == info->tmask) { tex10 -= info->tsize; tex11 -= info->tsize; } if (s == info->smask) { tex01 -= info->tbytesline; tex11 -= info->tbytesline; } sample[0] = (ti * (si * tex00[0] + sf * tex01[0]) + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * 11; sample[1] = (ti * (si * tex00[1] + sf * tex01[1]) + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * 11; sample[2] = (ti * (si * tex00[2] + sf * tex01[2]) + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * 11; sample[3] = (ti * (si * tex00[3] + sf * tex01[3]) + tf * (si * tex10[3] + sf * tex11[3])) >> 2 * 11;dest[0] = ((255 - sample[0]) * span->red + (sample[0] + 1) * info->er) >> (11 + 8); dest[1] = ((255 - sample[1]) * span->green + (sample[1] + 1) * info->eg) >> (11 + 8); dest[2] = ((255 - sample[2]) * span->blue + (sample[2] + 1) * info->eb) >> (11 + 8); dest[3] = span->alpha * (sample[3] + 1) >> (11 + 8); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; span->intTex[0] += span->intTexStep[0]; span->intTex[1] += span->intTexStep[1]; dest += 4; };
  3519.             break;
  3520.          case 0x0104:
  3521.             for (i = 0; i < span->end; i++) { GLint s = ((span->intTex[0]) >> 11) & info->smask; GLint t = ((span->intTex[1]) >> 11) & info->tmask; GLfixed sf = span->intTex[0] & 0x000007FF; GLfixed tf = span->intTex[1] & 0x000007FF; GLfixed si = 0x000007FF - sf; GLfixed ti = 0x000007FF - tf; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; const GLchan *tex10 = tex00 + info->tbytesline; const GLchan *tex01 = tex00 + 4; const GLchan *tex11 = tex10 + 4; (void) ti; (void) si; if (t == info->tmask) { tex10 -= info->tsize; tex11 -= info->tsize; } if (s == info->smask) { tex01 -= info->tbytesline; tex11 -= info->tbytesline; } sample[0] = (ti * (si * tex00[0] + sf * tex01[0]) + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * 11; sample[1] = (ti * (si * tex00[1] + sf * tex01[1]) + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * 11; sample[2] = (ti * (si * tex00[2] + sf * tex01[2]) + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * 11; sample[3] = (ti * (si * tex00[3] + sf * tex01[3]) + tf * (si * tex10[3] + sf * tex11[3])) >> 2 * 11;{ GLint rSum = ((span->red) >> 11) + (GLint) sample[0]; GLint gSum = ((span->green) >> 11) + (GLint) sample[1]; GLint bSum = ((span->blue) >> 11) + (GLint) sample[2]; dest[0] = ( (rSum)<(255) ? (rSum) : (255) ); dest[1] = ( (gSum)<(255) ? (gSum) : (255) ); dest[2] = ( (bSum)<(255) ? (bSum) : (255) ); dest[3] = span->alpha * (sample[3] + 1) >> (11 + 8); }; span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; span->intTex[0] += span->intTexStep[0]; span->intTex[1] += span->intTexStep[1]; dest += 4; };
  3522.             break;
  3523.          case 0x1E01:
  3524.             for (i = 0; i < span->end; i++) { GLint s = ((span->intTex[0]) >> 11) & info->smask; GLint t = ((span->intTex[1]) >> 11) & info->tmask; GLfixed sf = span->intTex[0] & 0x000007FF; GLfixed tf = span->intTex[1] & 0x000007FF; GLfixed si = 0x000007FF - sf; GLfixed ti = 0x000007FF - tf; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; const GLchan *tex10 = tex00 + info->tbytesline; const GLchan *tex01 = tex00 + 4; const GLchan *tex11 = tex10 + 4; (void) ti; (void) si; if (t == info->tmask) { tex10 -= info->tsize; tex11 -= info->tsize; } if (s == info->smask) { tex01 -= info->tbytesline; tex11 -= info->tbytesline; } sample[0] = (ti * (si * tex00[0] + sf * tex01[0]) + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * 11; sample[1] = (ti * (si * tex00[1] + sf * tex01[1]) + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * 11; sample[2] = (ti * (si * tex00[2] + sf * tex01[2]) + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * 11; sample[3] = (ti * (si * tex00[3] + sf * tex01[3]) + tf * (si * tex10[3] + sf * tex11[3])) >> 2 * 11;{ (dest)[0] = (sample)[0]; (dest)[1] = (sample)[1]; (dest)[2] = (sample)[2]; (dest)[3] = (sample)[3]; }; span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; span->intTex[0] += span->intTexStep[0]; span->intTex[1] += span->intTexStep[1]; dest += 4; };
  3525.             break;
  3526.          default:
  3527.             _mesa_problem(ctx, "bad tex env mode (4) in SPAN_LINEAR");
  3528.             return;
  3529.          }
  3530.          break;
  3531.       }
  3532.       break;
  3533.    }
  3534.    span->interpMask &= ~0x001;
  3535.    ;
  3536.    _mesa_write_rgba_span(ctx, span);
  3537.  
  3538. }
  3539.  
  3540.  
  3541.  
  3542. /*
  3543.  * Render an RGB/RGBA textured triangle without perspective correction.
  3544.  */
  3545.  
  3546.  
  3547.  
  3548. /* $Id: s_tritemp.h,v 1.41 2002/11/13 16:51:02 brianp Exp $ */
  3549.  
  3550. /*
  3551.  * Mesa 3-D graphics library
  3552.  * Version:  5.1
  3553.  *
  3554.  * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  3555.  *
  3556.  * Permission is hereby granted, free of charge, to any person obtaining a
  3557.  * copy of this software and associated documentation files (the "Software"),
  3558.  * to deal in the Software without restriction, including without limitation
  3559.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  3560.  * and/or sell copies of the Software, and to permit persons to whom the
  3561.  * Software is furnished to do so, subject to the following conditions:
  3562.  *
  3563.  * The above copyright notice and this permission notice shall be included
  3564.  * in all copies or substantial portions of the Software.
  3565.  *
  3566.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  3567.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  3568.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  3569.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  3570.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  3571.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  3572.  */
  3573. /* $XFree86: xc/extras/Mesa/src/swrast/s_tritemp.h,v 1.2 2002/02/27 21:07:54 tsi Exp $ */
  3574.  
  3575. /*
  3576.  * Triangle Rasterizer Template
  3577.  *
  3578.  * This file is #include'd to generate custom triangle rasterizers.
  3579.  *
  3580.  * The following macros may be defined to indicate what auxillary information
  3581.  * must be interplated across the triangle:
  3582.  *    INTERP_Z        - if defined, interpolate Z values
  3583.  *    INTERP_FOG      - if defined, interpolate fog values
  3584.  *    INTERP_RGB      - if defined, interpolate RGB values
  3585.  *    INTERP_ALPHA    - if defined, interpolate Alpha values (req's INTERP_RGB)
  3586.  *    INTERP_SPEC     - if defined, interpolate specular RGB values
  3587.  *    INTERP_INDEX    - if defined, interpolate color index values
  3588.  *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
  3589.  *                         (fast, simple 2-D texture mapping)
  3590.  *    INTERP_TEX      - if defined, interpolate set 0 float STRQ texcoords
  3591.  *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
  3592.  *    INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
  3593.  *    INTERP_FLOAT_RGBA - if defined, interpolate RGBA with floating point
  3594.  *    INTERP_FLOAT_SPEC - if defined, interpolate specular with floating point
  3595.  *
  3596.  * When one can directly address pixels in the color buffer the following
  3597.  * macros can be defined and used to compute pixel addresses during
  3598.  * rasterization (see pRow):
  3599.  *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
  3600.  *    BYTES_PER_ROW       - number of bytes per row in the color buffer
  3601.  *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
  3602.  *                          Y==0 at bottom of screen and increases upward.
  3603.  *
  3604.  * Similarly, for direct depth buffer access, this type is used for depth
  3605.  * buffer addressing:
  3606.  *    DEPTH_TYPE          - either GLushort or GLuint
  3607.  *
  3608.  * Optionally, one may provide one-time setup code per triangle:
  3609.  *    SETUP_CODE    - code which is to be executed once per triangle
  3610.  *    CLEANUP_CODE    - code to execute at end of triangle
  3611.  *
  3612.  * The following macro MUST be defined:
  3613.  *    RENDER_SPAN(span) - code to write a span of pixels.
  3614.  *
  3615.  * This code was designed for the origin to be in the lower-left corner.
  3616.  *
  3617.  * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
  3618.  */
  3619.  
  3620.  
  3621. /*
  3622.  * This is a bit of a hack, but it's a centralized place to enable floating-
  3623.  * point color interpolation when GLchan is actually floating point.
  3624.  */
  3625.  
  3626.  
  3627.  
  3628. static void affine_textured_triangle(GLcontext *ctx, const SWvertex *v0,
  3629.                                  const SWvertex *v1,
  3630.                                  const SWvertex *v2 )
  3631. {
  3632.    typedef struct {
  3633.         const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
  3634.         GLfloat dx;    /* X(v1) - X(v0) */
  3635.         GLfloat dy;    /* Y(v1) - Y(v0) */
  3636.         GLfixed fdxdy; /* dx/dy in fixed-point */
  3637.         GLfixed fsx;   /* first sample point x coord */
  3638.         GLfixed fsy;
  3639.         GLfloat adjy;  /* adjust from v[0]->fy to fsy, scaled */
  3640.         GLint lines;   /* number of lines to be sampled on this edge */
  3641.         GLfixed fx0;   /* fixed pt X of lower endpoint */
  3642.    } EdgeT;
  3643.  
  3644.    const GLint depthBits = ctx->Visual.depthBits;
  3645.    const GLfloat maxDepth = ctx->DepthMaxF;
  3646.    EdgeT eMaj, eTop, eBot;
  3647.    GLfloat oneOverArea;
  3648.    const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
  3649.    float bf = ((SWcontext *)ctx->swrast_context)->_backface_sign;
  3650.    const GLint snapMask = ~((0x00000800 / (1 << 4)) - 1); /* for x/y coord snapping */
  3651.    GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
  3652.  
  3653.    struct sw_span span;
  3654.  
  3655.    do { (span).primitive = (0x0009); (span).interpMask = (0); (span).arrayMask = (0); (span).start = 0; (span).end = (0); (span).facing = 0; (span).array = ((SWcontext *)ctx->swrast_context)->SpanArrays; } while (0);
  3656.  
  3657.  
  3658.    printf("%s()\n", __FUNCTION__);
  3659.    /*
  3660.    printf("  %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
  3661.    printf("  %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
  3662.    printf("  %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
  3663.     */
  3664.  
  3665.    /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
  3666.     * And find the order of the 3 vertices along the Y axis.
  3667.     */
  3668.    {
  3669.       const GLfixed fy0 = (((int) ((((v0->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v0->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v0->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  3670.       const GLfixed fy1 = (((int) ((((v1->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v1->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v1->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  3671.       const GLfixed fy2 = (((int) ((((v2->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v2->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v2->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  3672.  
  3673.       if (fy0 <= fy1) {
  3674.          if (fy1 <= fy2) {
  3675.             /* y0 <= y1 <= y2 */
  3676.             vMin = v0;   vMid = v1;   vMax = v2;
  3677.             vMin_fy = fy0;  vMid_fy = fy1;  vMax_fy = fy2;
  3678.          }
  3679.          else if (fy2 <= fy0) {
  3680.             /* y2 <= y0 <= y1 */
  3681.             vMin = v2;   vMid = v0;   vMax = v1;
  3682.             vMin_fy = fy2;  vMid_fy = fy0;  vMax_fy = fy1;
  3683.          }
  3684.          else {
  3685.             /* y0 <= y2 <= y1 */
  3686.             vMin = v0;   vMid = v2;   vMax = v1;
  3687.             vMin_fy = fy0;  vMid_fy = fy2;  vMax_fy = fy1;
  3688.             bf = -bf;
  3689.          }
  3690.       }
  3691.       else {
  3692.          if (fy0 <= fy2) {
  3693.             /* y1 <= y0 <= y2 */
  3694.             vMin = v1;   vMid = v0;   vMax = v2;
  3695.             vMin_fy = fy1;  vMid_fy = fy0;  vMax_fy = fy2;
  3696.             bf = -bf;
  3697.          }
  3698.          else if (fy2 <= fy1) {
  3699.             /* y2 <= y1 <= y0 */
  3700.             vMin = v2;   vMid = v1;   vMax = v0;
  3701.             vMin_fy = fy2;  vMid_fy = fy1;  vMax_fy = fy0;
  3702.             bf = -bf;
  3703.          }
  3704.          else {
  3705.             /* y1 <= y2 <= y0 */
  3706.             vMin = v1;   vMid = v2;   vMax = v0;
  3707.             vMin_fy = fy1;  vMid_fy = fy2;  vMax_fy = fy0;
  3708.          }
  3709.       }
  3710.  
  3711.       /* fixed point X coords */
  3712.       vMin_fx = (((int) ((((vMin->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMin->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMin->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  3713.       vMid_fx = (((int) ((((vMid->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMid->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMid->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  3714.       vMax_fx = (((int) ((((vMax->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMax->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMax->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  3715.    }
  3716.  
  3717.    /* vertex/edge relationship */
  3718.    eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
  3719.    eTop.v0 = vMid;   eTop.v1 = vMax;
  3720.    eBot.v0 = vMin;   eBot.v1 = vMid;
  3721.  
  3722.    /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
  3723.    eMaj.dx = ((vMax_fx - vMin_fx) * (1.0F / 2048.0f));
  3724.    eMaj.dy = ((vMax_fy - vMin_fy) * (1.0F / 2048.0f));
  3725.    eTop.dx = ((vMax_fx - vMid_fx) * (1.0F / 2048.0f));
  3726.    eTop.dy = ((vMax_fy - vMid_fy) * (1.0F / 2048.0f));
  3727.    eBot.dx = ((vMid_fx - vMin_fx) * (1.0F / 2048.0f));
  3728.    eBot.dy = ((vMid_fy - vMin_fy) * (1.0F / 2048.0f));
  3729.  
  3730.    /* compute area, oneOverArea and perform backface culling */
  3731.    {
  3732.       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
  3733.  
  3734.       /* Do backface culling */
  3735.       if (area * bf < 0.0)
  3736.          return;
  3737.  
  3738.       if (IS_INF_OR_NAN(area) || area == 0.0F)
  3739.          return;
  3740.  
  3741.       oneOverArea = 1.0F / area;
  3742.    }
  3743.  
  3744.    ctx->OcclusionResult = 0x1;
  3745.    span.facing = ctx->_Facing; /* for 2-sided stencil test */
  3746.  
  3747.    /* Edge setup.  For a triangle strip these could be reused... */
  3748.    {
  3749.       eMaj.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  3750.       eMaj.lines = (((((vMax_fy - eMaj.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  3751.       if (eMaj.lines > 0) {
  3752.          GLfloat dxdy = eMaj.dx / eMaj.dy;
  3753.          eMaj.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  3754.          eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
  3755.          eMaj.fx0 = vMin_fx;
  3756.          eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy);
  3757.       }
  3758.       else {
  3759.          return;  /*CULLED*/
  3760.       }
  3761.  
  3762.       eTop.fsy = (((vMid_fy) + 0x00000800 - 1) & (~0x000007FF));
  3763.       eTop.lines = (((((vMax_fy - eTop.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  3764.       if (eTop.lines > 0) {
  3765.          GLfloat dxdy = eTop.dx / eTop.dy;
  3766.          eTop.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  3767.          eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
  3768.          eTop.fx0 = vMid_fx;
  3769.          eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy);
  3770.       }
  3771.  
  3772.       eBot.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  3773.       eBot.lines = (((((vMid_fy - eBot.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  3774.       if (eBot.lines > 0) {
  3775.          GLfloat dxdy = eBot.dx / eBot.dy;
  3776.          eBot.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  3777.          eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
  3778.          eBot.fx0 = vMin_fx;
  3779.          eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy);
  3780.       }
  3781.    }
  3782.  
  3783.    /*
  3784.     * Conceptually, we view a triangle as two subtriangles
  3785.     * separated by a perfectly horizontal line.  The edge that is
  3786.     * intersected by this line is one with maximal absolute dy; we
  3787.     * call it a ``major'' edge.  The other two edges are the
  3788.     * ``top'' edge (for the upper subtriangle) and the ``bottom''
  3789.     * edge (for the lower subtriangle).  If either of these two
  3790.     * edges is horizontal or very close to horizontal, the
  3791.     * corresponding subtriangle might cover zero sample points;
  3792.     * we take care to handle such cases, for performance as well
  3793.     * as correctness.
  3794.     *
  3795.     * By stepping rasterization parameters along the major edge,
  3796.     * we can avoid recomputing them at the discontinuity where
  3797.     * the top and bottom edges meet.  However, this forces us to
  3798.     * be able to scan both left-to-right and right-to-left.
  3799.     * Also, we must determine whether the major edge is at the
  3800.     * left or right side of the triangle.  We do this by
  3801.     * computing the magnitude of the cross-product of the major
  3802.     * and top edges.  Since this magnitude depends on the sine of
  3803.     * the angle between the two edges, its sign tells us whether
  3804.     * we turn to the left or to the right when travelling along
  3805.     * the major edge to the top edge, and from this we infer
  3806.     * whether the major edge is on the left or the right.
  3807.     *
  3808.     * Serendipitously, this cross-product magnitude is also a
  3809.     * value we need to compute the iteration parameter
  3810.     * derivatives for the triangle, and it can be used to perform
  3811.     * backface culling because its sign tells us whether the
  3812.     * triangle is clockwise or counterclockwise.  In this code we
  3813.     * refer to it as ``area'' because it's also proportional to
  3814.     * the pixel area of the triangle.
  3815.     */
  3816.  
  3817.    {
  3818.       GLint scan_from_left_to_right;  /* true if scanning left-to-right */
  3819.       GLfloat dzdx, dzdy;
  3820.       GLfloat dfogdy;
  3821.       GLfloat drdx, drdy;
  3822.       GLfloat dgdx, dgdy;
  3823.       GLfloat dbdx, dbdy;
  3824.       GLfloat dadx, dady;
  3825.       GLfloat dsdx, dsdy;
  3826.       GLfloat dtdx, dtdy;
  3827.  
  3828.       /*
  3829.        * Execute user-supplied setup code
  3830.        */
  3831.       struct affine_info info; struct gl_texture_unit *unit = ctx->Texture.Unit+0; struct gl_texture_object *obj = unit->Current2D; const GLint b = obj->BaseLevel; const GLfloat twidth = (GLfloat) obj->Image[b]->Width; const GLfloat theight = (GLfloat) obj->Image[b]->Height; info.texture = (const GLchan *) obj->Image[b]->Data; info.twidth_log2 = obj->Image[b]->WidthLog2; info.smask = obj->Image[b]->Width - 1; info.tmask = obj->Image[b]->Height - 1; info.format = obj->Image[b]->Format; info.filter = obj->MinFilter; info.envmode = unit->EnvMode; span.arrayMask |= 0x001; if (info.envmode == 0x0BE2) { info.er = (((int) ((((unit->EnvColor[0] * 255.0F) * 2048.0f) >= 0.0F) ? (((unit->EnvColor[0] * 255.0F) * 2048.0f) + 0.5F) : (((unit->EnvColor[0] * 255.0F) * 2048.0f) - 0.5F)))); info.eg = (((int) ((((unit->EnvColor[1] * 255.0F) * 2048.0f) >= 0.0F) ? (((unit->EnvColor[1] * 255.0F) * 2048.0f) + 0.5F) : (((unit->EnvColor[1] * 255.0F) * 2048.0f) - 0.5F)))); info.eb = (((int) ((((unit->EnvColor[2] * 255.0F) * 2048.0f) >= 0.0F) ? (((unit->EnvColor[2] * 255.0F) * 2048.0f) + 0.5F) : (((unit->EnvColor[2] * 255.0F) * 2048.0f) - 0.5F)))); info.ea = (((int) ((((unit->EnvColor[3] * 255.0F) * 2048.0f) >= 0.0F) ? (((unit->EnvColor[3] * 255.0F) * 2048.0f) + 0.5F) : (((unit->EnvColor[3] * 255.0F) * 2048.0f) - 0.5F)))); } if (!info.texture) { return; } switch (info.format) { case 0x1906: case 0x1909: case 0x8049: info.tbytesline = obj->Image[b]->Width; break; case 0x190A: info.tbytesline = obj->Image[b]->Width * 2; break; case 0x1907: info.tbytesline = obj->Image[b]->Width * 3; break; case 0x1908: info.tbytesline = obj->Image[b]->Width * 4; break; default: _mesa_problem(0, "Bad texture format in affine_texture_triangle"); return; } info.tsize = obj->Image[b]->Height * info.tbytesline;
  3832.  
  3833.       scan_from_left_to_right = (oneOverArea < 0.0F);
  3834.  
  3835.  
  3836.       /* compute d?/dx and d?/dy derivatives */
  3837.       span.interpMask |= 0x008;
  3838.       {
  3839.          GLfloat eMaj_dz, eBot_dz;
  3840.          eMaj_dz = vMax->win[2] - vMin->win[2];
  3841.          eBot_dz = vMid->win[2] - vMin->win[2];
  3842.          dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
  3843.          if (dzdx > maxDepth || dzdx < -maxDepth) {
  3844.             /* probably a sliver triangle */
  3845.             dzdx = 0.0;
  3846.             dzdy = 0.0;
  3847.          }
  3848.          else {
  3849.             dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
  3850.          }
  3851.          if (depthBits <= 16)
  3852.             span.zStep = (((int) ((((dzdx) * 2048.0f) >= 0.0F) ? (((dzdx) * 2048.0f) + 0.5F) : (((dzdx) * 2048.0f) - 0.5F))));
  3853.          else
  3854.             span.zStep = (GLint) dzdx;
  3855.       }
  3856.       span.interpMask |= 0x010;
  3857.       {
  3858.          const GLfloat eMaj_dfog = vMax->fog - vMin->fog;
  3859.          const GLfloat eBot_dfog = vMid->fog - vMin->fog;
  3860.          span.fogStep = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
  3861.          dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
  3862.       }
  3863.       span.interpMask |= 0x001;
  3864.       if (ctx->Light.ShadeModel == 0x1D01) {
  3865.          GLfloat eMaj_dr, eBot_dr;
  3866.          GLfloat eMaj_dg, eBot_dg;
  3867.          GLfloat eMaj_db, eBot_db;
  3868.          GLfloat eMaj_da, eBot_da;
  3869.          eMaj_dr = (GLfloat) ((GLint) vMax->color[0] -
  3870.                              (GLint) vMin->color[0]);
  3871.          eBot_dr = (GLfloat) ((GLint) vMid->color[0] -
  3872.                              (GLint) vMin->color[0]);
  3873.          drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
  3874.          span.redStep = (((int) ((((drdx) * 2048.0f) >= 0.0F) ? (((drdx) * 2048.0f) + 0.5F) : (((drdx) * 2048.0f) - 0.5F))));
  3875.          drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
  3876.          eMaj_dg = (GLfloat) ((GLint) vMax->color[1] -
  3877.                              (GLint) vMin->color[1]);
  3878.          eBot_dg = (GLfloat) ((GLint) vMid->color[1] -
  3879.                              (GLint) vMin->color[1]);
  3880.          dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
  3881.          span.greenStep = (((int) ((((dgdx) * 2048.0f) >= 0.0F) ? (((dgdx) * 2048.0f) + 0.5F) : (((dgdx) * 2048.0f) - 0.5F))));
  3882.          dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
  3883.          eMaj_db = (GLfloat) ((GLint) vMax->color[2] -
  3884.                              (GLint) vMin->color[2]);
  3885.          eBot_db = (GLfloat) ((GLint) vMid->color[2] -
  3886.                              (GLint) vMin->color[2]);
  3887.          dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
  3888.          span.blueStep = (((int) ((((dbdx) * 2048.0f) >= 0.0F) ? (((dbdx) * 2048.0f) + 0.5F) : (((dbdx) * 2048.0f) - 0.5F))));
  3889.          dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
  3890.          eMaj_da = (GLfloat) ((GLint) vMax->color[3] -
  3891.                              (GLint) vMin->color[3]);
  3892.          eBot_da = (GLfloat) ((GLint) vMid->color[3] -
  3893.                              (GLint) vMin->color[3]);
  3894.          dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
  3895.          span.alphaStep = (((int) ((((dadx) * 2048.0f) >= 0.0F) ? (((dadx) * 2048.0f) + 0.5F) : (((dadx) * 2048.0f) - 0.5F))));
  3896.          dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
  3897.       }
  3898.       else {
  3899.          ;
  3900.          span.interpMask |= 0x200;
  3901.          drdx = drdy = 0.0F;
  3902.          dgdx = dgdy = 0.0F;
  3903.          dbdx = dbdy = 0.0F;
  3904.          span.redStep = 0;
  3905.          span.greenStep = 0;
  3906.          span.blueStep = 0;
  3907.          dadx = dady = 0.0F;
  3908.          span.alphaStep = 0;
  3909.       }
  3910.       span.interpMask |= 0x040;
  3911.       {
  3912.          GLfloat eMaj_ds, eBot_ds;
  3913.          eMaj_ds = (vMax->texcoord[0][0] - vMin->texcoord[0][0]) * twidth;
  3914.          eBot_ds = (vMid->texcoord[0][0] - vMin->texcoord[0][0]) * twidth;
  3915.          dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
  3916.          span.intTexStep[0] = (((int) ((((dsdx) * 2048.0f) >= 0.0F) ? (((dsdx) * 2048.0f) + 0.5F) : (((dsdx) * 2048.0f) - 0.5F))));
  3917.          dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
  3918.       }
  3919.       {
  3920.          GLfloat eMaj_dt, eBot_dt;
  3921.          eMaj_dt = (vMax->texcoord[0][1] - vMin->texcoord[0][1]) * theight;
  3922.          eBot_dt = (vMid->texcoord[0][1] - vMin->texcoord[0][1]) * theight;
  3923.          dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
  3924.          span.intTexStep[1] = (((int) ((((dtdx) * 2048.0f) >= 0.0F) ? (((dtdx) * 2048.0f) + 0.5F) : (((dtdx) * 2048.0f) - 0.5F))));
  3925.          dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
  3926.       }
  3927.  
  3928.  
  3929.       /*
  3930.        * We always sample at pixel centers.  However, we avoid
  3931.        * explicit half-pixel offsets in this code by incorporating
  3932.        * the proper offset in each of x and y during the
  3933.        * transformation to window coordinates.
  3934.        *
  3935.        * We also apply the usual rasterization rules to prevent
  3936.        * cracks and overlaps.  A pixel is considered inside a
  3937.        * subtriangle if it meets all of four conditions: it is on or
  3938.        * to the right of the left edge, strictly to the left of the
  3939.        * right edge, on or below the top edge, and strictly above
  3940.        * the bottom edge.  (Some edges may be degenerate.)
  3941.        *
  3942.        * The following discussion assumes left-to-right scanning
  3943.        * (that is, the major edge is on the left); the right-to-left
  3944.        * case is a straightforward variation.
  3945.        *
  3946.        * We start by finding the half-integral y coordinate that is
  3947.        * at or below the top of the triangle.  This gives us the
  3948.        * first scan line that could possibly contain pixels that are
  3949.        * inside the triangle.
  3950.        *
  3951.        * Next we creep down the major edge until we reach that y,
  3952.        * and compute the corresponding x coordinate on the edge.
  3953.        * Then we find the half-integral x that lies on or just
  3954.        * inside the edge.  This is the first pixel that might lie in
  3955.        * the interior of the triangle.  (We won't know for sure
  3956.        * until we check the other edges.)
  3957.        *
  3958.        * As we rasterize the triangle, we'll step down the major
  3959.        * edge.  For each step in y, we'll move an integer number
  3960.        * of steps in x.  There are two possible x step sizes, which
  3961.        * we'll call the ``inner'' step (guaranteed to land on the
  3962.        * edge or inside it) and the ``outer'' step (guaranteed to
  3963.        * land on the edge or outside it).  The inner and outer steps
  3964.        * differ by one.  During rasterization we maintain an error
  3965.        * term that indicates our distance from the true edge, and
  3966.        * select either the inner step or the outer step, whichever
  3967.        * gets us to the first pixel that falls inside the triangle.
  3968.        *
  3969.        * All parameters (z, red, etc.) as well as the buffer
  3970.        * addresses for color and z have inner and outer step values,
  3971.        * so that we can increment them appropriately.  This method
  3972.        * eliminates the need to adjust parameters by creeping a
  3973.        * sub-pixel amount into the triangle at each scanline.
  3974.        */
  3975.  
  3976.       {
  3977.          int subTriangle;
  3978.          GLfixed fx;
  3979.          GLfixed fxLeftEdge = 0, fxRightEdge = 0;
  3980.          GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
  3981.          GLfixed fdxOuter;
  3982.          int idxOuter;
  3983.          float dxOuter;
  3984.          GLfixed fError = 0, fdError = 0;
  3985.          float adjx, adjy;
  3986.          GLfixed fy;
  3987.          GLushort *zRow = 0;
  3988.          int dZRowOuter = 0, dZRowInner;  /* offset in bytes */
  3989.          GLfixed fz = 0, fdzOuter = 0, fdzInner;
  3990.          GLfloat fogLeft = 0, dfogOuter = 0, dfogInner;
  3991.          GLfixed fr = 0, fdrOuter = 0, fdrInner;
  3992.          GLfixed fg = 0, fdgOuter = 0, fdgInner;
  3993.          GLfixed fb = 0, fdbOuter = 0, fdbInner;
  3994.          GLfixed fa = 0, fdaOuter = 0, fdaInner;
  3995.          GLfixed fs=0, fdsOuter=0, fdsInner;
  3996.          GLfixed ft=0, fdtOuter=0, fdtInner;
  3997.  
  3998.          for (subTriangle=0; subTriangle<=1; subTriangle++) {
  3999.             EdgeT *eLeft, *eRight;
  4000.             int setupLeft, setupRight;
  4001.             int lines;
  4002.  
  4003.             if (subTriangle==0) {
  4004.                /* bottom half */
  4005.                if (scan_from_left_to_right) {
  4006.                   eLeft = &eMaj;
  4007.                   eRight = &eBot;
  4008.                   lines = eRight->lines;
  4009.                   setupLeft = 1;
  4010.                   setupRight = 1;
  4011.                }
  4012.                else {
  4013.                   eLeft = &eBot;
  4014.                   eRight = &eMaj;
  4015.                   lines = eLeft->lines;
  4016.                   setupLeft = 1;
  4017.                   setupRight = 1;
  4018.                }
  4019.             }
  4020.             else {
  4021.                /* top half */
  4022.                if (scan_from_left_to_right) {
  4023.                   eLeft = &eMaj;
  4024.                   eRight = &eTop;
  4025.                   lines = eRight->lines;
  4026.                   setupLeft = 0;
  4027.                   setupRight = 1;
  4028.                }
  4029.                else {
  4030.                   eLeft = &eTop;
  4031.                   eRight = &eMaj;
  4032.                   lines = eLeft->lines;
  4033.                   setupLeft = 1;
  4034.                   setupRight = 0;
  4035.                }
  4036.                if (lines == 0)
  4037.                   return;
  4038.             }
  4039.  
  4040.             if (setupLeft && eLeft->lines > 0) {
  4041.                const SWvertex *vLower;
  4042.                GLfixed fsx = eLeft->fsx;
  4043.                fx = (((fsx) + 0x00000800 - 1) & (~0x000007FF));
  4044.                fError = fx - fsx - 0x00000800;
  4045.                fxLeftEdge = fsx - 1;
  4046.                fdxLeftEdge = eLeft->fdxdy;
  4047.                fdxOuter = ((fdxLeftEdge - 1) & (~0x000007FF));
  4048.                fdError = fdxOuter - fdxLeftEdge + 0x00000800;
  4049.                idxOuter = ((fdxOuter) >> 11);
  4050.                dxOuter = (float) idxOuter;
  4051.                (void) dxOuter;
  4052.  
  4053.                fy = eLeft->fsy;
  4054.                span.y = ((fy) >> 11);
  4055.  
  4056.                adjx = (float)(fx - eLeft->fx0);  /* SCALED! */
  4057.                adjy = eLeft->adjy;              /* SCALED! */
  4058.                vLower = eLeft->v0;
  4059.  
  4060.                /*
  4061.                 * Now we need the set of parameter (z, color, etc.) values at
  4062.                 * the point (fx, fy).  This gives us properly-sampled parameter
  4063.                 * values that we can step from pixel to pixel.  Furthermore,
  4064.                 * although we might have intermediate results that overflow
  4065.                 * the normal parameter range when we step temporarily outside
  4066.                 * the triangle, we shouldn't overflow or underflow for any
  4067.                 * pixel that's actually inside the triangle.
  4068.                 */
  4069.  
  4070.                {
  4071.                   GLfloat z0 = vLower->win[2];
  4072.                   if (depthBits <= 16) {
  4073.                      /* interpolate fixed-pt values */
  4074.                      GLfloat tmp = (z0 * 2048.0f +
  4075.                                     dzdx * adjx + dzdy * adjy) + 0x00000400;
  4076.                      if (tmp < 0xffffffff / 2)
  4077.                         fz = (GLfixed) tmp;
  4078.                      else
  4079.                         fz = 0xffffffff / 2;
  4080.                      fdzOuter = (((int) ((((dzdy + dxOuter * dzdx) * 2048.0f) >= 0.0F) ? (((dzdy + dxOuter * dzdx) * 2048.0f) + 0.5F) : (((dzdy + dxOuter * dzdx) * 2048.0f) - 0.5F))));
  4081.                   }
  4082.                   else {
  4083.                      /* interpolate depth values exactly */
  4084.                      fz = (GLint) (z0 + dzdx * ((adjx) * (1.0F / 2048.0f))
  4085.                                    + dzdy * ((adjy) * (1.0F / 2048.0f)));
  4086.                      fdzOuter = (GLint) (dzdy + dxOuter * dzdx);
  4087.                   }
  4088.                   zRow = (GLushort *)
  4089.                     _mesa_zbuffer_address(ctx, ((fxLeftEdge) >> 11), span.y);
  4090.                   dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(GLushort);
  4091.                }
  4092.                fogLeft = vLower->fog + (span.fogStep * adjx + dfogdy * adjy)
  4093.                                        * (1.0F/2048.0f);
  4094.                dfogOuter = dfogdy + dxOuter * span.fogStep;
  4095.                if (ctx->Light.ShadeModel == 0x1D01) {
  4096.                   fr = (GLfixed) (((vLower->color[0]) << 11)
  4097.                                    + drdx * adjx + drdy * adjy) + 0x00000400;
  4098.                   fdrOuter = (((int) ((((drdy + dxOuter * drdx) * 2048.0f) >= 0.0F) ? (((drdy + dxOuter * drdx) * 2048.0f) + 0.5F) : (((drdy + dxOuter * drdx) * 2048.0f) - 0.5F))));
  4099.                   fg = (GLfixed) (((vLower->color[1]) << 11)
  4100.                                    + dgdx * adjx + dgdy * adjy) + 0x00000400;
  4101.                   fdgOuter = (((int) ((((dgdy + dxOuter * dgdx) * 2048.0f) >= 0.0F) ? (((dgdy + dxOuter * dgdx) * 2048.0f) + 0.5F) : (((dgdy + dxOuter * dgdx) * 2048.0f) - 0.5F))));
  4102.                   fb = (GLfixed) (((vLower->color[2]) << 11)
  4103.                                     + dbdx * adjx + dbdy * adjy) + 0x00000400;
  4104.                   fdbOuter = (((int) ((((dbdy + dxOuter * dbdx) * 2048.0f) >= 0.0F) ? (((dbdy + dxOuter * dbdx) * 2048.0f) + 0.5F) : (((dbdy + dxOuter * dbdx) * 2048.0f) - 0.5F))));
  4105.                   fa = (GLfixed) (((vLower->color[3]) << 11)
  4106.                                    + dadx * adjx + dady * adjy) + 0x00000400;
  4107.                   fdaOuter = (((int) ((((dady + dxOuter * dadx) * 2048.0f) >= 0.0F) ? (((dady + dxOuter * dadx) * 2048.0f) + 0.5F) : (((dady + dxOuter * dadx) * 2048.0f) - 0.5F))));
  4108.                }
  4109.                else {
  4110.                   ;
  4111.                   fr = ((v2->color[0]) << 11);
  4112.                   fg = ((v2->color[1]) << 11);
  4113.                   fb = ((v2->color[2]) << 11);
  4114.                   fdrOuter = fdgOuter = fdbOuter = 0;
  4115.                   fa =  ((v2->color[3]) << 11);
  4116.                   fdaOuter = 0;
  4117.                }
  4118.                {
  4119.                   GLfloat s0, t0;
  4120.                   s0 = vLower->texcoord[0][0] * twidth;
  4121.                   fs = (GLfixed)(s0 * 2048.0f + dsdx * adjx
  4122.                                  + dsdy * adjy) + 0x00000400;
  4123.                   fdsOuter = (((int) ((((dsdy + dxOuter * dsdx) * 2048.0f) >= 0.0F) ? (((dsdy + dxOuter * dsdx) * 2048.0f) + 0.5F) : (((dsdy + dxOuter * dsdx) * 2048.0f) - 0.5F))));
  4124.  
  4125.                   t0 = vLower->texcoord[0][1] * theight;
  4126.                   ft = (GLfixed)(t0 * 2048.0f + dtdx * adjx
  4127.                                  + dtdy * adjy) + 0x00000400;
  4128.                   fdtOuter = (((int) ((((dtdy + dxOuter * dtdx) * 2048.0f) >= 0.0F) ? (((dtdy + dxOuter * dtdx) * 2048.0f) + 0.5F) : (((dtdy + dxOuter * dtdx) * 2048.0f) - 0.5F))));
  4129.                }
  4130.  
  4131.             } /*if setupLeft*/
  4132.  
  4133.  
  4134.             if (setupRight && eRight->lines>0) {
  4135.                fxRightEdge = eRight->fsx - 1;
  4136.                fdxRightEdge = eRight->fdxdy;
  4137.             }
  4138.  
  4139.             if (lines==0) {
  4140.                continue;
  4141.             }
  4142.  
  4143.  
  4144.             /* Rasterize setup */
  4145.             dZRowInner = dZRowOuter + sizeof(GLushort);
  4146.             fdzInner = fdzOuter + span.zStep;
  4147.             dfogInner = dfogOuter + span.fogStep;
  4148.             fdrInner = fdrOuter + span.redStep;
  4149.             fdgInner = fdgOuter + span.greenStep;
  4150.             fdbInner = fdbOuter + span.blueStep;
  4151.             fdaInner = fdaOuter + span.alphaStep;
  4152.             fdsInner = fdsOuter + span.intTexStep[0];
  4153.             fdtInner = fdtOuter + span.intTexStep[1];
  4154.  
  4155.             while (lines > 0) {
  4156.                /* initialize the span interpolants to the leftmost value */
  4157.                /* ff = fixed-pt fragment */
  4158.                const GLint right = ((fxRightEdge) >> 11);
  4159.  
  4160.                span.x = ((fxLeftEdge) >> 11);
  4161.  
  4162.                if (right <= span.x)
  4163.                   span.end = 0;
  4164.                else
  4165.                   span.end = right - span.x;
  4166.  
  4167.                span.z = fz;
  4168.                span.fog = fogLeft;
  4169.                span.red = fr;
  4170.                span.green = fg;
  4171.                span.blue = fb;
  4172.                span.alpha = fa;
  4173.                span.intTex[0] = fs;
  4174.                span.intTex[1] = ft;
  4175.  
  4176.  
  4177.  
  4178.                {
  4179.                   /* need this to accomodate round-off errors */
  4180.                   const GLint len = right - span.x - 1;
  4181.                   GLfixed ffrend = span.red + len * span.redStep;
  4182.                   GLfixed ffgend = span.green + len * span.greenStep;
  4183.                   GLfixed ffbend = span.blue + len * span.blueStep;
  4184.                   if (ffrend < 0) {
  4185.                      span.red -= ffrend;
  4186.                      if (span.red < 0)
  4187.                         span.red = 0;
  4188.                   }
  4189.                   if (ffgend < 0) {
  4190.                      span.green -= ffgend;
  4191.                      if (span.green < 0)
  4192.                         span.green = 0;
  4193.                   }
  4194.                   if (ffbend < 0) {
  4195.                      span.blue -= ffbend;
  4196.                      if (span.blue < 0)
  4197.                         span.blue = 0;
  4198.                   }
  4199.                }
  4200.                {
  4201.                   const GLint len = right - span.x - 1;
  4202.                   GLfixed ffaend = span.alpha + len * span.alphaStep;
  4203.                   if (ffaend < 0) {
  4204.                      span.alpha -= ffaend;
  4205.                      if (span.alpha < 0)
  4206.                         span.alpha = 0;
  4207.                   }
  4208.                }
  4209.  
  4210.                /* This is where we actually generate fragments */
  4211.                if (span.end > 0) {
  4212.                   affine_span(ctx, &span, &info);;
  4213.                }
  4214.  
  4215.                /*
  4216.                 * Advance to the next scan line.  Compute the
  4217.                 * new edge coordinates, and adjust the
  4218.                 * pixel-center x coordinate so that it stays
  4219.                 * on or inside the major edge.
  4220.                 */
  4221.                (span.y)++;
  4222.                lines--;
  4223.  
  4224.                fxLeftEdge += fdxLeftEdge;
  4225.                fxRightEdge += fdxRightEdge;
  4226.  
  4227.  
  4228.                fError += fdError;
  4229.                if (fError >= 0) {
  4230.                   fError -= 0x00000800;
  4231.                   zRow = (GLushort *) ((GLubyte *) zRow + dZRowOuter);
  4232.                   fz += fdzOuter;
  4233.                   fogLeft += dfogOuter;
  4234.                   fr += fdrOuter;
  4235.                   fg += fdgOuter;
  4236.                   fb += fdbOuter;
  4237.                   fa += fdaOuter;
  4238.                   fs += fdsOuter;
  4239.                   ft += fdtOuter;
  4240.                }
  4241.                else {
  4242.                   zRow = (GLushort *) ((GLubyte *) zRow + dZRowInner);
  4243.                   fz += fdzInner;
  4244.                   fogLeft += dfogInner;
  4245.                   fr += fdrInner;
  4246.                   fg += fdgInner;
  4247.                   fb += fdbInner;
  4248.                   fa += fdaInner;
  4249.                   fs += fdsInner;
  4250.                   ft += fdtInner;
  4251.                }
  4252.             } /*while lines>0*/
  4253.  
  4254.          } /* for subTriangle */
  4255.  
  4256.       }
  4257.    }
  4258. }
  4259.  
  4260.  
  4261.  
  4262.  
  4263.  
  4264. struct persp_info
  4265. {
  4266.    GLenum filter;
  4267.    GLenum format;
  4268.    GLenum envmode;
  4269.    GLint smask, tmask;
  4270.    GLint twidth_log2;
  4271.    const GLchan *texture;
  4272.    GLfixed er, eg, eb, ea;   /* texture env color */
  4273.    GLint tbytesline, tsize;
  4274. };
  4275.  
  4276.  
  4277. static inline void
  4278. fast_persp_span(GLcontext *ctx, struct sw_span *span,
  4279.                struct persp_info *info)
  4280. {
  4281.    GLchan sample[4];  /* the filtered texture sample */
  4282.  
  4283.   /* Instead of defining a function for each mode, a test is done
  4284.    * between the outer and inner loops. This is to reduce code size
  4285.    * and complexity. Observe that an optimizing compiler kills
  4286.    * unused variables (for instance tf,sf,ti,si in case of GL_NEAREST).
  4287.    */
  4288.  
  4289.  
  4290.    GLuint i;
  4291.    GLfloat tex_coord[3], tex_step[3];
  4292.    GLchan *dest = span->array->rgba[0];
  4293.  
  4294.    tex_coord[0] = span->tex[0][0]  * (info->smask + 1);
  4295.    tex_step[0] = span->texStepX[0][0] * (info->smask + 1);
  4296.    tex_coord[1] = span->tex[0][1] * (info->tmask + 1);
  4297.    tex_step[1] = span->texStepX[0][1] * (info->tmask + 1);
  4298.    /* span->tex[0][2] only if 3D-texturing, here only 2D */
  4299.    tex_coord[2] = span->tex[0][3];
  4300.    tex_step[2] = span->texStepX[0][3];
  4301.  
  4302.    switch (info->filter) {
  4303.    case 0x2600:
  4304.       switch (info->format) {
  4305.       case 0x1907:
  4306.          switch (info->envmode) {
  4307.          case 0x2100:
  4308.             for (i = 0; i < span->end; i++) { GLdouble invQ = tex_coord[2] ? (1.0 / tex_coord[2]) : 1.0; GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); GLint s = ifloor(s_tmp) & info->smask; GLint t = ifloor(t_tmp) & info->tmask; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 3 * pos; sample[0] = tex00[0]; sample[1] = tex00[1]; sample[2] = tex00[2]; sample[3] = 255;dest[0] = span->red * (sample[0] + 1u) >> (11 + 8); dest[1] = span->green * (sample[1] + 1u) >> (11 + 8); dest[2] = span->blue * (sample[2] + 1u) >> (11 + 8); dest[3] = span->alpha * (sample[3] + 1u) >> (11 + 8); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; tex_coord[0] += tex_step[0]; tex_coord[1] += tex_step[1]; tex_coord[2] += tex_step[2]; dest += 4; };
  4309.             break;
  4310.          case 0x2101:
  4311.          case 0x1E01:
  4312.             for (i = 0; i < span->end; i++) { GLdouble invQ = tex_coord[2] ? (1.0 / tex_coord[2]) : 1.0; GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); GLint s = ifloor(s_tmp) & info->smask; GLint t = ifloor(t_tmp) & info->tmask; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 3 * pos; sample[0] = tex00[0]; sample[1] = tex00[1]; sample[2] = tex00[2]; sample[3] = 255; dest[0] = sample[0]; dest[1] = sample[1]; dest[2] = sample[2]; dest[3] = ((span->alpha) >> 11);; span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; tex_coord[0] += tex_step[0]; tex_coord[1] += tex_step[1]; tex_coord[2] += tex_step[2]; dest += 4; };
  4313.             break;
  4314.          case 0x0BE2:
  4315.             for (i = 0; i < span->end; i++) { GLdouble invQ = tex_coord[2] ? (1.0 / tex_coord[2]) : 1.0; GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); GLint s = ifloor(s_tmp) & info->smask; GLint t = ifloor(t_tmp) & info->tmask; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 3 * pos; sample[0] = tex00[0]; sample[1] = tex00[1]; sample[2] = tex00[2]; sample[3] = 255;dest[0] = ((255 - sample[0]) * span->red + (sample[0] + 1) * info->er) >> (11 + 8); dest[1] = ((255 - sample[1]) * span->green + (sample[1] + 1) * info->eg) >> (11 + 8); dest[2] = ((255 - sample[2]) * span->blue + (sample[2] + 1) * info->eb) >> (11 + 8); dest[3] = span->alpha * (sample[3] + 1) >> (11 + 8); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; tex_coord[0] += tex_step[0]; tex_coord[1] += tex_step[1]; tex_coord[2] += tex_step[2]; dest += 4; };
  4316.             break;
  4317.          case 0x0104:
  4318.             for (i = 0; i < span->end; i++) { GLdouble invQ = tex_coord[2] ? (1.0 / tex_coord[2]) : 1.0; GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); GLint s = ifloor(s_tmp) & info->smask; GLint t = ifloor(t_tmp) & info->tmask; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 3 * pos; sample[0] = tex00[0]; sample[1] = tex00[1]; sample[2] = tex00[2]; sample[3] = 255;{ GLint rSum = ((span->red) >> 11) + (GLint) sample[0]; GLint gSum = ((span->green) >> 11) + (GLint) sample[1]; GLint bSum = ((span->blue) >> 11) + (GLint) sample[2]; dest[0] = ( (rSum)<(255) ? (rSum) : (255) ); dest[1] = ( (gSum)<(255) ? (gSum) : (255) ); dest[2] = ( (bSum)<(255) ? (bSum) : (255) ); dest[3] = span->alpha * (sample[3] + 1) >> (11 + 8); }; span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; tex_coord[0] += tex_step[0]; tex_coord[1] += tex_step[1]; tex_coord[2] += tex_step[2]; dest += 4; };
  4319.             break;
  4320.          default:
  4321.             _mesa_problem(ctx, "bad tex env mode (5) in SPAN_LINEAR");
  4322.             return;
  4323.          }
  4324.          break;
  4325.       case 0x1908:
  4326.          switch(info->envmode) {
  4327.          case 0x2100:
  4328.             for (i = 0; i < span->end; i++) { GLdouble invQ = tex_coord[2] ? (1.0 / tex_coord[2]) : 1.0; GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); GLint s = ifloor(s_tmp) & info->smask; GLint t = ifloor(t_tmp) & info->tmask; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; { (sample)[0] = (tex00)[0]; (sample)[1] = (tex00)[1]; (sample)[2] = (tex00)[2]; (sample)[3] = (tex00)[3]; };dest[0] = span->red * (sample[0] + 1u) >> (11 + 8); dest[1] = span->green * (sample[1] + 1u) >> (11 + 8); dest[2] = span->blue * (sample[2] + 1u) >> (11 + 8); dest[3] = span->alpha * (sample[3] + 1u) >> (11 + 8); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; tex_coord[0] += tex_step[0]; tex_coord[1] += tex_step[1]; tex_coord[2] += tex_step[2]; dest += 4; };
  4329.             break;
  4330.          case 0x2101:
  4331.             for (i = 0; i < span->end; i++) { GLdouble invQ = tex_coord[2] ? (1.0 / tex_coord[2]) : 1.0; GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); GLint s = ifloor(s_tmp) & info->smask; GLint t = ifloor(t_tmp) & info->tmask; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; { (sample)[0] = (tex00)[0]; (sample)[1] = (tex00)[1]; (sample)[2] = (tex00)[2]; (sample)[3] = (tex00)[3]; };dest[0] = ((255 - sample[3]) * span->red + ((sample[3] + 1) * sample[0] << 11)) >> (11 + 8); dest[1] = ((255 - sample[3]) * span->green + ((sample[3] + 1) * sample[1] << 11)) >> (11 + 8); dest[2] = ((255 - sample[3]) * span->blue + ((sample[3] + 1) * sample[2] << 11)) >> (11 + 8); dest[3] = ((span->alpha) >> 11); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; tex_coord[0] += tex_step[0]; tex_coord[1] += tex_step[1]; tex_coord[2] += tex_step[2]; dest += 4; };
  4332.             break;
  4333.          case 0x0BE2:
  4334.             for (i = 0; i < span->end; i++) { GLdouble invQ = tex_coord[2] ? (1.0 / tex_coord[2]) : 1.0; GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); GLint s = ifloor(s_tmp) & info->smask; GLint t = ifloor(t_tmp) & info->tmask; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; { (sample)[0] = (tex00)[0]; (sample)[1] = (tex00)[1]; (sample)[2] = (tex00)[2]; (sample)[3] = (tex00)[3]; };dest[0] = ((255 - sample[0]) * span->red + (sample[0] + 1) * info->er) >> (11 + 8); dest[1] = ((255 - sample[1]) * span->green + (sample[1] + 1) * info->eg) >> (11 + 8); dest[2] = ((255 - sample[2]) * span->blue + (sample[2] + 1) * info->eb) >> (11 + 8); dest[3] = span->alpha * (sample[3] + 1) >> (11 + 8); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; tex_coord[0] += tex_step[0]; tex_coord[1] += tex_step[1]; tex_coord[2] += tex_step[2]; dest += 4; };
  4335.             break;
  4336.          case 0x0104:
  4337.             for (i = 0; i < span->end; i++) { GLdouble invQ = tex_coord[2] ? (1.0 / tex_coord[2]) : 1.0; GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); GLint s = ifloor(s_tmp) & info->smask; GLint t = ifloor(t_tmp) & info->tmask; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; { (sample)[0] = (tex00)[0]; (sample)[1] = (tex00)[1]; (sample)[2] = (tex00)[2]; (sample)[3] = (tex00)[3]; };{ GLint rSum = ((span->red) >> 11) + (GLint) sample[0]; GLint gSum = ((span->green) >> 11) + (GLint) sample[1]; GLint bSum = ((span->blue) >> 11) + (GLint) sample[2]; dest[0] = ( (rSum)<(255) ? (rSum) : (255) ); dest[1] = ( (gSum)<(255) ? (gSum) : (255) ); dest[2] = ( (bSum)<(255) ? (bSum) : (255) ); dest[3] = span->alpha * (sample[3] + 1) >> (11 + 8); }; span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; tex_coord[0] += tex_step[0]; tex_coord[1] += tex_step[1]; tex_coord[2] += tex_step[2]; dest += 4; };
  4338.             break;
  4339.          case 0x1E01:
  4340.             for (i = 0; i < span->end; i++) { GLdouble invQ = tex_coord[2] ? (1.0 / tex_coord[2]) : 1.0; GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); GLint s = ifloor(s_tmp) & info->smask; GLint t = ifloor(t_tmp) & info->tmask; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; { (dest)[0] = (tex00)[0]; (dest)[1] = (tex00)[1]; (dest)[2] = (tex00)[2]; (dest)[3] = (tex00)[3]; }; span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; tex_coord[0] += tex_step[0]; tex_coord[1] += tex_step[1]; tex_coord[2] += tex_step[2]; dest += 4; };
  4341.             break;
  4342.          default:
  4343.             _mesa_problem(ctx, "bad tex env mode (6) in SPAN_LINEAR");
  4344.             return;
  4345.          }
  4346.          break;
  4347.       }
  4348.       break;
  4349.  
  4350.    case 0x2601:
  4351.       switch (info->format) {
  4352.       case 0x1907:
  4353.          switch (info->envmode) {
  4354.          case 0x2100:
  4355.             for (i = 0; i < span->end; i++) { GLdouble invQ = tex_coord[2] ? (1.0 / tex_coord[2]) : 1.0; GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); GLfixed s_fix = (((int) ((((s_tmp) * 2048.0f) >= 0.0F) ? (((s_tmp) * 2048.0f) + 0.5F) : (((s_tmp) * 2048.0f) - 0.5F)))) - 0x00000400; GLfixed t_fix = (((int) ((((t_tmp) * 2048.0f) >= 0.0F) ? (((t_tmp) * 2048.0f) + 0.5F) : (((t_tmp) * 2048.0f) - 0.5F)))) - 0x00000400; GLint s = ((((s_fix) & (~0x000007FF))) >> 11) & info->smask; GLint t = ((((t_fix) & (~0x000007FF))) >> 11) & info->tmask; GLfixed sf = s_fix & 0x000007FF; GLfixed tf = t_fix & 0x000007FF; GLfixed si = 0x000007FF - sf; GLfixed ti = 0x000007FF - tf; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 3 * pos; const GLchan *tex10 = tex00 + info->tbytesline; const GLchan *tex01 = tex00 + 3; const GLchan *tex11 = tex10 + 3; (void) ti; (void) si; if (t == info->tmask) { tex10 -= info->tsize; tex11 -= info->tsize; } if (s == info->smask) { tex01 -= info->tbytesline; tex11 -= info->tbytesline; } sample[0] = (ti * (si * tex00[0] + sf * tex01[0]) + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * 11; sample[1] = (ti * (si * tex00[1] + sf * tex01[1]) + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * 11; sample[2] = (ti * (si * tex00[2] + sf * tex01[2]) + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * 11; sample[3] = 255;dest[0] = span->red * (sample[0] + 1u) >> (11 + 8); dest[1] = span->green * (sample[1] + 1u) >> (11 + 8); dest[2] = span->blue * (sample[2] + 1u) >> (11 + 8); dest[3] = span->alpha * (sample[3] + 1u) >> (11 + 8); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; tex_coord[0] += tex_step[0]; tex_coord[1] += tex_step[1]; tex_coord[2] += tex_step[2]; dest += 4; };
  4356.             break;
  4357.          case 0x2101:
  4358.          case 0x1E01:
  4359.             for (i = 0; i < span->end; i++) { GLdouble invQ = tex_coord[2] ? (1.0 / tex_coord[2]) : 1.0; GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); GLfixed s_fix = (((int) ((((s_tmp) * 2048.0f) >= 0.0F) ? (((s_tmp) * 2048.0f) + 0.5F) : (((s_tmp) * 2048.0f) - 0.5F)))) - 0x00000400; GLfixed t_fix = (((int) ((((t_tmp) * 2048.0f) >= 0.0F) ? (((t_tmp) * 2048.0f) + 0.5F) : (((t_tmp) * 2048.0f) - 0.5F)))) - 0x00000400; GLint s = ((((s_fix) & (~0x000007FF))) >> 11) & info->smask; GLint t = ((((t_fix) & (~0x000007FF))) >> 11) & info->tmask; GLfixed sf = s_fix & 0x000007FF; GLfixed tf = t_fix & 0x000007FF; GLfixed si = 0x000007FF - sf; GLfixed ti = 0x000007FF - tf; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 3 * pos; const GLchan *tex10 = tex00 + info->tbytesline; const GLchan *tex01 = tex00 + 3; const GLchan *tex11 = tex10 + 3; (void) ti; (void) si; if (t == info->tmask) { tex10 -= info->tsize; tex11 -= info->tsize; } if (s == info->smask) { tex01 -= info->tbytesline; tex11 -= info->tbytesline; } sample[0] = (ti * (si * tex00[0] + sf * tex01[0]) + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * 11; sample[1] = (ti * (si * tex00[1] + sf * tex01[1]) + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * 11; sample[2] = (ti * (si * tex00[2] + sf * tex01[2]) + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * 11; sample[3] = 255;{ (dest)[0] = (sample)[0]; (dest)[1] = (sample)[1]; (dest)[2] = (sample)[2]; (dest)[3] = (sample)[3]; }; span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; tex_coord[0] += tex_step[0]; tex_coord[1] += tex_step[1]; tex_coord[2] += tex_step[2]; dest += 4; };
  4360.             break;
  4361.          case 0x0BE2:
  4362.             for (i = 0; i < span->end; i++) { GLdouble invQ = tex_coord[2] ? (1.0 / tex_coord[2]) : 1.0; GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); GLfixed s_fix = (((int) ((((s_tmp) * 2048.0f) >= 0.0F) ? (((s_tmp) * 2048.0f) + 0.5F) : (((s_tmp) * 2048.0f) - 0.5F)))) - 0x00000400; GLfixed t_fix = (((int) ((((t_tmp) * 2048.0f) >= 0.0F) ? (((t_tmp) * 2048.0f) + 0.5F) : (((t_tmp) * 2048.0f) - 0.5F)))) - 0x00000400; GLint s = ((((s_fix) & (~0x000007FF))) >> 11) & info->smask; GLint t = ((((t_fix) & (~0x000007FF))) >> 11) & info->tmask; GLfixed sf = s_fix & 0x000007FF; GLfixed tf = t_fix & 0x000007FF; GLfixed si = 0x000007FF - sf; GLfixed ti = 0x000007FF - tf; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 3 * pos; const GLchan *tex10 = tex00 + info->tbytesline; const GLchan *tex01 = tex00 + 3; const GLchan *tex11 = tex10 + 3; (void) ti; (void) si; if (t == info->tmask) { tex10 -= info->tsize; tex11 -= info->tsize; } if (s == info->smask) { tex01 -= info->tbytesline; tex11 -= info->tbytesline; } sample[0] = (ti * (si * tex00[0] + sf * tex01[0]) + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * 11; sample[1] = (ti * (si * tex00[1] + sf * tex01[1]) + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * 11; sample[2] = (ti * (si * tex00[2] + sf * tex01[2]) + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * 11; sample[3] = 255;dest[0] = ((255 - sample[0]) * span->red + (sample[0] + 1) * info->er) >> (11 + 8); dest[1] = ((255 - sample[1]) * span->green + (sample[1] + 1) * info->eg) >> (11 + 8); dest[2] = ((255 - sample[2]) * span->blue + (sample[2] + 1) * info->eb) >> (11 + 8); dest[3] = span->alpha * (sample[3] + 1) >> (11 + 8); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; tex_coord[0] += tex_step[0]; tex_coord[1] += tex_step[1]; tex_coord[2] += tex_step[2]; dest += 4; };
  4363.             break;
  4364.          case 0x0104:
  4365.             for (i = 0; i < span->end; i++) { GLdouble invQ = tex_coord[2] ? (1.0 / tex_coord[2]) : 1.0; GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); GLfixed s_fix = (((int) ((((s_tmp) * 2048.0f) >= 0.0F) ? (((s_tmp) * 2048.0f) + 0.5F) : (((s_tmp) * 2048.0f) - 0.5F)))) - 0x00000400; GLfixed t_fix = (((int) ((((t_tmp) * 2048.0f) >= 0.0F) ? (((t_tmp) * 2048.0f) + 0.5F) : (((t_tmp) * 2048.0f) - 0.5F)))) - 0x00000400; GLint s = ((((s_fix) & (~0x000007FF))) >> 11) & info->smask; GLint t = ((((t_fix) & (~0x000007FF))) >> 11) & info->tmask; GLfixed sf = s_fix & 0x000007FF; GLfixed tf = t_fix & 0x000007FF; GLfixed si = 0x000007FF - sf; GLfixed ti = 0x000007FF - tf; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 3 * pos; const GLchan *tex10 = tex00 + info->tbytesline; const GLchan *tex01 = tex00 + 3; const GLchan *tex11 = tex10 + 3; (void) ti; (void) si; if (t == info->tmask) { tex10 -= info->tsize; tex11 -= info->tsize; } if (s == info->smask) { tex01 -= info->tbytesline; tex11 -= info->tbytesline; } sample[0] = (ti * (si * tex00[0] + sf * tex01[0]) + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * 11; sample[1] = (ti * (si * tex00[1] + sf * tex01[1]) + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * 11; sample[2] = (ti * (si * tex00[2] + sf * tex01[2]) + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * 11; sample[3] = 255;{ GLint rSum = ((span->red) >> 11) + (GLint) sample[0]; GLint gSum = ((span->green) >> 11) + (GLint) sample[1]; GLint bSum = ((span->blue) >> 11) + (GLint) sample[2]; dest[0] = ( (rSum)<(255) ? (rSum) : (255) ); dest[1] = ( (gSum)<(255) ? (gSum) : (255) ); dest[2] = ( (bSum)<(255) ? (bSum) : (255) ); dest[3] = span->alpha * (sample[3] + 1) >> (11 + 8); }; span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; tex_coord[0] += tex_step[0]; tex_coord[1] += tex_step[1]; tex_coord[2] += tex_step[2]; dest += 4; };
  4366.             break;
  4367.          default:
  4368.             _mesa_problem(ctx, "bad tex env mode (7) in SPAN_LINEAR");
  4369.             return;
  4370.          }
  4371.          break;
  4372.       case 0x1908:
  4373.          switch (info->envmode) {
  4374.          case 0x2100:
  4375.             for (i = 0; i < span->end; i++) { GLdouble invQ = tex_coord[2] ? (1.0 / tex_coord[2]) : 1.0; GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); GLfixed s_fix = (((int) ((((s_tmp) * 2048.0f) >= 0.0F) ? (((s_tmp) * 2048.0f) + 0.5F) : (((s_tmp) * 2048.0f) - 0.5F)))) - 0x00000400; GLfixed t_fix = (((int) ((((t_tmp) * 2048.0f) >= 0.0F) ? (((t_tmp) * 2048.0f) + 0.5F) : (((t_tmp) * 2048.0f) - 0.5F)))) - 0x00000400; GLint s = ((((s_fix) & (~0x000007FF))) >> 11) & info->smask; GLint t = ((((t_fix) & (~0x000007FF))) >> 11) & info->tmask; GLfixed sf = s_fix & 0x000007FF; GLfixed tf = t_fix & 0x000007FF; GLfixed si = 0x000007FF - sf; GLfixed ti = 0x000007FF - tf; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; const GLchan *tex10 = tex00 + info->tbytesline; const GLchan *tex01 = tex00 + 4; const GLchan *tex11 = tex10 + 4; (void) ti; (void) si; if (t == info->tmask) { tex10 -= info->tsize; tex11 -= info->tsize; } if (s == info->smask) { tex01 -= info->tbytesline; tex11 -= info->tbytesline; } sample[0] = (ti * (si * tex00[0] + sf * tex01[0]) + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * 11; sample[1] = (ti * (si * tex00[1] + sf * tex01[1]) + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * 11; sample[2] = (ti * (si * tex00[2] + sf * tex01[2]) + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * 11; sample[3] = (ti * (si * tex00[3] + sf * tex01[3]) + tf * (si * tex10[3] + sf * tex11[3])) >> 2 * 11;dest[0] = span->red * (sample[0] + 1u) >> (11 + 8); dest[1] = span->green * (sample[1] + 1u) >> (11 + 8); dest[2] = span->blue * (sample[2] + 1u) >> (11 + 8); dest[3] = span->alpha * (sample[3] + 1u) >> (11 + 8); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; tex_coord[0] += tex_step[0]; tex_coord[1] += tex_step[1]; tex_coord[2] += tex_step[2]; dest += 4; };
  4376.             break;
  4377.          case 0x2101:
  4378.             for (i = 0; i < span->end; i++) { GLdouble invQ = tex_coord[2] ? (1.0 / tex_coord[2]) : 1.0; GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); GLfixed s_fix = (((int) ((((s_tmp) * 2048.0f) >= 0.0F) ? (((s_tmp) * 2048.0f) + 0.5F) : (((s_tmp) * 2048.0f) - 0.5F)))) - 0x00000400; GLfixed t_fix = (((int) ((((t_tmp) * 2048.0f) >= 0.0F) ? (((t_tmp) * 2048.0f) + 0.5F) : (((t_tmp) * 2048.0f) - 0.5F)))) - 0x00000400; GLint s = ((((s_fix) & (~0x000007FF))) >> 11) & info->smask; GLint t = ((((t_fix) & (~0x000007FF))) >> 11) & info->tmask; GLfixed sf = s_fix & 0x000007FF; GLfixed tf = t_fix & 0x000007FF; GLfixed si = 0x000007FF - sf; GLfixed ti = 0x000007FF - tf; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; const GLchan *tex10 = tex00 + info->tbytesline; const GLchan *tex01 = tex00 + 4; const GLchan *tex11 = tex10 + 4; (void) ti; (void) si; if (t == info->tmask) { tex10 -= info->tsize; tex11 -= info->tsize; } if (s == info->smask) { tex01 -= info->tbytesline; tex11 -= info->tbytesline; } sample[0] = (ti * (si * tex00[0] + sf * tex01[0]) + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * 11; sample[1] = (ti * (si * tex00[1] + sf * tex01[1]) + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * 11; sample[2] = (ti * (si * tex00[2] + sf * tex01[2]) + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * 11; sample[3] = (ti * (si * tex00[3] + sf * tex01[3]) + tf * (si * tex10[3] + sf * tex11[3])) >> 2 * 11;dest[0] = ((255 - sample[3]) * span->red + ((sample[3] + 1) * sample[0] << 11)) >> (11 + 8); dest[1] = ((255 - sample[3]) * span->green + ((sample[3] + 1) * sample[1] << 11)) >> (11 + 8); dest[2] = ((255 - sample[3]) * span->blue + ((sample[3] + 1) * sample[2] << 11)) >> (11 + 8); dest[3] = ((span->alpha) >> 11); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; tex_coord[0] += tex_step[0]; tex_coord[1] += tex_step[1]; tex_coord[2] += tex_step[2]; dest += 4; };
  4379.             break;
  4380.          case 0x0BE2:
  4381.             for (i = 0; i < span->end; i++) { GLdouble invQ = tex_coord[2] ? (1.0 / tex_coord[2]) : 1.0; GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); GLfixed s_fix = (((int) ((((s_tmp) * 2048.0f) >= 0.0F) ? (((s_tmp) * 2048.0f) + 0.5F) : (((s_tmp) * 2048.0f) - 0.5F)))) - 0x00000400; GLfixed t_fix = (((int) ((((t_tmp) * 2048.0f) >= 0.0F) ? (((t_tmp) * 2048.0f) + 0.5F) : (((t_tmp) * 2048.0f) - 0.5F)))) - 0x00000400; GLint s = ((((s_fix) & (~0x000007FF))) >> 11) & info->smask; GLint t = ((((t_fix) & (~0x000007FF))) >> 11) & info->tmask; GLfixed sf = s_fix & 0x000007FF; GLfixed tf = t_fix & 0x000007FF; GLfixed si = 0x000007FF - sf; GLfixed ti = 0x000007FF - tf; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; const GLchan *tex10 = tex00 + info->tbytesline; const GLchan *tex01 = tex00 + 4; const GLchan *tex11 = tex10 + 4; (void) ti; (void) si; if (t == info->tmask) { tex10 -= info->tsize; tex11 -= info->tsize; } if (s == info->smask) { tex01 -= info->tbytesline; tex11 -= info->tbytesline; } sample[0] = (ti * (si * tex00[0] + sf * tex01[0]) + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * 11; sample[1] = (ti * (si * tex00[1] + sf * tex01[1]) + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * 11; sample[2] = (ti * (si * tex00[2] + sf * tex01[2]) + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * 11; sample[3] = (ti * (si * tex00[3] + sf * tex01[3]) + tf * (si * tex10[3] + sf * tex11[3])) >> 2 * 11;dest[0] = ((255 - sample[0]) * span->red + (sample[0] + 1) * info->er) >> (11 + 8); dest[1] = ((255 - sample[1]) * span->green + (sample[1] + 1) * info->eg) >> (11 + 8); dest[2] = ((255 - sample[2]) * span->blue + (sample[2] + 1) * info->eb) >> (11 + 8); dest[3] = span->alpha * (sample[3] + 1) >> (11 + 8); span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; tex_coord[0] += tex_step[0]; tex_coord[1] += tex_step[1]; tex_coord[2] += tex_step[2]; dest += 4; };
  4382.             break;
  4383.          case 0x0104:
  4384.             for (i = 0; i < span->end; i++) { GLdouble invQ = tex_coord[2] ? (1.0 / tex_coord[2]) : 1.0; GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); GLfixed s_fix = (((int) ((((s_tmp) * 2048.0f) >= 0.0F) ? (((s_tmp) * 2048.0f) + 0.5F) : (((s_tmp) * 2048.0f) - 0.5F)))) - 0x00000400; GLfixed t_fix = (((int) ((((t_tmp) * 2048.0f) >= 0.0F) ? (((t_tmp) * 2048.0f) + 0.5F) : (((t_tmp) * 2048.0f) - 0.5F)))) - 0x00000400; GLint s = ((((s_fix) & (~0x000007FF))) >> 11) & info->smask; GLint t = ((((t_fix) & (~0x000007FF))) >> 11) & info->tmask; GLfixed sf = s_fix & 0x000007FF; GLfixed tf = t_fix & 0x000007FF; GLfixed si = 0x000007FF - sf; GLfixed ti = 0x000007FF - tf; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; const GLchan *tex10 = tex00 + info->tbytesline; const GLchan *tex01 = tex00 + 4; const GLchan *tex11 = tex10 + 4; (void) ti; (void) si; if (t == info->tmask) { tex10 -= info->tsize; tex11 -= info->tsize; } if (s == info->smask) { tex01 -= info->tbytesline; tex11 -= info->tbytesline; } sample[0] = (ti * (si * tex00[0] + sf * tex01[0]) + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * 11; sample[1] = (ti * (si * tex00[1] + sf * tex01[1]) + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * 11; sample[2] = (ti * (si * tex00[2] + sf * tex01[2]) + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * 11; sample[3] = (ti * (si * tex00[3] + sf * tex01[3]) + tf * (si * tex10[3] + sf * tex11[3])) >> 2 * 11;{ GLint rSum = ((span->red) >> 11) + (GLint) sample[0]; GLint gSum = ((span->green) >> 11) + (GLint) sample[1]; GLint bSum = ((span->blue) >> 11) + (GLint) sample[2]; dest[0] = ( (rSum)<(255) ? (rSum) : (255) ); dest[1] = ( (gSum)<(255) ? (gSum) : (255) ); dest[2] = ( (bSum)<(255) ? (bSum) : (255) ); dest[3] = span->alpha * (sample[3] + 1) >> (11 + 8); }; span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; tex_coord[0] += tex_step[0]; tex_coord[1] += tex_step[1]; tex_coord[2] += tex_step[2]; dest += 4; };
  4385.             break;
  4386.          case 0x1E01:
  4387.             for (i = 0; i < span->end; i++) { GLdouble invQ = tex_coord[2] ? (1.0 / tex_coord[2]) : 1.0; GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); GLfixed s_fix = (((int) ((((s_tmp) * 2048.0f) >= 0.0F) ? (((s_tmp) * 2048.0f) + 0.5F) : (((s_tmp) * 2048.0f) - 0.5F)))) - 0x00000400; GLfixed t_fix = (((int) ((((t_tmp) * 2048.0f) >= 0.0F) ? (((t_tmp) * 2048.0f) + 0.5F) : (((t_tmp) * 2048.0f) - 0.5F)))) - 0x00000400; GLint s = ((((s_fix) & (~0x000007FF))) >> 11) & info->smask; GLint t = ((((t_fix) & (~0x000007FF))) >> 11) & info->tmask; GLfixed sf = s_fix & 0x000007FF; GLfixed tf = t_fix & 0x000007FF; GLfixed si = 0x000007FF - sf; GLfixed ti = 0x000007FF - tf; GLint pos = (t << info->twidth_log2) + s; const GLchan *tex00 = info->texture + 4 * pos; const GLchan *tex10 = tex00 + info->tbytesline; const GLchan *tex01 = tex00 + 4; const GLchan *tex11 = tex10 + 4; (void) ti; (void) si; if (t == info->tmask) { tex10 -= info->tsize; tex11 -= info->tsize; } if (s == info->smask) { tex01 -= info->tbytesline; tex11 -= info->tbytesline; } sample[0] = (ti * (si * tex00[0] + sf * tex01[0]) + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * 11; sample[1] = (ti * (si * tex00[1] + sf * tex01[1]) + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * 11; sample[2] = (ti * (si * tex00[2] + sf * tex01[2]) + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * 11; sample[3] = (ti * (si * tex00[3] + sf * tex01[3]) + tf * (si * tex10[3] + sf * tex11[3])) >> 2 * 11;{ (dest)[0] = (sample)[0]; (dest)[1] = (sample)[1]; (dest)[2] = (sample)[2]; (dest)[3] = (sample)[3]; }; span->red += span->redStep; span->green += span->greenStep; span->blue += span->blueStep; span->alpha += span->alphaStep; tex_coord[0] += tex_step[0]; tex_coord[1] += tex_step[1]; tex_coord[2] += tex_step[2]; dest += 4; };
  4388.             break;
  4389.          default:
  4390.             _mesa_problem(ctx, "bad tex env mode (8) in SPAN_LINEAR");
  4391.             return;
  4392.          }
  4393.          break;
  4394.       }
  4395.       break;
  4396.    }
  4397.  
  4398.    ;
  4399.    _mesa_write_rgba_span(ctx, span);
  4400.  
  4401. }
  4402.  
  4403.  
  4404. /*
  4405.  * Render an perspective corrected RGB/RGBA textured triangle.
  4406.  * The Q (aka V in Mesa) coordinate must be zero such that the divide
  4407.  * by interpolated Q/W comes out right.
  4408.  *
  4409.  */
  4410. /*
  4411.  * Triangle Rasterizer Template
  4412.  *
  4413.  * This file is #include'd to generate custom triangle rasterizers.
  4414.  *
  4415.  * The following macros may be defined to indicate what auxillary information
  4416.  * must be interplated across the triangle:
  4417.  *    INTERP_Z        - if defined, interpolate Z values
  4418.  *    INTERP_FOG      - if defined, interpolate fog values
  4419.  *    INTERP_RGB      - if defined, interpolate RGB values
  4420.  *    INTERP_ALPHA    - if defined, interpolate Alpha values (req's INTERP_RGB)
  4421.  *    INTERP_SPEC     - if defined, interpolate specular RGB values
  4422.  *    INTERP_INDEX    - if defined, interpolate color index values
  4423.  *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
  4424.  *                         (fast, simple 2-D texture mapping)
  4425.  *    INTERP_TEX      - if defined, interpolate set 0 float STRQ texcoords
  4426.  *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
  4427.  *    INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
  4428.  *    INTERP_FLOAT_RGBA - if defined, interpolate RGBA with floating point
  4429.  *    INTERP_FLOAT_SPEC - if defined, interpolate specular with floating point
  4430.  *
  4431.  * When one can directly address pixels in the color buffer the following
  4432.  * macros can be defined and used to compute pixel addresses during
  4433.  * rasterization (see pRow):
  4434.  *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
  4435.  *    BYTES_PER_ROW       - number of bytes per row in the color buffer
  4436.  *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
  4437.  *                          Y==0 at bottom of screen and increases upward.
  4438.  *
  4439.  * Similarly, for direct depth buffer access, this type is used for depth
  4440.  * buffer addressing:
  4441.  *    DEPTH_TYPE          - either GLushort or GLuint
  4442.  *
  4443.  * Optionally, one may provide one-time setup code per triangle:
  4444.  *    SETUP_CODE    - code which is to be executed once per triangle
  4445.  *    CLEANUP_CODE    - code to execute at end of triangle
  4446.  *
  4447.  * The following macro MUST be defined:
  4448.  *    RENDER_SPAN(span) - code to write a span of pixels.
  4449.  *
  4450.  * This code was designed for the origin to be in the lower-left corner.
  4451.  *
  4452.  * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
  4453.  */
  4454.  
  4455.  
  4456. /*
  4457.  * This is a bit of a hack, but it's a centralized place to enable floating-
  4458.  * point color interpolation when GLchan is actually floating point.
  4459.  */
  4460.  
  4461.  
  4462.  
  4463. static void persp_textured_triangle(GLcontext *ctx, const SWvertex *v0,
  4464.                                  const SWvertex *v1,
  4465.                                  const SWvertex *v2 )
  4466. {
  4467.    typedef struct {
  4468.         const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
  4469.         GLfloat dx;    /* X(v1) - X(v0) */
  4470.         GLfloat dy;    /* Y(v1) - Y(v0) */
  4471.         GLfixed fdxdy; /* dx/dy in fixed-point */
  4472.         GLfixed fsx;   /* first sample point x coord */
  4473.         GLfixed fsy;
  4474.         GLfloat adjy;  /* adjust from v[0]->fy to fsy, scaled */
  4475.         GLint lines;   /* number of lines to be sampled on this edge */
  4476.         GLfixed fx0;   /* fixed pt X of lower endpoint */
  4477.    } EdgeT;
  4478.  
  4479.    const GLint depthBits = ctx->Visual.depthBits;
  4480.    const GLfloat maxDepth = ctx->DepthMaxF;
  4481.    EdgeT eMaj, eTop, eBot;
  4482.    GLfloat oneOverArea;
  4483.    const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
  4484.    float bf = ((SWcontext *)ctx->swrast_context)->_backface_sign;
  4485.    const GLint snapMask = ~((0x00000800 / (1 << 4)) - 1); /* for x/y coord snapping */
  4486.    GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
  4487.  
  4488.    struct sw_span span;
  4489.  
  4490.     (span).primitive = (0x0009);
  4491.     (span).interpMask = (0);
  4492.     (span).arrayMask = (0);
  4493.     (span).start = 0;
  4494.     (span).end = (0);
  4495.     (span).facing = 0;
  4496.     (span).array = ((SWcontext *)ctx->swrast_context)->SpanArrays;
  4497.  
  4498.    /*
  4499.    printf("%s()\n", __FUNCTION__);
  4500.    printf("  %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
  4501.    printf("  %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
  4502.    printf("  %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
  4503.     */
  4504.  
  4505.    /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
  4506.     * And find the order of the 3 vertices along the Y axis.
  4507.     */
  4508.    {
  4509.       const GLfixed fy0 = (((int) ((((v0->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v0->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v0->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  4510.       const GLfixed fy1 = (((int) ((((v1->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v1->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v1->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  4511.       const GLfixed fy2 = (((int) ((((v2->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v2->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v2->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  4512.  
  4513.       if (fy0 <= fy1) {
  4514.          if (fy1 <= fy2) {
  4515.             /* y0 <= y1 <= y2 */
  4516.             vMin = v0;   vMid = v1;   vMax = v2;
  4517.             vMin_fy = fy0;  vMid_fy = fy1;  vMax_fy = fy2;
  4518.          }
  4519.          else if (fy2 <= fy0) {
  4520.             /* y2 <= y0 <= y1 */
  4521.             vMin = v2;   vMid = v0;   vMax = v1;
  4522.             vMin_fy = fy2;  vMid_fy = fy0;  vMax_fy = fy1;
  4523.          }
  4524.          else {
  4525.             /* y0 <= y2 <= y1 */
  4526.             vMin = v0;   vMid = v2;   vMax = v1;
  4527.             vMin_fy = fy0;  vMid_fy = fy2;  vMax_fy = fy1;
  4528.             bf = -bf;
  4529.          }
  4530.       }
  4531.       else {
  4532.          if (fy0 <= fy2) {
  4533.             /* y1 <= y0 <= y2 */
  4534.             vMin = v1;   vMid = v0;   vMax = v2;
  4535.             vMin_fy = fy1;  vMid_fy = fy0;  vMax_fy = fy2;
  4536.             bf = -bf;
  4537.          }
  4538.          else if (fy2 <= fy1) {
  4539.             /* y2 <= y1 <= y0 */
  4540.             vMin = v2;   vMid = v1;   vMax = v0;
  4541.             vMin_fy = fy2;  vMid_fy = fy1;  vMax_fy = fy0;
  4542.             bf = -bf;
  4543.          }
  4544.          else {
  4545.             /* y1 <= y2 <= y0 */
  4546.             vMin = v1;   vMid = v2;   vMax = v0;
  4547.             vMin_fy = fy1;  vMid_fy = fy2;  vMax_fy = fy0;
  4548.          }
  4549.       }
  4550.  
  4551.       /* fixed point X coords */
  4552.       vMin_fx = (((int) ((((vMin->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMin->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMin->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  4553.       vMid_fx = (((int) ((((vMid->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMid->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMid->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  4554.       vMax_fx = (((int) ((((vMax->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMax->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMax->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  4555.    }
  4556.  
  4557.    /* vertex/edge relationship */
  4558.    eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
  4559.    eTop.v0 = vMid;   eTop.v1 = vMax;
  4560.    eBot.v0 = vMin;   eBot.v1 = vMid;
  4561.  
  4562.    /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
  4563.    eMaj.dx = ((vMax_fx - vMin_fx) * (1.0F / 2048.0f));
  4564.    eMaj.dy = ((vMax_fy - vMin_fy) * (1.0F / 2048.0f));
  4565.    eTop.dx = ((vMax_fx - vMid_fx) * (1.0F / 2048.0f));
  4566.    eTop.dy = ((vMax_fy - vMid_fy) * (1.0F / 2048.0f));
  4567.    eBot.dx = ((vMid_fx - vMin_fx) * (1.0F / 2048.0f));
  4568.    eBot.dy = ((vMid_fy - vMin_fy) * (1.0F / 2048.0f));
  4569.  
  4570.    /* compute area, oneOverArea and perform backface culling */
  4571.    {
  4572.       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
  4573.  
  4574.       /* Do backface culling */
  4575.       if (area * bf < 0.0)
  4576.          return;
  4577.  
  4578.       if (IS_INF_OR_NAN(area) || area == 0.0F)
  4579.          return;
  4580.  
  4581.       oneOverArea = 1.0F / area;
  4582.    }
  4583.  
  4584.    ctx->OcclusionResult = 0x1;
  4585.    span.facing = ctx->_Facing; /* for 2-sided stencil test */
  4586.  
  4587.    /* Edge setup.  For a triangle strip these could be reused... */
  4588.    {
  4589.       eMaj.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  4590.       eMaj.lines = (((((vMax_fy - eMaj.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  4591.       if (eMaj.lines > 0) {
  4592.          GLfloat dxdy = eMaj.dx / eMaj.dy;
  4593.          eMaj.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  4594.          eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
  4595.          eMaj.fx0 = vMin_fx;
  4596.          eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy);
  4597.       }
  4598.       else {
  4599.          return;  /*CULLED*/
  4600.       }
  4601.  
  4602.       eTop.fsy = (((vMid_fy) + 0x00000800 - 1) & (~0x000007FF));
  4603.       eTop.lines = (((((vMax_fy - eTop.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  4604.       if (eTop.lines > 0) {
  4605.          GLfloat dxdy = eTop.dx / eTop.dy;
  4606.          eTop.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  4607.          eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
  4608.          eTop.fx0 = vMid_fx;
  4609.          eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy);
  4610.       }
  4611.  
  4612.       eBot.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  4613.       eBot.lines = (((((vMid_fy - eBot.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  4614.       if (eBot.lines > 0) {
  4615.          GLfloat dxdy = eBot.dx / eBot.dy;
  4616.          eBot.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  4617.          eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
  4618.          eBot.fx0 = vMin_fx;
  4619.          eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy);
  4620.       }
  4621.    }
  4622.  
  4623.    /*
  4624.     * Conceptually, we view a triangle as two subtriangles
  4625.     * separated by a perfectly horizontal line.  The edge that is
  4626.     * intersected by this line is one with maximal absolute dy; we
  4627.     * call it a ``major'' edge.  The other two edges are the
  4628.     * ``top'' edge (for the upper subtriangle) and the ``bottom''
  4629.     * edge (for the lower subtriangle).  If either of these two
  4630.     * edges is horizontal or very close to horizontal, the
  4631.     * corresponding subtriangle might cover zero sample points;
  4632.     * we take care to handle such cases, for performance as well
  4633.     * as correctness.
  4634.     *
  4635.     * By stepping rasterization parameters along the major edge,
  4636.     * we can avoid recomputing them at the discontinuity where
  4637.     * the top and bottom edges meet.  However, this forces us to
  4638.     * be able to scan both left-to-right and right-to-left.
  4639.     * Also, we must determine whether the major edge is at the
  4640.     * left or right side of the triangle.  We do this by
  4641.     * computing the magnitude of the cross-product of the major
  4642.     * and top edges.  Since this magnitude depends on the sine of
  4643.     * the angle between the two edges, its sign tells us whether
  4644.     * we turn to the left or to the right when travelling along
  4645.     * the major edge to the top edge, and from this we infer
  4646.     * whether the major edge is on the left or the right.
  4647.     *
  4648.     * Serendipitously, this cross-product magnitude is also a
  4649.     * value we need to compute the iteration parameter
  4650.     * derivatives for the triangle, and it can be used to perform
  4651.     * backface culling because its sign tells us whether the
  4652.     * triangle is clockwise or counterclockwise.  In this code we
  4653.     * refer to it as ``area'' because it's also proportional to
  4654.     * the pixel area of the triangle.
  4655.     */
  4656.  
  4657.    {
  4658.       GLint scan_from_left_to_right;  /* true if scanning left-to-right */
  4659.       GLfloat dzdx, dzdy;
  4660.       GLfloat dfogdy;
  4661.       GLfloat drdx, drdy;
  4662.       GLfloat dgdx, dgdy;
  4663.       GLfloat dbdx, dbdy;
  4664.       GLfloat dadx, dady;
  4665.       GLfloat dsdx, dsdy;
  4666.       GLfloat dtdx, dtdy;
  4667.       GLfloat dudx, dudy;
  4668.       GLfloat dvdx, dvdy;
  4669.  
  4670.       /*
  4671.        * Execute user-supplied setup code
  4672.        */
  4673.       struct persp_info info; const struct gl_texture_unit *unit = ctx->Texture.Unit+0; const struct gl_texture_object *obj = unit->Current2D; const GLint b = obj->BaseLevel; info.texture = (const GLchan *) obj->Image[b]->Data; info.twidth_log2 = obj->Image[b]->WidthLog2; info.smask = obj->Image[b]->Width - 1; info.tmask = obj->Image[b]->Height - 1; info.format = obj->Image[b]->Format; info.filter = obj->MinFilter; info.envmode = unit->EnvMode; if (info.envmode == 0x0BE2) { info.er = (((int) ((((unit->EnvColor[0] * 255.0F) * 2048.0f) >= 0.0F) ? (((unit->EnvColor[0] * 255.0F) * 2048.0f) + 0.5F) : (((unit->EnvColor[0] * 255.0F) * 2048.0f) - 0.5F)))); info.eg = (((int) ((((unit->EnvColor[1] * 255.0F) * 2048.0f) >= 0.0F) ? (((unit->EnvColor[1] * 255.0F) * 2048.0f) + 0.5F) : (((unit->EnvColor[1] * 255.0F) * 2048.0f) - 0.5F)))); info.eb = (((int) ((((unit->EnvColor[2] * 255.0F) * 2048.0f) >= 0.0F) ? (((unit->EnvColor[2] * 255.0F) * 2048.0f) + 0.5F) : (((unit->EnvColor[2] * 255.0F) * 2048.0f) - 0.5F)))); info.ea = (((int) ((((unit->EnvColor[3] * 255.0F) * 2048.0f) >= 0.0F) ? (((unit->EnvColor[3] * 255.0F) * 2048.0f) + 0.5F) : (((unit->EnvColor[3] * 255.0F) * 2048.0f) - 0.5F)))); } if (!info.texture) { return; } switch (info.format) { case 0x1906: case 0x1909: case 0x8049: info.tbytesline = obj->Image[b]->Width; break; case 0x190A: info.tbytesline = obj->Image[b]->Width * 2; break; case 0x1907: info.tbytesline = obj->Image[b]->Width * 3; break; case 0x1908: info.tbytesline = obj->Image[b]->Width * 4; break; default: _mesa_problem(0, "Bad texture format in persp_textured_triangle"); return; } info.tsize = obj->Image[b]->Height * info.tbytesline;
  4674.  
  4675.       scan_from_left_to_right = (oneOverArea < 0.0F);
  4676.  
  4677.  
  4678.       /* compute d?/dx and d?/dy derivatives */
  4679.       span.interpMask |= 0x008;
  4680.       {
  4681.          GLfloat eMaj_dz, eBot_dz;
  4682.          eMaj_dz = vMax->win[2] - vMin->win[2];
  4683.          eBot_dz = vMid->win[2] - vMin->win[2];
  4684.          dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
  4685.          if (dzdx > maxDepth || dzdx < -maxDepth) {
  4686.             /* probably a sliver triangle */
  4687.             dzdx = 0.0;
  4688.             dzdy = 0.0;
  4689.          }
  4690.          else {
  4691.             dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
  4692.          }
  4693.          if (depthBits <= 16)
  4694.             span.zStep = (((int) ((((dzdx) * 2048.0f) >= 0.0F) ? (((dzdx) * 2048.0f) + 0.5F) : (((dzdx) * 2048.0f) - 0.5F))));
  4695.          else
  4696.             span.zStep = (GLint) dzdx;
  4697.       }
  4698.       span.interpMask |= 0x010;
  4699.       {
  4700.          const GLfloat eMaj_dfog = vMax->fog - vMin->fog;
  4701.          const GLfloat eBot_dfog = vMid->fog - vMin->fog;
  4702.          span.fogStep = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
  4703.          dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
  4704.       }
  4705.       span.interpMask |= 0x001;
  4706.       if (ctx->Light.ShadeModel == 0x1D01) {
  4707.          GLfloat eMaj_dr, eBot_dr;
  4708.          GLfloat eMaj_dg, eBot_dg;
  4709.          GLfloat eMaj_db, eBot_db;
  4710.          GLfloat eMaj_da, eBot_da;
  4711.          eMaj_dr = (GLfloat) ((GLint) vMax->color[0] -
  4712.                              (GLint) vMin->color[0]);
  4713.          eBot_dr = (GLfloat) ((GLint) vMid->color[0] -
  4714.                              (GLint) vMin->color[0]);
  4715.          drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
  4716.          span.redStep = (((int) ((((drdx) * 2048.0f) >= 0.0F) ? (((drdx) * 2048.0f) + 0.5F) : (((drdx) * 2048.0f) - 0.5F))));
  4717.          drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
  4718.          eMaj_dg = (GLfloat) ((GLint) vMax->color[1] -
  4719.                              (GLint) vMin->color[1]);
  4720.          eBot_dg = (GLfloat) ((GLint) vMid->color[1] -
  4721.                              (GLint) vMin->color[1]);
  4722.          dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
  4723.          span.greenStep = (((int) ((((dgdx) * 2048.0f) >= 0.0F) ? (((dgdx) * 2048.0f) + 0.5F) : (((dgdx) * 2048.0f) - 0.5F))));
  4724.          dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
  4725.          eMaj_db = (GLfloat) ((GLint) vMax->color[2] -
  4726.                              (GLint) vMin->color[2]);
  4727.          eBot_db = (GLfloat) ((GLint) vMid->color[2] -
  4728.                              (GLint) vMin->color[2]);
  4729.          dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
  4730.          span.blueStep = (((int) ((((dbdx) * 2048.0f) >= 0.0F) ? (((dbdx) * 2048.0f) + 0.5F) : (((dbdx) * 2048.0f) - 0.5F))));
  4731.          dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
  4732.          eMaj_da = (GLfloat) ((GLint) vMax->color[3] -
  4733.                              (GLint) vMin->color[3]);
  4734.          eBot_da = (GLfloat) ((GLint) vMid->color[3] -
  4735.                              (GLint) vMin->color[3]);
  4736.          dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
  4737.          span.alphaStep = (((int) ((((dadx) * 2048.0f) >= 0.0F) ? (((dadx) * 2048.0f) + 0.5F) : (((dadx) * 2048.0f) - 0.5F))));
  4738.          dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
  4739.       }
  4740.       else {
  4741.          ;
  4742.          span.interpMask |= 0x200;
  4743.          drdx = drdy = 0.0F;
  4744.          dgdx = dgdy = 0.0F;
  4745.          dbdx = dbdy = 0.0F;
  4746.          span.redStep = 0;
  4747.          span.greenStep = 0;
  4748.          span.blueStep = 0;
  4749.          dadx = dady = 0.0F;
  4750.          span.alphaStep = 0;
  4751.       }
  4752.       span.interpMask |= 0x020;
  4753.       {
  4754.          GLfloat wMax = vMax->win[3];
  4755.          GLfloat wMin = vMin->win[3];
  4756.          GLfloat wMid = vMid->win[3];
  4757.          GLfloat eMaj_ds, eBot_ds;
  4758.          GLfloat eMaj_dt, eBot_dt;
  4759.          GLfloat eMaj_du, eBot_du;
  4760.          GLfloat eMaj_dv, eBot_dv;
  4761.  
  4762.          eMaj_ds = vMax->texcoord[0][0] * wMax - vMin->texcoord[0][0] * wMin;
  4763.          eBot_ds = vMid->texcoord[0][0] * wMid - vMin->texcoord[0][0] * wMin;
  4764.          dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
  4765.          dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
  4766.          span.texStepX[0][0] = dsdx;
  4767.          span.texStepY[0][0] = dsdy;
  4768.  
  4769.          eMaj_dt = vMax->texcoord[0][1] * wMax - vMin->texcoord[0][1] * wMin;
  4770.          eBot_dt = vMid->texcoord[0][1] * wMid - vMin->texcoord[0][1] * wMin;
  4771.          dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
  4772.          dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
  4773.          span.texStepX[0][1] = dtdx;
  4774.          span.texStepY[0][1] = dtdy;
  4775.  
  4776.          eMaj_du = vMax->texcoord[0][2] * wMax - vMin->texcoord[0][2] * wMin;
  4777.          eBot_du = vMid->texcoord[0][2] * wMid - vMin->texcoord[0][2] * wMin;
  4778.          dudx = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
  4779.          dudy = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
  4780.          span.texStepX[0][2] = dudx;
  4781.          span.texStepY[0][2] = dudy;
  4782.  
  4783.          eMaj_dv = vMax->texcoord[0][3] * wMax - vMin->texcoord[0][3] * wMin;
  4784.          eBot_dv = vMid->texcoord[0][3] * wMid - vMin->texcoord[0][3] * wMin;
  4785.          dvdx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
  4786.          dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
  4787.          span.texStepX[0][3] = dvdx;
  4788.          span.texStepY[0][3] = dvdy;
  4789.       }
  4790.  
  4791.       /*
  4792.        * We always sample at pixel centers.  However, we avoid
  4793.        * explicit half-pixel offsets in this code by incorporating
  4794.        * the proper offset in each of x and y during the
  4795.        * transformation to window coordinates.
  4796.        *
  4797.        * We also apply the usual rasterization rules to prevent
  4798.        * cracks and overlaps.  A pixel is considered inside a
  4799.        * subtriangle if it meets all of four conditions: it is on or
  4800.        * to the right of the left edge, strictly to the left of the
  4801.        * right edge, on or below the top edge, and strictly above
  4802.        * the bottom edge.  (Some edges may be degenerate.)
  4803.        *
  4804.        * The following discussion assumes left-to-right scanning
  4805.        * (that is, the major edge is on the left); the right-to-left
  4806.        * case is a straightforward variation.
  4807.        *
  4808.        * We start by finding the half-integral y coordinate that is
  4809.        * at or below the top of the triangle.  This gives us the
  4810.        * first scan line that could possibly contain pixels that are
  4811.        * inside the triangle.
  4812.        *
  4813.        * Next we creep down the major edge until we reach that y,
  4814.        * and compute the corresponding x coordinate on the edge.
  4815.        * Then we find the half-integral x that lies on or just
  4816.        * inside the edge.  This is the first pixel that might lie in
  4817.        * the interior of the triangle.  (We won't know for sure
  4818.        * until we check the other edges.)
  4819.        *
  4820.        * As we rasterize the triangle, we'll step down the major
  4821.        * edge.  For each step in y, we'll move an integer number
  4822.        * of steps in x.  There are two possible x step sizes, which
  4823.        * we'll call the ``inner'' step (guaranteed to land on the
  4824.        * edge or inside it) and the ``outer'' step (guaranteed to
  4825.        * land on the edge or outside it).  The inner and outer steps
  4826.        * differ by one.  During rasterization we maintain an error
  4827.        * term that indicates our distance from the true edge, and
  4828.        * select either the inner step or the outer step, whichever
  4829.        * gets us to the first pixel that falls inside the triangle.
  4830.        *
  4831.        * All parameters (z, red, etc.) as well as the buffer
  4832.        * addresses for color and z have inner and outer step values,
  4833.        * so that we can increment them appropriately.  This method
  4834.        * eliminates the need to adjust parameters by creeping a
  4835.        * sub-pixel amount into the triangle at each scanline.
  4836.        */
  4837.  
  4838.       {
  4839.          int subTriangle;
  4840.          GLfixed fx;
  4841.          GLfixed fxLeftEdge = 0, fxRightEdge = 0;
  4842.          GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
  4843.          GLfixed fdxOuter;
  4844.          int idxOuter;
  4845.          float dxOuter;
  4846.          GLfixed fError = 0, fdError = 0;
  4847.          float adjx, adjy;
  4848.          GLfixed fy;
  4849.          GLushort *zRow = 0;
  4850.          int dZRowOuter = 0, dZRowInner;  /* offset in bytes */
  4851.          GLfixed fz = 0, fdzOuter = 0, fdzInner;
  4852.          GLfloat fogLeft = 0, dfogOuter = 0, dfogInner;
  4853.          GLfixed fr = 0, fdrOuter = 0, fdrInner;
  4854.          GLfixed fg = 0, fdgOuter = 0, fdgInner;
  4855.          GLfixed fb = 0, fdbOuter = 0, fdbInner;
  4856.          GLfixed fa = 0, fdaOuter = 0, fdaInner;
  4857.          GLfloat sLeft=0, dsOuter=0, dsInner;
  4858.          GLfloat tLeft=0, dtOuter=0, dtInner;
  4859.          GLfloat uLeft=0, duOuter=0, duInner;
  4860.          GLfloat vLeft=0, dvOuter=0, dvInner;
  4861.  
  4862.          for (subTriangle=0; subTriangle<=1; subTriangle++) {
  4863.             EdgeT *eLeft, *eRight;
  4864.             int setupLeft, setupRight;
  4865.             int lines;
  4866.  
  4867.             if (subTriangle==0) {
  4868.                /* bottom half */
  4869.                if (scan_from_left_to_right) {
  4870.                   eLeft = &eMaj;
  4871.                   eRight = &eBot;
  4872.                   lines = eRight->lines;
  4873.                   setupLeft = 1;
  4874.                   setupRight = 1;
  4875.                }
  4876.                else {
  4877.                   eLeft = &eBot;
  4878.                   eRight = &eMaj;
  4879.                   lines = eLeft->lines;
  4880.                   setupLeft = 1;
  4881.                   setupRight = 1;
  4882.                }
  4883.             }
  4884.             else {
  4885.                /* top half */
  4886.                if (scan_from_left_to_right) {
  4887.                   eLeft = &eMaj;
  4888.                   eRight = &eTop;
  4889.                   lines = eRight->lines;
  4890.                   setupLeft = 0;
  4891.                   setupRight = 1;
  4892.                }
  4893.                else {
  4894.                   eLeft = &eTop;
  4895.                   eRight = &eMaj;
  4896.                   lines = eLeft->lines;
  4897.                   setupLeft = 1;
  4898.                   setupRight = 0;
  4899.                }
  4900.                if (lines == 0)
  4901.                   return;
  4902.             }
  4903.  
  4904.             if (setupLeft && eLeft->lines > 0) {
  4905.                const SWvertex *vLower;
  4906.                GLfixed fsx = eLeft->fsx;
  4907.                fx = (((fsx) + 0x00000800 - 1) & (~0x000007FF));
  4908.                fError = fx - fsx - 0x00000800;
  4909.                fxLeftEdge = fsx - 1;
  4910.                fdxLeftEdge = eLeft->fdxdy;
  4911.                fdxOuter = ((fdxLeftEdge - 1) & (~0x000007FF));
  4912.                fdError = fdxOuter - fdxLeftEdge + 0x00000800;
  4913.                idxOuter = ((fdxOuter) >> 11);
  4914.                dxOuter = (float) idxOuter;
  4915.                (void) dxOuter;
  4916.  
  4917.                fy = eLeft->fsy;
  4918.                span.y = ((fy) >> 11);
  4919.  
  4920.                adjx = (float)(fx - eLeft->fx0);  /* SCALED! */
  4921.                adjy = eLeft->adjy;              /* SCALED! */
  4922.                vLower = eLeft->v0;
  4923.  
  4924.                /*
  4925.                 * Now we need the set of parameter (z, color, etc.) values at
  4926.                 * the point (fx, fy).  This gives us properly-sampled parameter
  4927.                 * values that we can step from pixel to pixel.  Furthermore,
  4928.                 * although we might have intermediate results that overflow
  4929.                 * the normal parameter range when we step temporarily outside
  4930.                 * the triangle, we shouldn't overflow or underflow for any
  4931.                 * pixel that's actually inside the triangle.
  4932.                 */
  4933.  
  4934.                {
  4935.                   GLfloat z0 = vLower->win[2];
  4936.                   if (depthBits <= 16) {
  4937.                      /* interpolate fixed-pt values */
  4938.                      GLfloat tmp = (z0 * 2048.0f +
  4939.                                     dzdx * adjx + dzdy * adjy) + 0x00000400;
  4940.                      if (tmp < 0xffffffff / 2)
  4941.                         fz = (GLfixed) tmp;
  4942.                      else
  4943.                         fz = 0xffffffff / 2;
  4944.                      fdzOuter = (((int) ((((dzdy + dxOuter * dzdx) * 2048.0f) >= 0.0F) ? (((dzdy + dxOuter * dzdx) * 2048.0f) + 0.5F) : (((dzdy + dxOuter * dzdx) * 2048.0f) - 0.5F))));
  4945.                   }
  4946.                   else {
  4947.                      /* interpolate depth values exactly */
  4948.                      fz = (GLint) (z0 + dzdx * ((adjx) * (1.0F / 2048.0f))
  4949.                                    + dzdy * ((adjy) * (1.0F / 2048.0f)));
  4950.                      fdzOuter = (GLint) (dzdy + dxOuter * dzdx);
  4951.                   }
  4952.                   zRow = (GLushort *)
  4953.                     _mesa_zbuffer_address(ctx, ((fxLeftEdge) >> 11), span.y);
  4954.                   dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(GLushort);
  4955.                }
  4956.                fogLeft = vLower->fog + (span.fogStep * adjx + dfogdy * adjy)
  4957.                                        * (1.0F/2048.0f);
  4958.                dfogOuter = dfogdy + dxOuter * span.fogStep;
  4959.                if (ctx->Light.ShadeModel == 0x1D01) {
  4960.                   fr = (GLfixed) (((vLower->color[0]) << 11)
  4961.                                    + drdx * adjx + drdy * adjy) + 0x00000400;
  4962.                   fdrOuter = (((int) ((((drdy + dxOuter * drdx) * 2048.0f) >= 0.0F) ? (((drdy + dxOuter * drdx) * 2048.0f) + 0.5F) : (((drdy + dxOuter * drdx) * 2048.0f) - 0.5F))));
  4963.                   fg = (GLfixed) (((vLower->color[1]) << 11)
  4964.                                    + dgdx * adjx + dgdy * adjy) + 0x00000400;
  4965.                   fdgOuter = (((int) ((((dgdy + dxOuter * dgdx) * 2048.0f) >= 0.0F) ? (((dgdy + dxOuter * dgdx) * 2048.0f) + 0.5F) : (((dgdy + dxOuter * dgdx) * 2048.0f) - 0.5F))));
  4966.                   fb = (GLfixed) (((vLower->color[2]) << 11)
  4967.                                     + dbdx * adjx + dbdy * adjy) + 0x00000400;
  4968.                   fdbOuter = (((int) ((((dbdy + dxOuter * dbdx) * 2048.0f) >= 0.0F) ? (((dbdy + dxOuter * dbdx) * 2048.0f) + 0.5F) : (((dbdy + dxOuter * dbdx) * 2048.0f) - 0.5F))));
  4969.                   fa = (GLfixed) (((vLower->color[3]) << 11)
  4970.                                    + dadx * adjx + dady * adjy) + 0x00000400;
  4971.                   fdaOuter = (((int) ((((dady + dxOuter * dadx) * 2048.0f) >= 0.0F) ? (((dady + dxOuter * dadx) * 2048.0f) + 0.5F) : (((dady + dxOuter * dadx) * 2048.0f) - 0.5F))));
  4972.                }
  4973.                else {
  4974.                   ;
  4975.                   fr = ((v2->color[0]) << 11);
  4976.                   fg = ((v2->color[1]) << 11);
  4977.                   fb = ((v2->color[2]) << 11);
  4978.                   fdrOuter = fdgOuter = fdbOuter = 0;
  4979.                   fa =  ((v2->color[3]) << 11);
  4980.                   fdaOuter = 0;
  4981.                }
  4982.                {
  4983.                   GLfloat invW = vLower->win[3];
  4984.                   GLfloat s0, t0, u0, v0;
  4985.                   s0 = vLower->texcoord[0][0] * invW;
  4986.                   sLeft = s0 + (span.texStepX[0][0] * adjx + dsdy * adjy)
  4987.                      * (1.0F/2048.0f);
  4988.                   dsOuter = dsdy + dxOuter * span.texStepX[0][0];
  4989.                   t0 = vLower->texcoord[0][1] * invW;
  4990.                   tLeft = t0 + (span.texStepX[0][1] * adjx + dtdy * adjy)
  4991.                      * (1.0F/2048.0f);
  4992.                   dtOuter = dtdy + dxOuter * span.texStepX[0][1];
  4993.                   u0 = vLower->texcoord[0][2] * invW;
  4994.                   uLeft = u0 + (span.texStepX[0][2] * adjx + dudy * adjy)
  4995.                      * (1.0F/2048.0f);
  4996.                   duOuter = dudy + dxOuter * span.texStepX[0][2];
  4997.                   v0 = vLower->texcoord[0][3] * invW;
  4998.                   vLeft = v0 + (span.texStepX[0][3] * adjx + dvdy * adjy)
  4999.                      * (1.0F/2048.0f);
  5000.                   dvOuter = dvdy + dxOuter * span.texStepX[0][3];
  5001.                }
  5002.  
  5003.             } /*if setupLeft*/
  5004.  
  5005.  
  5006.             if (setupRight && eRight->lines>0) {
  5007.                fxRightEdge = eRight->fsx - 1;
  5008.                fdxRightEdge = eRight->fdxdy;
  5009.             }
  5010.  
  5011.             if (lines==0) {
  5012.                continue;
  5013.             }
  5014.  
  5015.  
  5016.             /* Rasterize setup */
  5017.             dZRowInner = dZRowOuter + sizeof(GLushort);
  5018.             fdzInner = fdzOuter + span.zStep;
  5019.             dfogInner = dfogOuter + span.fogStep;
  5020.             fdrInner = fdrOuter + span.redStep;
  5021.             fdgInner = fdgOuter + span.greenStep;
  5022.             fdbInner = fdbOuter + span.blueStep;
  5023.             fdaInner = fdaOuter + span.alphaStep;
  5024.             dsInner = dsOuter + span.texStepX[0][0];
  5025.             dtInner = dtOuter + span.texStepX[0][1];
  5026.             duInner = duOuter + span.texStepX[0][2];
  5027.             dvInner = dvOuter + span.texStepX[0][3];
  5028.  
  5029.             while (lines > 0) {
  5030.                /* initialize the span interpolants to the leftmost value */
  5031.                /* ff = fixed-pt fragment */
  5032.                const GLint right = ((fxRightEdge) >> 11);
  5033.  
  5034.                span.x = ((fxLeftEdge) >> 11);
  5035.  
  5036.                if (right <= span.x)
  5037.                   span.end = 0;
  5038.                else
  5039.                   span.end = right - span.x;
  5040.  
  5041.                span.z = fz;
  5042.                span.fog = fogLeft;
  5043.                span.red = fr;
  5044.                span.green = fg;
  5045.                span.blue = fb;
  5046.                span.alpha = fa;
  5047.  
  5048.                span.tex[0][0] = sLeft;
  5049.                span.tex[0][1] = tLeft;
  5050.                span.tex[0][2] = uLeft;
  5051.                span.tex[0][3] = vLeft;
  5052.  
  5053.  
  5054.                {
  5055.                   /* need this to accomodate round-off errors */
  5056.                   const GLint len = right - span.x - 1;
  5057.                   GLfixed ffrend = span.red + len * span.redStep;
  5058.                   GLfixed ffgend = span.green + len * span.greenStep;
  5059.                   GLfixed ffbend = span.blue + len * span.blueStep;
  5060.                   if (ffrend < 0) {
  5061.                      span.red -= ffrend;
  5062.                      if (span.red < 0)
  5063.                         span.red = 0;
  5064.                   }
  5065.                   if (ffgend < 0) {
  5066.                      span.green -= ffgend;
  5067.                      if (span.green < 0)
  5068.                         span.green = 0;
  5069.                   }
  5070.                   if (ffbend < 0) {
  5071.                      span.blue -= ffbend;
  5072.                      if (span.blue < 0)
  5073.                         span.blue = 0;
  5074.                   }
  5075.                }
  5076.                {
  5077.                   const GLint len = right - span.x - 1;
  5078.                   GLfixed ffaend = span.alpha + len * span.alphaStep;
  5079.                   if (ffaend < 0) {
  5080.                      span.alpha -= ffaend;
  5081.                      if (span.alpha < 0)
  5082.                         span.alpha = 0;
  5083.                   }
  5084.                }
  5085.  
  5086.                /* This is where we actually generate fragments */
  5087.                if (span.end > 0) {
  5088.                   span.interpMask &= ~0x001; span.arrayMask |= 0x001; fast_persp_span(ctx, &span, &info);;
  5089.                }
  5090.  
  5091.                /*
  5092.                 * Advance to the next scan line.  Compute the
  5093.                 * new edge coordinates, and adjust the
  5094.                 * pixel-center x coordinate so that it stays
  5095.                 * on or inside the major edge.
  5096.                 */
  5097.                (span.y)++;
  5098.                lines--;
  5099.  
  5100.                fxLeftEdge += fdxLeftEdge;
  5101.                fxRightEdge += fdxRightEdge;
  5102.  
  5103.  
  5104.                fError += fdError;
  5105.                if (fError >= 0) {
  5106.                   fError -= 0x00000800;
  5107.                   zRow = (GLushort *) ((GLubyte *) zRow + dZRowOuter);
  5108.                   fz += fdzOuter;
  5109.                   fogLeft += dfogOuter;
  5110.                   fr += fdrOuter;
  5111.                   fg += fdgOuter;
  5112.                   fb += fdbOuter;
  5113.                   fa += fdaOuter;
  5114.                   sLeft += dsOuter;
  5115.                   tLeft += dtOuter;
  5116.                   uLeft += duOuter;
  5117.                   vLeft += dvOuter;
  5118.                }
  5119.                else {
  5120.                   zRow = (GLushort *) ((GLubyte *) zRow + dZRowInner);
  5121.                   fz += fdzInner;
  5122.                   fogLeft += dfogInner;
  5123.                   fr += fdrInner;
  5124.                   fg += fdgInner;
  5125.                   fb += fdbInner;
  5126.                   fa += fdaInner;
  5127.                   sLeft += dsInner;
  5128.                   tLeft += dtInner;
  5129.                   uLeft += duInner;
  5130.                   vLeft += dvInner;
  5131.                }
  5132.             } /*while lines>0*/
  5133.  
  5134.          } /* for subTriangle */
  5135.  
  5136.       }
  5137.    }
  5138. }
  5139.  
  5140.  
  5141.  
  5142.  
  5143. /*
  5144.  * Render a smooth-shaded, textured, RGBA triangle.
  5145.  * Interpolate S,T,R with perspective correction, w/out mipmapping.
  5146.  */
  5147. /*
  5148.  * Triangle Rasterizer Template
  5149.  *
  5150.  * This file is #include'd to generate custom triangle rasterizers.
  5151.  *
  5152.  * The following macros may be defined to indicate what auxillary information
  5153.  * must be interplated across the triangle:
  5154.  *    INTERP_Z        - if defined, interpolate Z values
  5155.  *    INTERP_FOG      - if defined, interpolate fog values
  5156.  *    INTERP_RGB      - if defined, interpolate RGB values
  5157.  *    INTERP_ALPHA    - if defined, interpolate Alpha values (req's INTERP_RGB)
  5158.  *    INTERP_SPEC     - if defined, interpolate specular RGB values
  5159.  *    INTERP_INDEX    - if defined, interpolate color index values
  5160.  *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
  5161.  *                         (fast, simple 2-D texture mapping)
  5162.  *    INTERP_TEX      - if defined, interpolate set 0 float STRQ texcoords
  5163.  *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
  5164.  *    INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
  5165.  *    INTERP_FLOAT_RGBA - if defined, interpolate RGBA with floating point
  5166.  *    INTERP_FLOAT_SPEC - if defined, interpolate specular with floating point
  5167.  *
  5168.  * When one can directly address pixels in the color buffer the following
  5169.  * macros can be defined and used to compute pixel addresses during
  5170.  * rasterization (see pRow):
  5171.  *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
  5172.  *    BYTES_PER_ROW       - number of bytes per row in the color buffer
  5173.  *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
  5174.  *                          Y==0 at bottom of screen and increases upward.
  5175.  *
  5176.  * Similarly, for direct depth buffer access, this type is used for depth
  5177.  * buffer addressing:
  5178.  *    DEPTH_TYPE          - either GLushort or GLuint
  5179.  *
  5180.  * Optionally, one may provide one-time setup code per triangle:
  5181.  *    SETUP_CODE    - code which is to be executed once per triangle
  5182.  *    CLEANUP_CODE    - code to execute at end of triangle
  5183.  *
  5184.  * The following macro MUST be defined:
  5185.  *    RENDER_SPAN(span) - code to write a span of pixels.
  5186.  *
  5187.  * This code was designed for the origin to be in the lower-left corner.
  5188.  *
  5189.  * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
  5190.  */
  5191.  
  5192.  
  5193. /*
  5194.  * This is a bit of a hack, but it's a centralized place to enable floating-
  5195.  * point color interpolation when GLchan is actually floating point.
  5196.  */
  5197.  
  5198.  
  5199.  
  5200. static void general_textured_triangle(GLcontext *ctx, const SWvertex *v0,
  5201.                                  const SWvertex *v1,
  5202.                                  const SWvertex *v2 )
  5203. {
  5204.    typedef struct {
  5205.         const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
  5206.         GLfloat dx;    /* X(v1) - X(v0) */
  5207.         GLfloat dy;    /* Y(v1) - Y(v0) */
  5208.         GLfixed fdxdy; /* dx/dy in fixed-point */
  5209.         GLfixed fsx;   /* first sample point x coord */
  5210.         GLfixed fsy;
  5211.         GLfloat adjy;  /* adjust from v[0]->fy to fsy, scaled */
  5212.         GLint lines;   /* number of lines to be sampled on this edge */
  5213.         GLfixed fx0;   /* fixed pt X of lower endpoint */
  5214.    } EdgeT;
  5215.  
  5216.    const GLint depthBits = ctx->Visual.depthBits;
  5217.    const GLfloat maxDepth = ctx->DepthMaxF;
  5218.    EdgeT eMaj, eTop, eBot;
  5219.    GLfloat oneOverArea;
  5220.    const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
  5221.    float bf = ((SWcontext *)ctx->swrast_context)->_backface_sign;
  5222.    const GLint snapMask = ~((0x00000800 / (1 << 4)) - 1); /* for x/y coord snapping */
  5223.    GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
  5224.  
  5225.    struct sw_span span;
  5226.  
  5227.    (span).primitive = (0x0009);
  5228.    (span).interpMask = (0);
  5229.    (span).arrayMask = (0);
  5230.    (span).start = 0;
  5231.    (span).end = (0);
  5232.    (span).facing = 0;
  5233.    (span).array = ((SWcontext *)ctx->swrast_context)->SpanArrays;
  5234.  
  5235.  
  5236.    /*
  5237.    printf("%s()\n", __FUNCTION__);
  5238.    printf("  %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
  5239.    printf("  %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
  5240.    printf("  %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
  5241.     */
  5242.  
  5243.    /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
  5244.     * And find the order of the 3 vertices along the Y axis.
  5245.     */
  5246.    {
  5247.       const GLfixed fy0 = (((int) ((((v0->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v0->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v0->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  5248.       const GLfixed fy1 = (((int) ((((v1->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v1->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v1->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  5249.       const GLfixed fy2 = (((int) ((((v2->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v2->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v2->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  5250.  
  5251.       if (fy0 <= fy1) {
  5252.          if (fy1 <= fy2) {
  5253.             /* y0 <= y1 <= y2 */
  5254.             vMin = v0;   vMid = v1;   vMax = v2;
  5255.             vMin_fy = fy0;  vMid_fy = fy1;  vMax_fy = fy2;
  5256.          }
  5257.          else if (fy2 <= fy0) {
  5258.             /* y2 <= y0 <= y1 */
  5259.             vMin = v2;   vMid = v0;   vMax = v1;
  5260.             vMin_fy = fy2;  vMid_fy = fy0;  vMax_fy = fy1;
  5261.          }
  5262.          else {
  5263.             /* y0 <= y2 <= y1 */
  5264.             vMin = v0;   vMid = v2;   vMax = v1;
  5265.             vMin_fy = fy0;  vMid_fy = fy2;  vMax_fy = fy1;
  5266.             bf = -bf;
  5267.          }
  5268.       }
  5269.       else {
  5270.          if (fy0 <= fy2) {
  5271.             /* y1 <= y0 <= y2 */
  5272.             vMin = v1;   vMid = v0;   vMax = v2;
  5273.             vMin_fy = fy1;  vMid_fy = fy0;  vMax_fy = fy2;
  5274.             bf = -bf;
  5275.          }
  5276.          else if (fy2 <= fy1) {
  5277.             /* y2 <= y1 <= y0 */
  5278.             vMin = v2;   vMid = v1;   vMax = v0;
  5279.             vMin_fy = fy2;  vMid_fy = fy1;  vMax_fy = fy0;
  5280.             bf = -bf;
  5281.          }
  5282.          else {
  5283.             /* y1 <= y2 <= y0 */
  5284.             vMin = v1;   vMid = v2;   vMax = v0;
  5285.             vMin_fy = fy1;  vMid_fy = fy2;  vMax_fy = fy0;
  5286.          }
  5287.       }
  5288.  
  5289.       /* fixed point X coords */
  5290.       vMin_fx = (((int) ((((vMin->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMin->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMin->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  5291.       vMid_fx = (((int) ((((vMid->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMid->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMid->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  5292.       vMax_fx = (((int) ((((vMax->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMax->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMax->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  5293.    }
  5294.  
  5295.    /* vertex/edge relationship */
  5296.    eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
  5297.    eTop.v0 = vMid;   eTop.v1 = vMax;
  5298.    eBot.v0 = vMin;   eBot.v1 = vMid;
  5299.  
  5300.    /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
  5301.    eMaj.dx = ((vMax_fx - vMin_fx) * (1.0F / 2048.0f));
  5302.    eMaj.dy = ((vMax_fy - vMin_fy) * (1.0F / 2048.0f));
  5303.    eTop.dx = ((vMax_fx - vMid_fx) * (1.0F / 2048.0f));
  5304.    eTop.dy = ((vMax_fy - vMid_fy) * (1.0F / 2048.0f));
  5305.    eBot.dx = ((vMid_fx - vMin_fx) * (1.0F / 2048.0f));
  5306.    eBot.dy = ((vMid_fy - vMin_fy) * (1.0F / 2048.0f));
  5307.  
  5308.    /* compute area, oneOverArea and perform backface culling */
  5309.    {
  5310.       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
  5311.  
  5312.       /* Do backface culling */
  5313.       if (area * bf < 0.0)
  5314.          return;
  5315.  
  5316.       if (IS_INF_OR_NAN(area) || area == 0.0F)
  5317.          return;
  5318.  
  5319.       oneOverArea = 1.0F / area;
  5320.    }
  5321.  
  5322.    ctx->OcclusionResult = 0x1;
  5323.    span.facing = ctx->_Facing; /* for 2-sided stencil test */
  5324.  
  5325.    /* Edge setup.  For a triangle strip these could be reused... */
  5326.    {
  5327.       eMaj.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  5328.       eMaj.lines = (((((vMax_fy - eMaj.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  5329.       if (eMaj.lines > 0) {
  5330.          GLfloat dxdy = eMaj.dx / eMaj.dy;
  5331.          eMaj.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  5332.          eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
  5333.          eMaj.fx0 = vMin_fx;
  5334.          eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy);
  5335.       }
  5336.       else {
  5337.          return;  /*CULLED*/
  5338.       }
  5339.  
  5340.       eTop.fsy = (((vMid_fy) + 0x00000800 - 1) & (~0x000007FF));
  5341.       eTop.lines = (((((vMax_fy - eTop.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  5342.       if (eTop.lines > 0) {
  5343.          GLfloat dxdy = eTop.dx / eTop.dy;
  5344.          eTop.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  5345.          eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
  5346.          eTop.fx0 = vMid_fx;
  5347.          eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy);
  5348.       }
  5349.  
  5350.       eBot.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  5351.       eBot.lines = (((((vMid_fy - eBot.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  5352.       if (eBot.lines > 0) {
  5353.          GLfloat dxdy = eBot.dx / eBot.dy;
  5354.          eBot.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  5355.          eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
  5356.          eBot.fx0 = vMin_fx;
  5357.          eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy);
  5358.       }
  5359.    }
  5360.  
  5361.    /*
  5362.     * Conceptually, we view a triangle as two subtriangles
  5363.     * separated by a perfectly horizontal line.  The edge that is
  5364.     * intersected by this line is one with maximal absolute dy; we
  5365.     * call it a ``major'' edge.  The other two edges are the
  5366.     * ``top'' edge (for the upper subtriangle) and the ``bottom''
  5367.     * edge (for the lower subtriangle).  If either of these two
  5368.     * edges is horizontal or very close to horizontal, the
  5369.     * corresponding subtriangle might cover zero sample points;
  5370.     * we take care to handle such cases, for performance as well
  5371.     * as correctness.
  5372.     *
  5373.     * By stepping rasterization parameters along the major edge,
  5374.     * we can avoid recomputing them at the discontinuity where
  5375.     * the top and bottom edges meet.  However, this forces us to
  5376.     * be able to scan both left-to-right and right-to-left.
  5377.     * Also, we must determine whether the major edge is at the
  5378.     * left or right side of the triangle.  We do this by
  5379.     * computing the magnitude of the cross-product of the major
  5380.     * and top edges.  Since this magnitude depends on the sine of
  5381.     * the angle between the two edges, its sign tells us whether
  5382.     * we turn to the left or to the right when travelling along
  5383.     * the major edge to the top edge, and from this we infer
  5384.     * whether the major edge is on the left or the right.
  5385.     *
  5386.     * Serendipitously, this cross-product magnitude is also a
  5387.     * value we need to compute the iteration parameter
  5388.     * derivatives for the triangle, and it can be used to perform
  5389.     * backface culling because its sign tells us whether the
  5390.     * triangle is clockwise or counterclockwise.  In this code we
  5391.     * refer to it as ``area'' because it's also proportional to
  5392.     * the pixel area of the triangle.
  5393.     */
  5394.  
  5395.    {
  5396.       GLint scan_from_left_to_right;  /* true if scanning left-to-right */
  5397.       GLfloat dzdx, dzdy;
  5398.       GLfloat dfogdy;
  5399.       GLfloat drdx, drdy;
  5400.       GLfloat dgdx, dgdy;
  5401.       GLfloat dbdx, dbdy;
  5402.       GLfloat dadx, dady;
  5403.       GLfloat dsrdx, dsrdy;
  5404.       GLfloat dsgdx, dsgdy;
  5405.       GLfloat dsbdx, dsbdy;
  5406.       GLfloat dsdx, dsdy;
  5407.       GLfloat dtdx, dtdy;
  5408.       GLfloat dudx, dudy;
  5409.       GLfloat dvdx, dvdy;
  5410.  
  5411.       /*
  5412.        * Execute user-supplied setup code
  5413.        */
  5414.  
  5415.       scan_from_left_to_right = (oneOverArea < 0.0F);
  5416.  
  5417.  
  5418.       /* compute d?/dx and d?/dy derivatives */
  5419.       span.interpMask |= 0x008;
  5420.       {
  5421.          GLfloat eMaj_dz, eBot_dz;
  5422.          eMaj_dz = vMax->win[2] - vMin->win[2];
  5423.          eBot_dz = vMid->win[2] - vMin->win[2];
  5424.          dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
  5425.          if (dzdx > maxDepth || dzdx < -maxDepth) {
  5426.             /* probably a sliver triangle */
  5427.             dzdx = 0.0;
  5428.             dzdy = 0.0;
  5429.          }
  5430.          else {
  5431.             dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
  5432.          }
  5433.          if (depthBits <= 16)
  5434.             span.zStep = (((int) ((((dzdx) * 2048.0f) >= 0.0F) ? (((dzdx) * 2048.0f) + 0.5F) : (((dzdx) * 2048.0f) - 0.5F))));
  5435.          else
  5436.             span.zStep = (GLint) dzdx;
  5437.       }
  5438.       span.interpMask |= 0x010;
  5439.       {
  5440.          const GLfloat eMaj_dfog = vMax->fog - vMin->fog;
  5441.          const GLfloat eBot_dfog = vMid->fog - vMin->fog;
  5442.          span.fogStep = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
  5443.          dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
  5444.       }
  5445.       span.interpMask |= 0x001;
  5446.       if (ctx->Light.ShadeModel == 0x1D01) {
  5447.          GLfloat eMaj_dr, eBot_dr;
  5448.          GLfloat eMaj_dg, eBot_dg;
  5449.          GLfloat eMaj_db, eBot_db;
  5450.          GLfloat eMaj_da, eBot_da;
  5451.          eMaj_dr = (GLfloat) ((GLint) vMax->color[0] -
  5452.                              (GLint) vMin->color[0]);
  5453.          eBot_dr = (GLfloat) ((GLint) vMid->color[0] -
  5454.                              (GLint) vMin->color[0]);
  5455.          drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
  5456.          span.redStep = (((int) ((((drdx) * 2048.0f) >= 0.0F) ? (((drdx) * 2048.0f) + 0.5F) : (((drdx) * 2048.0f) - 0.5F))));
  5457.          drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
  5458.          eMaj_dg = (GLfloat) ((GLint) vMax->color[1] -
  5459.                              (GLint) vMin->color[1]);
  5460.          eBot_dg = (GLfloat) ((GLint) vMid->color[1] -
  5461.                              (GLint) vMin->color[1]);
  5462.          dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
  5463.          span.greenStep = (((int) ((((dgdx) * 2048.0f) >= 0.0F) ? (((dgdx) * 2048.0f) + 0.5F) : (((dgdx) * 2048.0f) - 0.5F))));
  5464.          dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
  5465.          eMaj_db = (GLfloat) ((GLint) vMax->color[2] -
  5466.                              (GLint) vMin->color[2]);
  5467.          eBot_db = (GLfloat) ((GLint) vMid->color[2] -
  5468.                              (GLint) vMin->color[2]);
  5469.          dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
  5470.          span.blueStep = (((int) ((((dbdx) * 2048.0f) >= 0.0F) ? (((dbdx) * 2048.0f) + 0.5F) : (((dbdx) * 2048.0f) - 0.5F))));
  5471.          dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
  5472.          eMaj_da = (GLfloat) ((GLint) vMax->color[3] -
  5473.                              (GLint) vMin->color[3]);
  5474.          eBot_da = (GLfloat) ((GLint) vMid->color[3] -
  5475.                              (GLint) vMin->color[3]);
  5476.          dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
  5477.          span.alphaStep = (((int) ((((dadx) * 2048.0f) >= 0.0F) ? (((dadx) * 2048.0f) + 0.5F) : (((dadx) * 2048.0f) - 0.5F))));
  5478.          dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
  5479.       }
  5480.       else {
  5481.          ;
  5482.          span.interpMask |= 0x200;
  5483.          drdx = drdy = 0.0F;
  5484.          dgdx = dgdy = 0.0F;
  5485.          dbdx = dbdy = 0.0F;
  5486.          span.redStep = 0;
  5487.          span.greenStep = 0;
  5488.          span.blueStep = 0;
  5489.          dadx = dady = 0.0F;
  5490.          span.alphaStep = 0;
  5491.       }
  5492.       span.interpMask |= 0x002;
  5493.       if (ctx->Light.ShadeModel == 0x1D01) {
  5494.          GLfloat eMaj_dsr, eBot_dsr;
  5495.          GLfloat eMaj_dsg, eBot_dsg;
  5496.          GLfloat eMaj_dsb, eBot_dsb;
  5497.          eMaj_dsr = (GLfloat) ((GLint) vMax->specular[0] -
  5498.                               (GLint) vMin->specular[0]);
  5499.          eBot_dsr = (GLfloat) ((GLint) vMid->specular[0] -
  5500.                               (GLint) vMin->specular[0]);
  5501.          dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr);
  5502.          span.specRedStep = (((int) ((((dsrdx) * 2048.0f) >= 0.0F) ? (((dsrdx) * 2048.0f) + 0.5F) : (((dsrdx) * 2048.0f) - 0.5F))));
  5503.          dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx);
  5504.          eMaj_dsg = (GLfloat) ((GLint) vMax->specular[1] -
  5505.                               (GLint) vMin->specular[1]);
  5506.          eBot_dsg = (GLfloat) ((GLint) vMid->specular[1] -
  5507.                               (GLint) vMin->specular[1]);
  5508.          dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg);
  5509.          span.specGreenStep = (((int) ((((dsgdx) * 2048.0f) >= 0.0F) ? (((dsgdx) * 2048.0f) + 0.5F) : (((dsgdx) * 2048.0f) - 0.5F))));
  5510.          dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx);
  5511.          eMaj_dsb = (GLfloat) ((GLint) vMax->specular[2] -
  5512.                               (GLint) vMin->specular[2]);
  5513.          eBot_dsb = (GLfloat) ((GLint) vMid->specular[2] -
  5514.                               (GLint) vMin->specular[2]);
  5515.          dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb);
  5516.          span.specBlueStep = (((int) ((((dsbdx) * 2048.0f) >= 0.0F) ? (((dsbdx) * 2048.0f) + 0.5F) : (((dsbdx) * 2048.0f) - 0.5F))));
  5517.          dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx);
  5518.       }
  5519.       else {
  5520.          dsrdx = dsrdy = 0.0F;
  5521.          dsgdx = dsgdy = 0.0F;
  5522.          dsbdx = dsbdy = 0.0F;
  5523.          span.specRedStep = 0;
  5524.          span.specGreenStep = 0;
  5525.          span.specBlueStep = 0;
  5526.       }
  5527.       span.interpMask |= 0x020;
  5528.       {
  5529.          GLfloat wMax = vMax->win[3];
  5530.          GLfloat wMin = vMin->win[3];
  5531.          GLfloat wMid = vMid->win[3];
  5532.          GLfloat eMaj_ds, eBot_ds;
  5533.          GLfloat eMaj_dt, eBot_dt;
  5534.          GLfloat eMaj_du, eBot_du;
  5535.          GLfloat eMaj_dv, eBot_dv;
  5536.  
  5537.          eMaj_ds = vMax->texcoord[0][0] * wMax - vMin->texcoord[0][0] * wMin;
  5538.          eBot_ds = vMid->texcoord[0][0] * wMid - vMin->texcoord[0][0] * wMin;
  5539.          dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
  5540.          dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
  5541.          span.texStepX[0][0] = dsdx;
  5542.          span.texStepY[0][0] = dsdy;
  5543.  
  5544.          eMaj_dt = vMax->texcoord[0][1] * wMax - vMin->texcoord[0][1] * wMin;
  5545.          eBot_dt = vMid->texcoord[0][1] * wMid - vMin->texcoord[0][1] * wMin;
  5546.          dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
  5547.          dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
  5548.          span.texStepX[0][1] = dtdx;
  5549.          span.texStepY[0][1] = dtdy;
  5550.  
  5551.          eMaj_du = vMax->texcoord[0][2] * wMax - vMin->texcoord[0][2] * wMin;
  5552.          eBot_du = vMid->texcoord[0][2] * wMid - vMin->texcoord[0][2] * wMin;
  5553.          dudx = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
  5554.          dudy = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
  5555.          span.texStepX[0][2] = dudx;
  5556.          span.texStepY[0][2] = dudy;
  5557.  
  5558.          eMaj_dv = vMax->texcoord[0][3] * wMax - vMin->texcoord[0][3] * wMin;
  5559.          eBot_dv = vMid->texcoord[0][3] * wMid - vMin->texcoord[0][3] * wMin;
  5560.          dvdx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
  5561.          dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
  5562.          span.texStepX[0][3] = dvdx;
  5563.          span.texStepY[0][3] = dvdy;
  5564.       }
  5565.  
  5566.       /*
  5567.        * We always sample at pixel centers.  However, we avoid
  5568.        * explicit half-pixel offsets in this code by incorporating
  5569.        * the proper offset in each of x and y during the
  5570.        * transformation to window coordinates.
  5571.        *
  5572.        * We also apply the usual rasterization rules to prevent
  5573.        * cracks and overlaps.  A pixel is considered inside a
  5574.        * subtriangle if it meets all of four conditions: it is on or
  5575.        * to the right of the left edge, strictly to the left of the
  5576.        * right edge, on or below the top edge, and strictly above
  5577.        * the bottom edge.  (Some edges may be degenerate.)
  5578.        *
  5579.        * The following discussion assumes left-to-right scanning
  5580.        * (that is, the major edge is on the left); the right-to-left
  5581.        * case is a straightforward variation.
  5582.        *
  5583.        * We start by finding the half-integral y coordinate that is
  5584.        * at or below the top of the triangle.  This gives us the
  5585.        * first scan line that could possibly contain pixels that are
  5586.        * inside the triangle.
  5587.        *
  5588.        * Next we creep down the major edge until we reach that y,
  5589.        * and compute the corresponding x coordinate on the edge.
  5590.        * Then we find the half-integral x that lies on or just
  5591.        * inside the edge.  This is the first pixel that might lie in
  5592.        * the interior of the triangle.  (We won't know for sure
  5593.        * until we check the other edges.)
  5594.        *
  5595.        * As we rasterize the triangle, we'll step down the major
  5596.        * edge.  For each step in y, we'll move an integer number
  5597.        * of steps in x.  There are two possible x step sizes, which
  5598.        * we'll call the ``inner'' step (guaranteed to land on the
  5599.        * edge or inside it) and the ``outer'' step (guaranteed to
  5600.        * land on the edge or outside it).  The inner and outer steps
  5601.        * differ by one.  During rasterization we maintain an error
  5602.        * term that indicates our distance from the true edge, and
  5603.        * select either the inner step or the outer step, whichever
  5604.        * gets us to the first pixel that falls inside the triangle.
  5605.        *
  5606.        * All parameters (z, red, etc.) as well as the buffer
  5607.        * addresses for color and z have inner and outer step values,
  5608.        * so that we can increment them appropriately.  This method
  5609.        * eliminates the need to adjust parameters by creeping a
  5610.        * sub-pixel amount into the triangle at each scanline.
  5611.        */
  5612.  
  5613.       {
  5614.          int subTriangle;
  5615.          GLfixed fx;
  5616.          GLfixed fxLeftEdge = 0, fxRightEdge = 0;
  5617.          GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
  5618.          GLfixed fdxOuter;
  5619.          int idxOuter;
  5620.          float dxOuter;
  5621.          GLfixed fError = 0, fdError = 0;
  5622.          float adjx, adjy;
  5623.          GLfixed fy;
  5624.          GLushort *zRow = 0;
  5625.          int dZRowOuter = 0, dZRowInner;  /* offset in bytes */
  5626.          GLfixed fz = 0, fdzOuter = 0, fdzInner;
  5627.          GLfloat fogLeft = 0, dfogOuter = 0, dfogInner;
  5628.          GLfixed fr = 0, fdrOuter = 0, fdrInner;
  5629.          GLfixed fg = 0, fdgOuter = 0, fdgInner;
  5630.          GLfixed fb = 0, fdbOuter = 0, fdbInner;
  5631.          GLfixed fa = 0, fdaOuter = 0, fdaInner;
  5632.          GLfixed fsr=0, fdsrOuter=0, fdsrInner;
  5633.          GLfixed fsg=0, fdsgOuter=0, fdsgInner;
  5634.          GLfixed fsb=0, fdsbOuter=0, fdsbInner;
  5635.          GLfloat sLeft=0, dsOuter=0, dsInner;
  5636.          GLfloat tLeft=0, dtOuter=0, dtInner;
  5637.          GLfloat uLeft=0, duOuter=0, duInner;
  5638.          GLfloat vLeft=0, dvOuter=0, dvInner;
  5639.  
  5640.          for (subTriangle=0; subTriangle<=1; subTriangle++) {
  5641.             EdgeT *eLeft, *eRight;
  5642.             int setupLeft, setupRight;
  5643.             int lines;
  5644.  
  5645.             if (subTriangle==0) {
  5646.                /* bottom half */
  5647.                if (scan_from_left_to_right) {
  5648.                   eLeft = &eMaj;
  5649.                   eRight = &eBot;
  5650.                   lines = eRight->lines;
  5651.                   setupLeft = 1;
  5652.                   setupRight = 1;
  5653.                }
  5654.                else {
  5655.                   eLeft = &eBot;
  5656.                   eRight = &eMaj;
  5657.                   lines = eLeft->lines;
  5658.                   setupLeft = 1;
  5659.                   setupRight = 1;
  5660.                }
  5661.             }
  5662.             else {
  5663.                /* top half */
  5664.                if (scan_from_left_to_right) {
  5665.                   eLeft = &eMaj;
  5666.                   eRight = &eTop;
  5667.                   lines = eRight->lines;
  5668.                   setupLeft = 0;
  5669.                   setupRight = 1;
  5670.                }
  5671.                else {
  5672.                   eLeft = &eTop;
  5673.                   eRight = &eMaj;
  5674.                   lines = eLeft->lines;
  5675.                   setupLeft = 1;
  5676.                   setupRight = 0;
  5677.                }
  5678.                if (lines == 0)
  5679.                   return;
  5680.             }
  5681.  
  5682.             if (setupLeft && eLeft->lines > 0) {
  5683.                const SWvertex *vLower;
  5684.                GLfixed fsx = eLeft->fsx;
  5685.                fx = (((fsx) + 0x00000800 - 1) & (~0x000007FF));
  5686.                fError = fx - fsx - 0x00000800;
  5687.                fxLeftEdge = fsx - 1;
  5688.                fdxLeftEdge = eLeft->fdxdy;
  5689.                fdxOuter = ((fdxLeftEdge - 1) & (~0x000007FF));
  5690.                fdError = fdxOuter - fdxLeftEdge + 0x00000800;
  5691.                idxOuter = ((fdxOuter) >> 11);
  5692.                dxOuter = (float) idxOuter;
  5693.                (void) dxOuter;
  5694.  
  5695.                fy = eLeft->fsy;
  5696.                span.y = ((fy) >> 11);
  5697.  
  5698.                adjx = (float)(fx - eLeft->fx0);  /* SCALED! */
  5699.                adjy = eLeft->adjy;              /* SCALED! */
  5700.                vLower = eLeft->v0;
  5701.  
  5702.                /*
  5703.                 * Now we need the set of parameter (z, color, etc.) values at
  5704.                 * the point (fx, fy).  This gives us properly-sampled parameter
  5705.                 * values that we can step from pixel to pixel.  Furthermore,
  5706.                 * although we might have intermediate results that overflow
  5707.                 * the normal parameter range when we step temporarily outside
  5708.                 * the triangle, we shouldn't overflow or underflow for any
  5709.                 * pixel that's actually inside the triangle.
  5710.                 */
  5711.  
  5712.                {
  5713.                   GLfloat z0 = vLower->win[2];
  5714.                   if (depthBits <= 16) {
  5715.                      /* interpolate fixed-pt values */
  5716.                      GLfloat tmp = (z0 * 2048.0f +
  5717.                                     dzdx * adjx + dzdy * adjy) + 0x00000400;
  5718.                      if (tmp < 0xffffffff / 2)
  5719.                         fz = (GLfixed) tmp;
  5720.                      else
  5721.                         fz = 0xffffffff / 2;
  5722.                      fdzOuter = (((int) ((((dzdy + dxOuter * dzdx) * 2048.0f) >= 0.0F) ? (((dzdy + dxOuter * dzdx) * 2048.0f) + 0.5F) : (((dzdy + dxOuter * dzdx) * 2048.0f) - 0.5F))));
  5723.                   }
  5724.                   else {
  5725.                      /* interpolate depth values exactly */
  5726.                      fz = (GLint) (z0 + dzdx * ((adjx) * (1.0F / 2048.0f))
  5727.                                    + dzdy * ((adjy) * (1.0F / 2048.0f)));
  5728.                      fdzOuter = (GLint) (dzdy + dxOuter * dzdx);
  5729.                   }
  5730.                   zRow = (GLushort *)
  5731.                     _mesa_zbuffer_address(ctx, ((fxLeftEdge) >> 11), span.y);
  5732.                   dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(GLushort);
  5733.                }
  5734.                fogLeft = vLower->fog + (span.fogStep * adjx + dfogdy * adjy)
  5735.                                        * (1.0F/2048.0f);
  5736.                dfogOuter = dfogdy + dxOuter * span.fogStep;
  5737.                if (ctx->Light.ShadeModel == 0x1D01) {
  5738.                   fr = (GLfixed) (((vLower->color[0]) << 11)
  5739.                                    + drdx * adjx + drdy * adjy) + 0x00000400;
  5740.                   fdrOuter = (((int) ((((drdy + dxOuter * drdx) * 2048.0f) >= 0.0F) ? (((drdy + dxOuter * drdx) * 2048.0f) + 0.5F) : (((drdy + dxOuter * drdx) * 2048.0f) - 0.5F))));
  5741.                   fg = (GLfixed) (((vLower->color[1]) << 11)
  5742.                                    + dgdx * adjx + dgdy * adjy) + 0x00000400;
  5743.                   fdgOuter = (((int) ((((dgdy + dxOuter * dgdx) * 2048.0f) >= 0.0F) ? (((dgdy + dxOuter * dgdx) * 2048.0f) + 0.5F) : (((dgdy + dxOuter * dgdx) * 2048.0f) - 0.5F))));
  5744.                   fb = (GLfixed) (((vLower->color[2]) << 11)
  5745.                                     + dbdx * adjx + dbdy * adjy) + 0x00000400;
  5746.                   fdbOuter = (((int) ((((dbdy + dxOuter * dbdx) * 2048.0f) >= 0.0F) ? (((dbdy + dxOuter * dbdx) * 2048.0f) + 0.5F) : (((dbdy + dxOuter * dbdx) * 2048.0f) - 0.5F))));
  5747.                   fa = (GLfixed) (((vLower->color[3]) << 11)
  5748.                                    + dadx * adjx + dady * adjy) + 0x00000400;
  5749.                   fdaOuter = (((int) ((((dady + dxOuter * dadx) * 2048.0f) >= 0.0F) ? (((dady + dxOuter * dadx) * 2048.0f) + 0.5F) : (((dady + dxOuter * dadx) * 2048.0f) - 0.5F))));
  5750.                }
  5751.                else {
  5752.                   ;
  5753.                   fr = ((v2->color[0]) << 11);
  5754.                   fg = ((v2->color[1]) << 11);
  5755.                   fb = ((v2->color[2]) << 11);
  5756.                   fdrOuter = fdgOuter = fdbOuter = 0;
  5757.                   fa =  ((v2->color[3]) << 11);
  5758.                   fdaOuter = 0;
  5759.                }
  5760.                if (ctx->Light.ShadeModel == 0x1D01) {
  5761.                   fsr = (GLfixed) (((vLower->specular[0]) << 11)
  5762.                                    + dsrdx * adjx + dsrdy * adjy) + 0x00000400;
  5763.                   fdsrOuter = (((int) ((((dsrdy + dxOuter * dsrdx) * 2048.0f) >= 0.0F) ? (((dsrdy + dxOuter * dsrdx) * 2048.0f) + 0.5F) : (((dsrdy + dxOuter * dsrdx) * 2048.0f) - 0.5F))));
  5764.                   fsg = (GLfixed) (((vLower->specular[1]) << 11)
  5765.                                    + dsgdx * adjx + dsgdy * adjy) + 0x00000400;
  5766.                   fdsgOuter = (((int) ((((dsgdy + dxOuter * dsgdx) * 2048.0f) >= 0.0F) ? (((dsgdy + dxOuter * dsgdx) * 2048.0f) + 0.5F) : (((dsgdy + dxOuter * dsgdx) * 2048.0f) - 0.5F))));
  5767.                   fsb = (GLfixed) (((vLower->specular[2]) << 11)
  5768.                                    + dsbdx * adjx + dsbdy * adjy) + 0x00000400;
  5769.                   fdsbOuter = (((int) ((((dsbdy + dxOuter * dsbdx) * 2048.0f) >= 0.0F) ? (((dsbdy + dxOuter * dsbdx) * 2048.0f) + 0.5F) : (((dsbdy + dxOuter * dsbdx) * 2048.0f) - 0.5F))));
  5770.                }
  5771.                else {
  5772.                   fsr = ((v2->specular[0]) << 11);
  5773.                   fsg = ((v2->specular[1]) << 11);
  5774.                   fsb = ((v2->specular[2]) << 11);
  5775.                   fdsrOuter = fdsgOuter = fdsbOuter = 0;
  5776.                }
  5777.                {
  5778.                   GLfloat invW = vLower->win[3];
  5779.                   GLfloat s0, t0, u0, v0;
  5780.                   s0 = vLower->texcoord[0][0] * invW;
  5781.                   sLeft = s0 + (span.texStepX[0][0] * adjx + dsdy * adjy)
  5782.                      * (1.0F/2048.0f);
  5783.                   dsOuter = dsdy + dxOuter * span.texStepX[0][0];
  5784.                   t0 = vLower->texcoord[0][1] * invW;
  5785.                   tLeft = t0 + (span.texStepX[0][1] * adjx + dtdy * adjy)
  5786.                      * (1.0F/2048.0f);
  5787.                   dtOuter = dtdy + dxOuter * span.texStepX[0][1];
  5788.                   u0 = vLower->texcoord[0][2] * invW;
  5789.                   uLeft = u0 + (span.texStepX[0][2] * adjx + dudy * adjy)
  5790.                      * (1.0F/2048.0f);
  5791.                   duOuter = dudy + dxOuter * span.texStepX[0][2];
  5792.                   v0 = vLower->texcoord[0][3] * invW;
  5793.                   vLeft = v0 + (span.texStepX[0][3] * adjx + dvdy * adjy)
  5794.                      * (1.0F/2048.0f);
  5795.                   dvOuter = dvdy + dxOuter * span.texStepX[0][3];
  5796.                }
  5797.  
  5798.             } /*if setupLeft*/
  5799.  
  5800.  
  5801.             if (setupRight && eRight->lines>0) {
  5802.                fxRightEdge = eRight->fsx - 1;
  5803.                fdxRightEdge = eRight->fdxdy;
  5804.             }
  5805.  
  5806.             if (lines==0) {
  5807.                continue;
  5808.             }
  5809.  
  5810.  
  5811.             /* Rasterize setup */
  5812.             dZRowInner = dZRowOuter + sizeof(GLushort);
  5813.             fdzInner = fdzOuter + span.zStep;
  5814.             dfogInner = dfogOuter + span.fogStep;
  5815.             fdrInner = fdrOuter + span.redStep;
  5816.             fdgInner = fdgOuter + span.greenStep;
  5817.             fdbInner = fdbOuter + span.blueStep;
  5818.             fdaInner = fdaOuter + span.alphaStep;
  5819.             fdsrInner = fdsrOuter + span.specRedStep;
  5820.             fdsgInner = fdsgOuter + span.specGreenStep;
  5821.             fdsbInner = fdsbOuter + span.specBlueStep;
  5822.             dsInner = dsOuter + span.texStepX[0][0];
  5823.             dtInner = dtOuter + span.texStepX[0][1];
  5824.             duInner = duOuter + span.texStepX[0][2];
  5825.             dvInner = dvOuter + span.texStepX[0][3];
  5826.  
  5827.             while (lines > 0) {
  5828.                /* initialize the span interpolants to the leftmost value */
  5829.                /* ff = fixed-pt fragment */
  5830.                const GLint right = ((fxRightEdge) >> 11);
  5831.  
  5832.                span.x = ((fxLeftEdge) >> 11);
  5833.  
  5834.                if (right <= span.x)
  5835.                   span.end = 0;
  5836.                else
  5837.                   span.end = right - span.x;
  5838.  
  5839.                span.z = fz;
  5840.                span.fog = fogLeft;
  5841.                span.red = fr;
  5842.                span.green = fg;
  5843.                span.blue = fb;
  5844.                span.alpha = fa;
  5845.                span.specRed = fsr;
  5846.                span.specGreen = fsg;
  5847.                span.specBlue = fsb;
  5848.  
  5849.                span.tex[0][0] = sLeft;
  5850.                span.tex[0][1] = tLeft;
  5851.                span.tex[0][2] = uLeft;
  5852.                span.tex[0][3] = vLeft;
  5853.  
  5854.  
  5855.                {
  5856.                   /* need this to accomodate round-off errors */
  5857.                   const GLint len = right - span.x - 1;
  5858.                   GLfixed ffrend = span.red + len * span.redStep;
  5859.                   GLfixed ffgend = span.green + len * span.greenStep;
  5860.                   GLfixed ffbend = span.blue + len * span.blueStep;
  5861.                   if (ffrend < 0) {
  5862.                      span.red -= ffrend;
  5863.                      if (span.red < 0)
  5864.                         span.red = 0;
  5865.                   }
  5866.                   if (ffgend < 0) {
  5867.                      span.green -= ffgend;
  5868.                      if (span.green < 0)
  5869.                         span.green = 0;
  5870.                   }
  5871.                   if (ffbend < 0) {
  5872.                      span.blue -= ffbend;
  5873.                      if (span.blue < 0)
  5874.                         span.blue = 0;
  5875.                   }
  5876.                }
  5877.                {
  5878.                   const GLint len = right - span.x - 1;
  5879.                   GLfixed ffaend = span.alpha + len * span.alphaStep;
  5880.                   if (ffaend < 0) {
  5881.                      span.alpha -= ffaend;
  5882.                      if (span.alpha < 0)
  5883.                         span.alpha = 0;
  5884.                   }
  5885.                }
  5886.                {
  5887.                   /* need this to accomodate round-off errors */
  5888.                   const GLint len = right - span.x - 1;
  5889.                   GLfixed ffsrend = span.specRed + len * span.specRedStep;
  5890.                   GLfixed ffsgend = span.specGreen + len * span.specGreenStep;
  5891.                   GLfixed ffsbend = span.specBlue + len * span.specBlueStep;
  5892.                   if (ffsrend < 0) {
  5893.                      span.specRed -= ffsrend;
  5894.                      if (span.specRed < 0)
  5895.                         span.specRed = 0;
  5896.                   }
  5897.                   if (ffsgend < 0) {
  5898.                      span.specGreen -= ffsgend;
  5899.                      if (span.specGreen < 0)
  5900.                         span.specGreen = 0;
  5901.                   }
  5902.                   if (ffsbend < 0) {
  5903.                      span.specBlue -= ffsbend;
  5904.                      if (span.specBlue < 0)
  5905.                         span.specBlue = 0;
  5906.                   }
  5907.                }
  5908.  
  5909.                /* This is where we actually generate fragments */
  5910.                if (span.end > 0) {
  5911.                   _mesa_write_texture_span(ctx, &span);;
  5912.                }
  5913.  
  5914.                /*
  5915.                 * Advance to the next scan line.  Compute the
  5916.                 * new edge coordinates, and adjust the
  5917.                 * pixel-center x coordinate so that it stays
  5918.                 * on or inside the major edge.
  5919.                 */
  5920.                (span.y)++;
  5921.                lines--;
  5922.  
  5923.                fxLeftEdge += fdxLeftEdge;
  5924.                fxRightEdge += fdxRightEdge;
  5925.  
  5926.  
  5927.                fError += fdError;
  5928.                if (fError >= 0) {
  5929.                   fError -= 0x00000800;
  5930.                   zRow = (GLushort *) ((GLubyte *) zRow + dZRowOuter);
  5931.                   fz += fdzOuter;
  5932.                   fogLeft += dfogOuter;
  5933.                   fr += fdrOuter;
  5934.                   fg += fdgOuter;
  5935.                   fb += fdbOuter;
  5936.                   fa += fdaOuter;
  5937.                   fsr += fdsrOuter;
  5938.                   fsg += fdsgOuter;
  5939.                   fsb += fdsbOuter;
  5940.                   sLeft += dsOuter;
  5941.                   tLeft += dtOuter;
  5942.                   uLeft += duOuter;
  5943.                   vLeft += dvOuter;
  5944.                }
  5945.                else {
  5946.                   zRow = (GLushort *) ((GLubyte *) zRow + dZRowInner);
  5947.                   fz += fdzInner;
  5948.                   fogLeft += dfogInner;
  5949.                   fr += fdrInner;
  5950.                   fg += fdgInner;
  5951.                   fb += fdbInner;
  5952.                   fa += fdaInner;
  5953.                   fsr += fdsrInner;
  5954.                   fsg += fdsgInner;
  5955.                   fsb += fdsbInner;
  5956.                   sLeft += dsInner;
  5957.                   tLeft += dtInner;
  5958.                   uLeft += duInner;
  5959.                   vLeft += dvInner;
  5960.                }
  5961.             } /*while lines>0*/
  5962.  
  5963.          } /* for subTriangle */
  5964.  
  5965.       }
  5966.    }
  5967. }
  5968.  
  5969.  
  5970.  
  5971. /*
  5972.  * This is the big one!
  5973.  * Interpolate Z, RGB, Alpha, specular, fog, and N sets of texture coordinates.
  5974.  * Yup, it's slow.
  5975.  */
  5976.  
  5977. /*
  5978.  * Triangle Rasterizer Template
  5979.  *
  5980.  * This file is #include'd to generate custom triangle rasterizers.
  5981.  *
  5982.  * The following macros may be defined to indicate what auxillary information
  5983.  * must be interplated across the triangle:
  5984.  *    INTERP_Z        - if defined, interpolate Z values
  5985.  *    INTERP_FOG      - if defined, interpolate fog values
  5986.  *    INTERP_RGB      - if defined, interpolate RGB values
  5987.  *    INTERP_ALPHA    - if defined, interpolate Alpha values (req's INTERP_RGB)
  5988.  *    INTERP_SPEC     - if defined, interpolate specular RGB values
  5989.  *    INTERP_INDEX    - if defined, interpolate color index values
  5990.  *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
  5991.  *                         (fast, simple 2-D texture mapping)
  5992.  *    INTERP_TEX      - if defined, interpolate set 0 float STRQ texcoords
  5993.  *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
  5994.  *    INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
  5995.  *    INTERP_FLOAT_RGBA - if defined, interpolate RGBA with floating point
  5996.  *    INTERP_FLOAT_SPEC - if defined, interpolate specular with floating point
  5997.  *
  5998.  * When one can directly address pixels in the color buffer the following
  5999.  * macros can be defined and used to compute pixel addresses during
  6000.  * rasterization (see pRow):
  6001.  *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
  6002.  *    BYTES_PER_ROW       - number of bytes per row in the color buffer
  6003.  *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
  6004.  *                          Y==0 at bottom of screen and increases upward.
  6005.  *
  6006.  * Similarly, for direct depth buffer access, this type is used for depth
  6007.  * buffer addressing:
  6008.  *    DEPTH_TYPE          - either GLushort or GLuint
  6009.  *
  6010.  * Optionally, one may provide one-time setup code per triangle:
  6011.  *    SETUP_CODE    - code which is to be executed once per triangle
  6012.  *    CLEANUP_CODE    - code to execute at end of triangle
  6013.  *
  6014.  * The following macro MUST be defined:
  6015.  *    RENDER_SPAN(span) - code to write a span of pixels.
  6016.  *
  6017.  * This code was designed for the origin to be in the lower-left corner.
  6018.  *
  6019.  * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
  6020.  */
  6021.  
  6022.  
  6023. /*
  6024.  * This is a bit of a hack, but it's a centralized place to enable floating-
  6025.  * point color interpolation when GLchan is actually floating point.
  6026.  */
  6027.  
  6028.  
  6029.  
  6030. static void multitextured_triangle(GLcontext *ctx, const SWvertex *v0,
  6031.                                  const SWvertex *v1,
  6032.                                  const SWvertex *v2 )
  6033. {
  6034.    typedef struct {
  6035.         const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
  6036.         GLfloat dx;    /* X(v1) - X(v0) */
  6037.         GLfloat dy;    /* Y(v1) - Y(v0) */
  6038.         GLfixed fdxdy; /* dx/dy in fixed-point */
  6039.         GLfixed fsx;   /* first sample point x coord */
  6040.         GLfixed fsy;
  6041.         GLfloat adjy;  /* adjust from v[0]->fy to fsy, scaled */
  6042.         GLint lines;   /* number of lines to be sampled on this edge */
  6043.         GLfixed fx0;   /* fixed pt X of lower endpoint */
  6044.    } EdgeT;
  6045.  
  6046.    const GLint depthBits = ctx->Visual.depthBits;
  6047.    const GLfloat maxDepth = ctx->DepthMaxF;
  6048.    EdgeT eMaj, eTop, eBot;
  6049.    GLfloat oneOverArea;
  6050.    const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
  6051.    float bf = ((SWcontext *)ctx->swrast_context)->_backface_sign;
  6052.    const GLint snapMask = ~((0x00000800 / (1 << 4)) - 1); /* for x/y coord snapping */
  6053.    GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
  6054.  
  6055.    struct sw_span span;
  6056.  
  6057.    do { (span).primitive = (0x0009); (span).interpMask = (0); (span).arrayMask = (0); (span).start = 0; (span).end = (0); (span).facing = 0; (span).array = ((SWcontext *)ctx->swrast_context)->SpanArrays; } while (0);
  6058.  
  6059.  
  6060.    printf("%s()\n", __FUNCTION__);
  6061.    /*
  6062.    printf("  %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
  6063.    printf("  %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
  6064.    printf("  %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
  6065.     */
  6066.  
  6067.    /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
  6068.     * And find the order of the 3 vertices along the Y axis.
  6069.     */
  6070.    {
  6071.       const GLfixed fy0 = (((int) ((((v0->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v0->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v0->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  6072.       const GLfixed fy1 = (((int) ((((v1->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v1->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v1->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  6073.       const GLfixed fy2 = (((int) ((((v2->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v2->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v2->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  6074.  
  6075.       if (fy0 <= fy1) {
  6076.          if (fy1 <= fy2) {
  6077.             /* y0 <= y1 <= y2 */
  6078.             vMin = v0;   vMid = v1;   vMax = v2;
  6079.             vMin_fy = fy0;  vMid_fy = fy1;  vMax_fy = fy2;
  6080.          }
  6081.          else if (fy2 <= fy0) {
  6082.             /* y2 <= y0 <= y1 */
  6083.             vMin = v2;   vMid = v0;   vMax = v1;
  6084.             vMin_fy = fy2;  vMid_fy = fy0;  vMax_fy = fy1;
  6085.          }
  6086.          else {
  6087.             /* y0 <= y2 <= y1 */
  6088.             vMin = v0;   vMid = v2;   vMax = v1;
  6089.             vMin_fy = fy0;  vMid_fy = fy2;  vMax_fy = fy1;
  6090.             bf = -bf;
  6091.          }
  6092.       }
  6093.       else {
  6094.          if (fy0 <= fy2) {
  6095.             /* y1 <= y0 <= y2 */
  6096.             vMin = v1;   vMid = v0;   vMax = v2;
  6097.             vMin_fy = fy1;  vMid_fy = fy0;  vMax_fy = fy2;
  6098.             bf = -bf;
  6099.          }
  6100.          else if (fy2 <= fy1) {
  6101.             /* y2 <= y1 <= y0 */
  6102.             vMin = v2;   vMid = v1;   vMax = v0;
  6103.             vMin_fy = fy2;  vMid_fy = fy1;  vMax_fy = fy0;
  6104.             bf = -bf;
  6105.          }
  6106.          else {
  6107.             /* y1 <= y2 <= y0 */
  6108.             vMin = v1;   vMid = v2;   vMax = v0;
  6109.             vMin_fy = fy1;  vMid_fy = fy2;  vMax_fy = fy0;
  6110.          }
  6111.       }
  6112.  
  6113.       /* fixed point X coords */
  6114.       vMin_fx = (((int) ((((vMin->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMin->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMin->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  6115.       vMid_fx = (((int) ((((vMid->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMid->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMid->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  6116.       vMax_fx = (((int) ((((vMax->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMax->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMax->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  6117.    }
  6118.  
  6119.    /* vertex/edge relationship */
  6120.    eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
  6121.    eTop.v0 = vMid;   eTop.v1 = vMax;
  6122.    eBot.v0 = vMin;   eBot.v1 = vMid;
  6123.  
  6124.    /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
  6125.    eMaj.dx = ((vMax_fx - vMin_fx) * (1.0F / 2048.0f));
  6126.    eMaj.dy = ((vMax_fy - vMin_fy) * (1.0F / 2048.0f));
  6127.    eTop.dx = ((vMax_fx - vMid_fx) * (1.0F / 2048.0f));
  6128.    eTop.dy = ((vMax_fy - vMid_fy) * (1.0F / 2048.0f));
  6129.    eBot.dx = ((vMid_fx - vMin_fx) * (1.0F / 2048.0f));
  6130.    eBot.dy = ((vMid_fy - vMin_fy) * (1.0F / 2048.0f));
  6131.  
  6132.    /* compute area, oneOverArea and perform backface culling */
  6133.    {
  6134.       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
  6135.  
  6136.       /* Do backface culling */
  6137.       if (area * bf < 0.0)
  6138.          return;
  6139.  
  6140.       if (IS_INF_OR_NAN(area) || area == 0.0F)
  6141.          return;
  6142.  
  6143.       oneOverArea = 1.0F / area;
  6144.    }
  6145.  
  6146.    ctx->OcclusionResult = 0x1;
  6147.    span.facing = ctx->_Facing; /* for 2-sided stencil test */
  6148.  
  6149.    /* Edge setup.  For a triangle strip these could be reused... */
  6150.    {
  6151.       eMaj.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  6152.       eMaj.lines = (((((vMax_fy - eMaj.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  6153.       if (eMaj.lines > 0) {
  6154.          GLfloat dxdy = eMaj.dx / eMaj.dy;
  6155.          eMaj.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  6156.          eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
  6157.          eMaj.fx0 = vMin_fx;
  6158.          eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy);
  6159.       }
  6160.       else {
  6161.          return;  /*CULLED*/
  6162.       }
  6163.  
  6164.       eTop.fsy = (((vMid_fy) + 0x00000800 - 1) & (~0x000007FF));
  6165.       eTop.lines = (((((vMax_fy - eTop.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  6166.       if (eTop.lines > 0) {
  6167.          GLfloat dxdy = eTop.dx / eTop.dy;
  6168.          eTop.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  6169.          eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
  6170.          eTop.fx0 = vMid_fx;
  6171.          eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy);
  6172.       }
  6173.  
  6174.       eBot.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  6175.       eBot.lines = (((((vMid_fy - eBot.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  6176.       if (eBot.lines > 0) {
  6177.          GLfloat dxdy = eBot.dx / eBot.dy;
  6178.          eBot.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  6179.          eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
  6180.          eBot.fx0 = vMin_fx;
  6181.          eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy);
  6182.       }
  6183.    }
  6184.  
  6185.    /*
  6186.     * Conceptually, we view a triangle as two subtriangles
  6187.     * separated by a perfectly horizontal line.  The edge that is
  6188.     * intersected by this line is one with maximal absolute dy; we
  6189.     * call it a ``major'' edge.  The other two edges are the
  6190.     * ``top'' edge (for the upper subtriangle) and the ``bottom''
  6191.     * edge (for the lower subtriangle).  If either of these two
  6192.     * edges is horizontal or very close to horizontal, the
  6193.     * corresponding subtriangle might cover zero sample points;
  6194.     * we take care to handle such cases, for performance as well
  6195.     * as correctness.
  6196.     *
  6197.     * By stepping rasterization parameters along the major edge,
  6198.     * we can avoid recomputing them at the discontinuity where
  6199.     * the top and bottom edges meet.  However, this forces us to
  6200.     * be able to scan both left-to-right and right-to-left.
  6201.     * Also, we must determine whether the major edge is at the
  6202.     * left or right side of the triangle.  We do this by
  6203.     * computing the magnitude of the cross-product of the major
  6204.     * and top edges.  Since this magnitude depends on the sine of
  6205.     * the angle between the two edges, its sign tells us whether
  6206.     * we turn to the left or to the right when travelling along
  6207.     * the major edge to the top edge, and from this we infer
  6208.     * whether the major edge is on the left or the right.
  6209.     *
  6210.     * Serendipitously, this cross-product magnitude is also a
  6211.     * value we need to compute the iteration parameter
  6212.     * derivatives for the triangle, and it can be used to perform
  6213.     * backface culling because its sign tells us whether the
  6214.     * triangle is clockwise or counterclockwise.  In this code we
  6215.     * refer to it as ``area'' because it's also proportional to
  6216.     * the pixel area of the triangle.
  6217.     */
  6218.  
  6219.    {
  6220.       GLint scan_from_left_to_right;  /* true if scanning left-to-right */
  6221.       GLfloat dzdx, dzdy;
  6222.       GLfloat dfogdy;
  6223.       GLfloat drdx, drdy;
  6224.       GLfloat dgdx, dgdy;
  6225.       GLfloat dbdx, dbdy;
  6226.       GLfloat dadx, dady;
  6227.       GLfloat dsrdx, dsrdy;
  6228.       GLfloat dsgdx, dsgdy;
  6229.       GLfloat dsbdx, dsbdy;
  6230.       GLfloat dsdx[8], dsdy[8];
  6231.       GLfloat dtdx[8], dtdy[8];
  6232.       GLfloat dudx[8], dudy[8];
  6233.       GLfloat dvdx[8], dvdy[8];
  6234.  
  6235.       /*
  6236.        * Execute user-supplied setup code
  6237.        */
  6238.  
  6239.       scan_from_left_to_right = (oneOverArea < 0.0F);
  6240.  
  6241.  
  6242.       /* compute d?/dx and d?/dy derivatives */
  6243.       span.interpMask |= 0x008;
  6244.       {
  6245.          GLfloat eMaj_dz, eBot_dz;
  6246.          eMaj_dz = vMax->win[2] - vMin->win[2];
  6247.          eBot_dz = vMid->win[2] - vMin->win[2];
  6248.          dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
  6249.          if (dzdx > maxDepth || dzdx < -maxDepth) {
  6250.             /* probably a sliver triangle */
  6251.             dzdx = 0.0;
  6252.             dzdy = 0.0;
  6253.          }
  6254.          else {
  6255.             dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
  6256.          }
  6257.          if (depthBits <= 16)
  6258.             span.zStep = (((int) ((((dzdx) * 2048.0f) >= 0.0F) ? (((dzdx) * 2048.0f) + 0.5F) : (((dzdx) * 2048.0f) - 0.5F))));
  6259.          else
  6260.             span.zStep = (GLint) dzdx;
  6261.       }
  6262.       span.interpMask |= 0x010;
  6263.       {
  6264.          const GLfloat eMaj_dfog = vMax->fog - vMin->fog;
  6265.          const GLfloat eBot_dfog = vMid->fog - vMin->fog;
  6266.          span.fogStep = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
  6267.          dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
  6268.       }
  6269.       span.interpMask |= 0x001;
  6270.       if (ctx->Light.ShadeModel == 0x1D01) {
  6271.          GLfloat eMaj_dr, eBot_dr;
  6272.          GLfloat eMaj_dg, eBot_dg;
  6273.          GLfloat eMaj_db, eBot_db;
  6274.          GLfloat eMaj_da, eBot_da;
  6275.          eMaj_dr = (GLfloat) ((GLint) vMax->color[0] -
  6276.                              (GLint) vMin->color[0]);
  6277.          eBot_dr = (GLfloat) ((GLint) vMid->color[0] -
  6278.                              (GLint) vMin->color[0]);
  6279.          drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
  6280.          span.redStep = (((int) ((((drdx) * 2048.0f) >= 0.0F) ? (((drdx) * 2048.0f) + 0.5F) : (((drdx) * 2048.0f) - 0.5F))));
  6281.          drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
  6282.          eMaj_dg = (GLfloat) ((GLint) vMax->color[1] -
  6283.                              (GLint) vMin->color[1]);
  6284.          eBot_dg = (GLfloat) ((GLint) vMid->color[1] -
  6285.                              (GLint) vMin->color[1]);
  6286.          dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
  6287.          span.greenStep = (((int) ((((dgdx) * 2048.0f) >= 0.0F) ? (((dgdx) * 2048.0f) + 0.5F) : (((dgdx) * 2048.0f) - 0.5F))));
  6288.          dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
  6289.          eMaj_db = (GLfloat) ((GLint) vMax->color[2] -
  6290.                              (GLint) vMin->color[2]);
  6291.          eBot_db = (GLfloat) ((GLint) vMid->color[2] -
  6292.                              (GLint) vMin->color[2]);
  6293.          dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
  6294.          span.blueStep = (((int) ((((dbdx) * 2048.0f) >= 0.0F) ? (((dbdx) * 2048.0f) + 0.5F) : (((dbdx) * 2048.0f) - 0.5F))));
  6295.          dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
  6296.          eMaj_da = (GLfloat) ((GLint) vMax->color[3] -
  6297.                              (GLint) vMin->color[3]);
  6298.          eBot_da = (GLfloat) ((GLint) vMid->color[3] -
  6299.                              (GLint) vMin->color[3]);
  6300.          dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
  6301.          span.alphaStep = (((int) ((((dadx) * 2048.0f) >= 0.0F) ? (((dadx) * 2048.0f) + 0.5F) : (((dadx) * 2048.0f) - 0.5F))));
  6302.          dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
  6303.       }
  6304.       else {
  6305.          ;
  6306.          span.interpMask |= 0x200;
  6307.          drdx = drdy = 0.0F;
  6308.          dgdx = dgdy = 0.0F;
  6309.          dbdx = dbdy = 0.0F;
  6310.          span.redStep = 0;
  6311.          span.greenStep = 0;
  6312.          span.blueStep = 0;
  6313.          dadx = dady = 0.0F;
  6314.          span.alphaStep = 0;
  6315.       }
  6316.       span.interpMask |= 0x002;
  6317.       if (ctx->Light.ShadeModel == 0x1D01) {
  6318.          GLfloat eMaj_dsr, eBot_dsr;
  6319.          GLfloat eMaj_dsg, eBot_dsg;
  6320.          GLfloat eMaj_dsb, eBot_dsb;
  6321.          eMaj_dsr = (GLfloat) ((GLint) vMax->specular[0] -
  6322.                               (GLint) vMin->specular[0]);
  6323.          eBot_dsr = (GLfloat) ((GLint) vMid->specular[0] -
  6324.                               (GLint) vMin->specular[0]);
  6325.          dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr);
  6326.          span.specRedStep = (((int) ((((dsrdx) * 2048.0f) >= 0.0F) ? (((dsrdx) * 2048.0f) + 0.5F) : (((dsrdx) * 2048.0f) - 0.5F))));
  6327.          dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx);
  6328.          eMaj_dsg = (GLfloat) ((GLint) vMax->specular[1] -
  6329.                               (GLint) vMin->specular[1]);
  6330.          eBot_dsg = (GLfloat) ((GLint) vMid->specular[1] -
  6331.                               (GLint) vMin->specular[1]);
  6332.          dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg);
  6333.          span.specGreenStep = (((int) ((((dsgdx) * 2048.0f) >= 0.0F) ? (((dsgdx) * 2048.0f) + 0.5F) : (((dsgdx) * 2048.0f) - 0.5F))));
  6334.          dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx);
  6335.          eMaj_dsb = (GLfloat) ((GLint) vMax->specular[2] -
  6336.                               (GLint) vMin->specular[2]);
  6337.          eBot_dsb = (GLfloat) ((GLint) vMid->specular[2] -
  6338.                               (GLint) vMin->specular[2]);
  6339.          dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb);
  6340.          span.specBlueStep = (((int) ((((dsbdx) * 2048.0f) >= 0.0F) ? (((dsbdx) * 2048.0f) + 0.5F) : (((dsbdx) * 2048.0f) - 0.5F))));
  6341.          dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx);
  6342.       }
  6343.       else {
  6344.          dsrdx = dsrdy = 0.0F;
  6345.          dsgdx = dsgdy = 0.0F;
  6346.          dsbdx = dsbdy = 0.0F;
  6347.          span.specRedStep = 0;
  6348.          span.specGreenStep = 0;
  6349.          span.specBlueStep = 0;
  6350.       }
  6351.       span.interpMask |= 0x020;
  6352.       {
  6353.          GLfloat wMax = vMax->win[3];
  6354.          GLfloat wMin = vMin->win[3];
  6355.          GLfloat wMid = vMid->win[3];
  6356.          GLuint u;
  6357.          for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  6358.             if (ctx->Texture.Unit[u]._ReallyEnabled) {
  6359.                GLfloat eMaj_ds, eBot_ds;
  6360.                GLfloat eMaj_dt, eBot_dt;
  6361.                GLfloat eMaj_du, eBot_du;
  6362.                GLfloat eMaj_dv, eBot_dv;
  6363.                eMaj_ds = vMax->texcoord[u][0] * wMax
  6364.                        - vMin->texcoord[u][0] * wMin;
  6365.                eBot_ds = vMid->texcoord[u][0] * wMid
  6366.                        - vMin->texcoord[u][0] * wMin;
  6367.                dsdx[u] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
  6368.                dsdy[u] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
  6369.                span.texStepX[u][0] = dsdx[u];
  6370.                span.texStepY[u][0] = dsdy[u];
  6371.  
  6372.                eMaj_dt = vMax->texcoord[u][1] * wMax
  6373.                        - vMin->texcoord[u][1] * wMin;
  6374.                eBot_dt = vMid->texcoord[u][1] * wMid
  6375.                        - vMin->texcoord[u][1] * wMin;
  6376.                dtdx[u] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
  6377.                dtdy[u] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
  6378.                span.texStepX[u][1] = dtdx[u];
  6379.                span.texStepY[u][1] = dtdy[u];
  6380.  
  6381.                eMaj_du = vMax->texcoord[u][2] * wMax
  6382.                        - vMin->texcoord[u][2] * wMin;
  6383.                eBot_du = vMid->texcoord[u][2] * wMid
  6384.                        - vMin->texcoord[u][2] * wMin;
  6385.                dudx[u] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
  6386.                dudy[u] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
  6387.                span.texStepX[u][2] = dudx[u];
  6388.                span.texStepY[u][2] = dudy[u];
  6389.  
  6390.                eMaj_dv = vMax->texcoord[u][3] * wMax
  6391.                        - vMin->texcoord[u][3] * wMin;
  6392.                eBot_dv = vMid->texcoord[u][3] * wMid
  6393.                        - vMin->texcoord[u][3] * wMin;
  6394.                dvdx[u] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
  6395.                dvdy[u] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
  6396.                span.texStepX[u][3] = dvdx[u];
  6397.                span.texStepY[u][3] = dvdy[u];
  6398.             }
  6399.          }
  6400.       }
  6401.  
  6402.       /*
  6403.        * We always sample at pixel centers.  However, we avoid
  6404.        * explicit half-pixel offsets in this code by incorporating
  6405.        * the proper offset in each of x and y during the
  6406.        * transformation to window coordinates.
  6407.        *
  6408.        * We also apply the usual rasterization rules to prevent
  6409.        * cracks and overlaps.  A pixel is considered inside a
  6410.        * subtriangle if it meets all of four conditions: it is on or
  6411.        * to the right of the left edge, strictly to the left of the
  6412.        * right edge, on or below the top edge, and strictly above
  6413.        * the bottom edge.  (Some edges may be degenerate.)
  6414.        *
  6415.        * The following discussion assumes left-to-right scanning
  6416.        * (that is, the major edge is on the left); the right-to-left
  6417.        * case is a straightforward variation.
  6418.        *
  6419.        * We start by finding the half-integral y coordinate that is
  6420.        * at or below the top of the triangle.  This gives us the
  6421.        * first scan line that could possibly contain pixels that are
  6422.        * inside the triangle.
  6423.        *
  6424.        * Next we creep down the major edge until we reach that y,
  6425.        * and compute the corresponding x coordinate on the edge.
  6426.        * Then we find the half-integral x that lies on or just
  6427.        * inside the edge.  This is the first pixel that might lie in
  6428.        * the interior of the triangle.  (We won't know for sure
  6429.        * until we check the other edges.)
  6430.        *
  6431.        * As we rasterize the triangle, we'll step down the major
  6432.        * edge.  For each step in y, we'll move an integer number
  6433.        * of steps in x.  There are two possible x step sizes, which
  6434.        * we'll call the ``inner'' step (guaranteed to land on the
  6435.        * edge or inside it) and the ``outer'' step (guaranteed to
  6436.        * land on the edge or outside it).  The inner and outer steps
  6437.        * differ by one.  During rasterization we maintain an error
  6438.        * term that indicates our distance from the true edge, and
  6439.        * select either the inner step or the outer step, whichever
  6440.        * gets us to the first pixel that falls inside the triangle.
  6441.        *
  6442.        * All parameters (z, red, etc.) as well as the buffer
  6443.        * addresses for color and z have inner and outer step values,
  6444.        * so that we can increment them appropriately.  This method
  6445.        * eliminates the need to adjust parameters by creeping a
  6446.        * sub-pixel amount into the triangle at each scanline.
  6447.        */
  6448.  
  6449.       {
  6450.          int subTriangle;
  6451.          GLfixed fx;
  6452.          GLfixed fxLeftEdge = 0, fxRightEdge = 0;
  6453.          GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
  6454.          GLfixed fdxOuter;
  6455.          int idxOuter;
  6456.          float dxOuter;
  6457.          GLfixed fError = 0, fdError = 0;
  6458.          float adjx, adjy;
  6459.          GLfixed fy;
  6460.          GLushort *zRow = 0;
  6461.          int dZRowOuter = 0, dZRowInner;  /* offset in bytes */
  6462.          GLfixed fz = 0, fdzOuter = 0, fdzInner;
  6463.          GLfloat fogLeft = 0, dfogOuter = 0, dfogInner;
  6464.          GLfixed fr = 0, fdrOuter = 0, fdrInner;
  6465.          GLfixed fg = 0, fdgOuter = 0, fdgInner;
  6466.          GLfixed fb = 0, fdbOuter = 0, fdbInner;
  6467.          GLfixed fa = 0, fdaOuter = 0, fdaInner;
  6468.          GLfixed fsr=0, fdsrOuter=0, fdsrInner;
  6469.          GLfixed fsg=0, fdsgOuter=0, fdsgInner;
  6470.          GLfixed fsb=0, fdsbOuter=0, fdsbInner;
  6471.          GLfloat sLeft[8];
  6472.          GLfloat tLeft[8];
  6473.          GLfloat uLeft[8];
  6474.          GLfloat vLeft[8];
  6475.          GLfloat dsOuter[8], dsInner[8];
  6476.          GLfloat dtOuter[8], dtInner[8];
  6477.          GLfloat duOuter[8], duInner[8];
  6478.          GLfloat dvOuter[8], dvInner[8];
  6479.  
  6480.          for (subTriangle=0; subTriangle<=1; subTriangle++) {
  6481.             EdgeT *eLeft, *eRight;
  6482.             int setupLeft, setupRight;
  6483.             int lines;
  6484.  
  6485.             if (subTriangle==0) {
  6486.                /* bottom half */
  6487.                if (scan_from_left_to_right) {
  6488.                   eLeft = &eMaj;
  6489.                   eRight = &eBot;
  6490.                   lines = eRight->lines;
  6491.                   setupLeft = 1;
  6492.                   setupRight = 1;
  6493.                }
  6494.                else {
  6495.                   eLeft = &eBot;
  6496.                   eRight = &eMaj;
  6497.                   lines = eLeft->lines;
  6498.                   setupLeft = 1;
  6499.                   setupRight = 1;
  6500.                }
  6501.             }
  6502.             else {
  6503.                /* top half */
  6504.                if (scan_from_left_to_right) {
  6505.                   eLeft = &eMaj;
  6506.                   eRight = &eTop;
  6507.                   lines = eRight->lines;
  6508.                   setupLeft = 0;
  6509.                   setupRight = 1;
  6510.                }
  6511.                else {
  6512.                   eLeft = &eTop;
  6513.                   eRight = &eMaj;
  6514.                   lines = eLeft->lines;
  6515.                   setupLeft = 1;
  6516.                   setupRight = 0;
  6517.                }
  6518.                if (lines == 0)
  6519.                   return;
  6520.             }
  6521.  
  6522.             if (setupLeft && eLeft->lines > 0) {
  6523.                const SWvertex *vLower;
  6524.                GLfixed fsx = eLeft->fsx;
  6525.                fx = (((fsx) + 0x00000800 - 1) & (~0x000007FF));
  6526.                fError = fx - fsx - 0x00000800;
  6527.                fxLeftEdge = fsx - 1;
  6528.                fdxLeftEdge = eLeft->fdxdy;
  6529.                fdxOuter = ((fdxLeftEdge - 1) & (~0x000007FF));
  6530.                fdError = fdxOuter - fdxLeftEdge + 0x00000800;
  6531.                idxOuter = ((fdxOuter) >> 11);
  6532.                dxOuter = (float) idxOuter;
  6533.                (void) dxOuter;
  6534.  
  6535.                fy = eLeft->fsy;
  6536.                span.y = ((fy) >> 11);
  6537.  
  6538.                adjx = (float)(fx - eLeft->fx0);  /* SCALED! */
  6539.                adjy = eLeft->adjy;              /* SCALED! */
  6540.                vLower = eLeft->v0;
  6541.  
  6542.                /*
  6543.                 * Now we need the set of parameter (z, color, etc.) values at
  6544.                 * the point (fx, fy).  This gives us properly-sampled parameter
  6545.                 * values that we can step from pixel to pixel.  Furthermore,
  6546.                 * although we might have intermediate results that overflow
  6547.                 * the normal parameter range when we step temporarily outside
  6548.                 * the triangle, we shouldn't overflow or underflow for any
  6549.                 * pixel that's actually inside the triangle.
  6550.                 */
  6551.  
  6552.                {
  6553.                   GLfloat z0 = vLower->win[2];
  6554.                   if (depthBits <= 16) {
  6555.                      /* interpolate fixed-pt values */
  6556.                      GLfloat tmp = (z0 * 2048.0f +
  6557.                                     dzdx * adjx + dzdy * adjy) + 0x00000400;
  6558.                      if (tmp < 0xffffffff / 2)
  6559.                         fz = (GLfixed) tmp;
  6560.                      else
  6561.                         fz = 0xffffffff / 2;
  6562.                      fdzOuter = (((int) ((((dzdy + dxOuter * dzdx) * 2048.0f) >= 0.0F) ? (((dzdy + dxOuter * dzdx) * 2048.0f) + 0.5F) : (((dzdy + dxOuter * dzdx) * 2048.0f) - 0.5F))));
  6563.                   }
  6564.                   else {
  6565.                      /* interpolate depth values exactly */
  6566.                      fz = (GLint) (z0 + dzdx * ((adjx) * (1.0F / 2048.0f))
  6567.                                    + dzdy * ((adjy) * (1.0F / 2048.0f)));
  6568.                      fdzOuter = (GLint) (dzdy + dxOuter * dzdx);
  6569.                   }
  6570.                   zRow = (GLushort *)
  6571.                     _mesa_zbuffer_address(ctx, ((fxLeftEdge) >> 11), span.y);
  6572.                   dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(GLushort);
  6573.                }
  6574.                fogLeft = vLower->fog + (span.fogStep * adjx + dfogdy * adjy)
  6575.                                        * (1.0F/2048.0f);
  6576.                dfogOuter = dfogdy + dxOuter * span.fogStep;
  6577.                if (ctx->Light.ShadeModel == 0x1D01) {
  6578.                   fr = (GLfixed) (((vLower->color[0]) << 11)
  6579.                                    + drdx * adjx + drdy * adjy) + 0x00000400;
  6580.                   fdrOuter = (((int) ((((drdy + dxOuter * drdx) * 2048.0f) >= 0.0F) ? (((drdy + dxOuter * drdx) * 2048.0f) + 0.5F) : (((drdy + dxOuter * drdx) * 2048.0f) - 0.5F))));
  6581.                   fg = (GLfixed) (((vLower->color[1]) << 11)
  6582.                                    + dgdx * adjx + dgdy * adjy) + 0x00000400;
  6583.                   fdgOuter = (((int) ((((dgdy + dxOuter * dgdx) * 2048.0f) >= 0.0F) ? (((dgdy + dxOuter * dgdx) * 2048.0f) + 0.5F) : (((dgdy + dxOuter * dgdx) * 2048.0f) - 0.5F))));
  6584.                   fb = (GLfixed) (((vLower->color[2]) << 11)
  6585.                                     + dbdx * adjx + dbdy * adjy) + 0x00000400;
  6586.                   fdbOuter = (((int) ((((dbdy + dxOuter * dbdx) * 2048.0f) >= 0.0F) ? (((dbdy + dxOuter * dbdx) * 2048.0f) + 0.5F) : (((dbdy + dxOuter * dbdx) * 2048.0f) - 0.5F))));
  6587.                   fa = (GLfixed) (((vLower->color[3]) << 11)
  6588.                                    + dadx * adjx + dady * adjy) + 0x00000400;
  6589.                   fdaOuter = (((int) ((((dady + dxOuter * dadx) * 2048.0f) >= 0.0F) ? (((dady + dxOuter * dadx) * 2048.0f) + 0.5F) : (((dady + dxOuter * dadx) * 2048.0f) - 0.5F))));
  6590.                }
  6591.                else {
  6592.                   ;
  6593.                   fr = ((v2->color[0]) << 11);
  6594.                   fg = ((v2->color[1]) << 11);
  6595.                   fb = ((v2->color[2]) << 11);
  6596.                   fdrOuter = fdgOuter = fdbOuter = 0;
  6597.                   fa =  ((v2->color[3]) << 11);
  6598.                   fdaOuter = 0;
  6599.                }
  6600.                if (ctx->Light.ShadeModel == 0x1D01) {
  6601.                   fsr = (GLfixed) (((vLower->specular[0]) << 11)
  6602.                                    + dsrdx * adjx + dsrdy * adjy) + 0x00000400;
  6603.                   fdsrOuter = (((int) ((((dsrdy + dxOuter * dsrdx) * 2048.0f) >= 0.0F) ? (((dsrdy + dxOuter * dsrdx) * 2048.0f) + 0.5F) : (((dsrdy + dxOuter * dsrdx) * 2048.0f) - 0.5F))));
  6604.                   fsg = (GLfixed) (((vLower->specular[1]) << 11)
  6605.                                    + dsgdx * adjx + dsgdy * adjy) + 0x00000400;
  6606.                   fdsgOuter = (((int) ((((dsgdy + dxOuter * dsgdx) * 2048.0f) >= 0.0F) ? (((dsgdy + dxOuter * dsgdx) * 2048.0f) + 0.5F) : (((dsgdy + dxOuter * dsgdx) * 2048.0f) - 0.5F))));
  6607.                   fsb = (GLfixed) (((vLower->specular[2]) << 11)
  6608.                                    + dsbdx * adjx + dsbdy * adjy) + 0x00000400;
  6609.                   fdsbOuter = (((int) ((((dsbdy + dxOuter * dsbdx) * 2048.0f) >= 0.0F) ? (((dsbdy + dxOuter * dsbdx) * 2048.0f) + 0.5F) : (((dsbdy + dxOuter * dsbdx) * 2048.0f) - 0.5F))));
  6610.                }
  6611.                else {
  6612.                   fsr = ((v2->specular[0]) << 11);
  6613.                   fsg = ((v2->specular[1]) << 11);
  6614.                   fsb = ((v2->specular[2]) << 11);
  6615.                   fdsrOuter = fdsgOuter = fdsbOuter = 0;
  6616.                }
  6617.                {
  6618.                   GLuint u;
  6619.                   for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  6620.                      if (ctx->Texture.Unit[u]._ReallyEnabled) {
  6621.                         GLfloat invW = vLower->win[3];
  6622.                         GLfloat s0, t0, u0, v0;
  6623.                         s0 = vLower->texcoord[u][0] * invW;
  6624.                         sLeft[u] = s0 + (span.texStepX[u][0] * adjx + dsdy[u]
  6625.                                          * adjy) * (1.0F/2048.0f);
  6626.                         dsOuter[u] = dsdy[u] + dxOuter * span.texStepX[u][0];
  6627.                         t0 = vLower->texcoord[u][1] * invW;
  6628.                         tLeft[u] = t0 + (span.texStepX[u][1] * adjx + dtdy[u]
  6629.                                          * adjy) * (1.0F/2048.0f);
  6630.                         dtOuter[u] = dtdy[u] + dxOuter * span.texStepX[u][1];
  6631.                         u0 = vLower->texcoord[u][2] * invW;
  6632.                         uLeft[u] = u0 + (span.texStepX[u][2] * adjx + dudy[u]
  6633.                                          * adjy) * (1.0F/2048.0f);
  6634.                         duOuter[u] = dudy[u] + dxOuter * span.texStepX[u][2];
  6635.                         v0 = vLower->texcoord[u][3] * invW;
  6636.                         vLeft[u] = v0 + (span.texStepX[u][3] * adjx + dvdy[u]
  6637.                                          * adjy) * (1.0F/2048.0f);
  6638.                         dvOuter[u] = dvdy[u] + dxOuter * span.texStepX[u][3];
  6639.                      }
  6640.                   }
  6641.                }
  6642.  
  6643.             } /*if setupLeft*/
  6644.  
  6645.  
  6646.             if (setupRight && eRight->lines>0) {
  6647.                fxRightEdge = eRight->fsx - 1;
  6648.                fdxRightEdge = eRight->fdxdy;
  6649.             }
  6650.  
  6651.             if (lines==0) {
  6652.                continue;
  6653.             }
  6654.  
  6655.  
  6656.             /* Rasterize setup */
  6657.             dZRowInner = dZRowOuter + sizeof(GLushort);
  6658.             fdzInner = fdzOuter + span.zStep;
  6659.             dfogInner = dfogOuter + span.fogStep;
  6660.             fdrInner = fdrOuter + span.redStep;
  6661.             fdgInner = fdgOuter + span.greenStep;
  6662.             fdbInner = fdbOuter + span.blueStep;
  6663.             fdaInner = fdaOuter + span.alphaStep;
  6664.             fdsrInner = fdsrOuter + span.specRedStep;
  6665.             fdsgInner = fdsgOuter + span.specGreenStep;
  6666.             fdsbInner = fdsbOuter + span.specBlueStep;
  6667.             {
  6668.                GLuint u;
  6669.                for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  6670.                   if (ctx->Texture.Unit[u]._ReallyEnabled) {
  6671.                      dsInner[u] = dsOuter[u] + span.texStepX[u][0];
  6672.                      dtInner[u] = dtOuter[u] + span.texStepX[u][1];
  6673.                      duInner[u] = duOuter[u] + span.texStepX[u][2];
  6674.                      dvInner[u] = dvOuter[u] + span.texStepX[u][3];
  6675.                   }
  6676.                }
  6677.             }
  6678.  
  6679.             while (lines > 0) {
  6680.                /* initialize the span interpolants to the leftmost value */
  6681.                /* ff = fixed-pt fragment */
  6682.                const GLint right = ((fxRightEdge) >> 11);
  6683.  
  6684.                span.x = ((fxLeftEdge) >> 11);
  6685.  
  6686.                if (right <= span.x)
  6687.                   span.end = 0;
  6688.                else
  6689.                   span.end = right - span.x;
  6690.  
  6691.                span.z = fz;
  6692.                span.fog = fogLeft;
  6693.                span.red = fr;
  6694.                span.green = fg;
  6695.                span.blue = fb;
  6696.                span.alpha = fa;
  6697.                span.specRed = fsr;
  6698.                span.specGreen = fsg;
  6699.                span.specBlue = fsb;
  6700.  
  6701.  
  6702.                {
  6703.                   GLuint u;
  6704.                   for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  6705.                      if (ctx->Texture.Unit[u]._ReallyEnabled) {
  6706.                         span.tex[u][0] = sLeft[u];
  6707.                         span.tex[u][1] = tLeft[u];
  6708.                         span.tex[u][2] = uLeft[u];
  6709.                         span.tex[u][3] = vLeft[u];
  6710.                      }
  6711.                   }
  6712.                }
  6713.  
  6714.                {
  6715.                   /* need this to accomodate round-off errors */
  6716.                   const GLint len = right - span.x - 1;
  6717.                   GLfixed ffrend = span.red + len * span.redStep;
  6718.                   GLfixed ffgend = span.green + len * span.greenStep;
  6719.                   GLfixed ffbend = span.blue + len * span.blueStep;
  6720.                   if (ffrend < 0) {
  6721.                      span.red -= ffrend;
  6722.                      if (span.red < 0)
  6723.                         span.red = 0;
  6724.                   }
  6725.                   if (ffgend < 0) {
  6726.                      span.green -= ffgend;
  6727.                      if (span.green < 0)
  6728.                         span.green = 0;
  6729.                   }
  6730.                   if (ffbend < 0) {
  6731.                      span.blue -= ffbend;
  6732.                      if (span.blue < 0)
  6733.                         span.blue = 0;
  6734.                   }
  6735.                }
  6736.                {
  6737.                   const GLint len = right - span.x - 1;
  6738.                   GLfixed ffaend = span.alpha + len * span.alphaStep;
  6739.                   if (ffaend < 0) {
  6740.                      span.alpha -= ffaend;
  6741.                      if (span.alpha < 0)
  6742.                         span.alpha = 0;
  6743.                   }
  6744.                }
  6745.                {
  6746.                   /* need this to accomodate round-off errors */
  6747.                   const GLint len = right - span.x - 1;
  6748.                   GLfixed ffsrend = span.specRed + len * span.specRedStep;
  6749.                   GLfixed ffsgend = span.specGreen + len * span.specGreenStep;
  6750.                   GLfixed ffsbend = span.specBlue + len * span.specBlueStep;
  6751.                   if (ffsrend < 0) {
  6752.                      span.specRed -= ffsrend;
  6753.                      if (span.specRed < 0)
  6754.                         span.specRed = 0;
  6755.                   }
  6756.                   if (ffsgend < 0) {
  6757.                      span.specGreen -= ffsgend;
  6758.                      if (span.specGreen < 0)
  6759.                         span.specGreen = 0;
  6760.                   }
  6761.                   if (ffsbend < 0) {
  6762.                      span.specBlue -= ffsbend;
  6763.                      if (span.specBlue < 0)
  6764.                         span.specBlue = 0;
  6765.                   }
  6766.                }
  6767.  
  6768.                /* This is where we actually generate fragments */
  6769.                if (span.end > 0) {
  6770.                   _mesa_write_texture_span(ctx, &span);;
  6771.                }
  6772.  
  6773.                /*
  6774.                 * Advance to the next scan line.  Compute the
  6775.                 * new edge coordinates, and adjust the
  6776.                 * pixel-center x coordinate so that it stays
  6777.                 * on or inside the major edge.
  6778.                 */
  6779.                (span.y)++;
  6780.                lines--;
  6781.  
  6782.                fxLeftEdge += fdxLeftEdge;
  6783.                fxRightEdge += fdxRightEdge;
  6784.  
  6785.  
  6786.                fError += fdError;
  6787.                if (fError >= 0) {
  6788.                   fError -= 0x00000800;
  6789.                   zRow = (GLushort *) ((GLubyte *) zRow + dZRowOuter);
  6790.                   fz += fdzOuter;
  6791.                   fogLeft += dfogOuter;
  6792.                   fr += fdrOuter;
  6793.                   fg += fdgOuter;
  6794.                   fb += fdbOuter;
  6795.                   fa += fdaOuter;
  6796.                   fsr += fdsrOuter;
  6797.                   fsg += fdsgOuter;
  6798.                   fsb += fdsbOuter;
  6799.                   {
  6800.                      GLuint u;
  6801.                      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  6802.                         if (ctx->Texture.Unit[u]._ReallyEnabled) {
  6803.                            sLeft[u] += dsOuter[u];
  6804.                            tLeft[u] += dtOuter[u];
  6805.                            uLeft[u] += duOuter[u];
  6806.                            vLeft[u] += dvOuter[u];
  6807.                         }
  6808.                      }
  6809.                   }
  6810.                }
  6811.                else {
  6812.                   zRow = (GLushort *) ((GLubyte *) zRow + dZRowInner);
  6813.                   fz += fdzInner;
  6814.                   fogLeft += dfogInner;
  6815.                   fr += fdrInner;
  6816.                   fg += fdgInner;
  6817.                   fb += fdbInner;
  6818.                   fa += fdaInner;
  6819.                   fsr += fdsrInner;
  6820.                   fsg += fdsgInner;
  6821.                   fsb += fdsbInner;
  6822.                   {
  6823.                      GLuint u;
  6824.                      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  6825.                         if (ctx->Texture.Unit[u]._ReallyEnabled) {
  6826.                            sLeft[u] += dsInner[u];
  6827.                            tLeft[u] += dtInner[u];
  6828.                            uLeft[u] += duInner[u];
  6829.                            vLeft[u] += dvInner[u];
  6830.                         }
  6831.                      }
  6832.                   }
  6833.                }
  6834.             } /*while lines>0*/
  6835.  
  6836.          } /* for subTriangle */
  6837.  
  6838.       }
  6839.    }
  6840. }
  6841.  
  6842.  
  6843. /*
  6844.  * Triangle Rasterizer Template
  6845.  *
  6846.  * This file is #include'd to generate custom triangle rasterizers.
  6847.  *
  6848.  * The following macros may be defined to indicate what auxillary information
  6849.  * must be interplated across the triangle:
  6850.  *    INTERP_Z        - if defined, interpolate Z values
  6851.  *    INTERP_FOG      - if defined, interpolate fog values
  6852.  *    INTERP_RGB      - if defined, interpolate RGB values
  6853.  *    INTERP_ALPHA    - if defined, interpolate Alpha values (req's INTERP_RGB)
  6854.  *    INTERP_SPEC     - if defined, interpolate specular RGB values
  6855.  *    INTERP_INDEX    - if defined, interpolate color index values
  6856.  *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
  6857.  *                         (fast, simple 2-D texture mapping)
  6858.  *    INTERP_TEX      - if defined, interpolate set 0 float STRQ texcoords
  6859.  *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
  6860.  *    INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
  6861.  *    INTERP_FLOAT_RGBA - if defined, interpolate RGBA with floating point
  6862.  *    INTERP_FLOAT_SPEC - if defined, interpolate specular with floating point
  6863.  *
  6864.  * When one can directly address pixels in the color buffer the following
  6865.  * macros can be defined and used to compute pixel addresses during
  6866.  * rasterization (see pRow):
  6867.  *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
  6868.  *    BYTES_PER_ROW       - number of bytes per row in the color buffer
  6869.  *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
  6870.  *                          Y==0 at bottom of screen and increases upward.
  6871.  *
  6872.  * Similarly, for direct depth buffer access, this type is used for depth
  6873.  * buffer addressing:
  6874.  *    DEPTH_TYPE          - either GLushort or GLuint
  6875.  *
  6876.  * Optionally, one may provide one-time setup code per triangle:
  6877.  *    SETUP_CODE    - code which is to be executed once per triangle
  6878.  *    CLEANUP_CODE    - code to execute at end of triangle
  6879.  *
  6880.  * The following macro MUST be defined:
  6881.  *    RENDER_SPAN(span) - code to write a span of pixels.
  6882.  *
  6883.  * This code was designed for the origin to be in the lower-left corner.
  6884.  *
  6885.  * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
  6886.  */
  6887.  
  6888.  
  6889. /*
  6890.  * This is a bit of a hack, but it's a centralized place to enable floating-
  6891.  * point color interpolation when GLchan is actually floating point.
  6892.  */
  6893.  
  6894.  
  6895.  
  6896. static void occlusion_zless_triangle(GLcontext *ctx, const SWvertex *v0,
  6897.                                  const SWvertex *v1,
  6898.                                  const SWvertex *v2 )
  6899. {
  6900.    typedef struct {
  6901.         const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
  6902.         GLfloat dx;    /* X(v1) - X(v0) */
  6903.         GLfloat dy;    /* Y(v1) - Y(v0) */
  6904.         GLfixed fdxdy; /* dx/dy in fixed-point */
  6905.         GLfixed fsx;   /* first sample point x coord */
  6906.         GLfixed fsy;
  6907.         GLfloat adjy;  /* adjust from v[0]->fy to fsy, scaled */
  6908.         GLint lines;   /* number of lines to be sampled on this edge */
  6909.         GLfixed fx0;   /* fixed pt X of lower endpoint */
  6910.    } EdgeT;
  6911.  
  6912.    const GLint depthBits = ctx->Visual.depthBits;
  6913.    const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0;
  6914.    const GLfloat maxDepth = ctx->DepthMaxF;
  6915.    EdgeT eMaj, eTop, eBot;
  6916.    GLfloat oneOverArea;
  6917.    const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
  6918.    float bf = ((SWcontext *)ctx->swrast_context)->_backface_sign;
  6919.    const GLint snapMask = ~((0x00000800 / (1 << 4)) - 1); /* for x/y coord snapping */
  6920.    GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
  6921.  
  6922.    struct sw_span span;
  6923.  
  6924.    do { (span).primitive = (0x0009); (span).interpMask = (0); (span).arrayMask = (0); (span).start = 0; (span).end = (0); (span).facing = 0; (span).array = ((SWcontext *)ctx->swrast_context)->SpanArrays; } while (0);
  6925.  
  6926.  
  6927.    printf("%s()\n", __FUNCTION__);
  6928.    /*
  6929.    printf("  %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
  6930.    printf("  %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
  6931.    printf("  %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
  6932.     */
  6933.  
  6934.    /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
  6935.     * And find the order of the 3 vertices along the Y axis.
  6936.     */
  6937.    {
  6938.       const GLfixed fy0 = (((int) ((((v0->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v0->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v0->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  6939.       const GLfixed fy1 = (((int) ((((v1->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v1->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v1->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  6940.       const GLfixed fy2 = (((int) ((((v2->win[1] - 0.5F) * 2048.0f) >= 0.0F) ? (((v2->win[1] - 0.5F) * 2048.0f) + 0.5F) : (((v2->win[1] - 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  6941.  
  6942.       if (fy0 <= fy1) {
  6943.          if (fy1 <= fy2) {
  6944.             /* y0 <= y1 <= y2 */
  6945.             vMin = v0;   vMid = v1;   vMax = v2;
  6946.             vMin_fy = fy0;  vMid_fy = fy1;  vMax_fy = fy2;
  6947.          }
  6948.          else if (fy2 <= fy0) {
  6949.             /* y2 <= y0 <= y1 */
  6950.             vMin = v2;   vMid = v0;   vMax = v1;
  6951.             vMin_fy = fy2;  vMid_fy = fy0;  vMax_fy = fy1;
  6952.          }
  6953.          else {
  6954.             /* y0 <= y2 <= y1 */
  6955.             vMin = v0;   vMid = v2;   vMax = v1;
  6956.             vMin_fy = fy0;  vMid_fy = fy2;  vMax_fy = fy1;
  6957.             bf = -bf;
  6958.          }
  6959.       }
  6960.       else {
  6961.          if (fy0 <= fy2) {
  6962.             /* y1 <= y0 <= y2 */
  6963.             vMin = v1;   vMid = v0;   vMax = v2;
  6964.             vMin_fy = fy1;  vMid_fy = fy0;  vMax_fy = fy2;
  6965.             bf = -bf;
  6966.          }
  6967.          else if (fy2 <= fy1) {
  6968.             /* y2 <= y1 <= y0 */
  6969.             vMin = v2;   vMid = v1;   vMax = v0;
  6970.             vMin_fy = fy2;  vMid_fy = fy1;  vMax_fy = fy0;
  6971.             bf = -bf;
  6972.          }
  6973.          else {
  6974.             /* y1 <= y2 <= y0 */
  6975.             vMin = v1;   vMid = v2;   vMax = v0;
  6976.             vMin_fy = fy1;  vMid_fy = fy2;  vMax_fy = fy0;
  6977.          }
  6978.       }
  6979.  
  6980.       /* fixed point X coords */
  6981.       vMin_fx = (((int) ((((vMin->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMin->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMin->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  6982.       vMid_fx = (((int) ((((vMid->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMid->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMid->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  6983.       vMax_fx = (((int) ((((vMax->win[0] + 0.5F) * 2048.0f) >= 0.0F) ? (((vMax->win[0] + 0.5F) * 2048.0f) + 0.5F) : (((vMax->win[0] + 0.5F) * 2048.0f) - 0.5F)))) & snapMask;
  6984.    }
  6985.  
  6986.    /* vertex/edge relationship */
  6987.    eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
  6988.    eTop.v0 = vMid;   eTop.v1 = vMax;
  6989.    eBot.v0 = vMin;   eBot.v1 = vMid;
  6990.  
  6991.    /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
  6992.    eMaj.dx = ((vMax_fx - vMin_fx) * (1.0F / 2048.0f));
  6993.    eMaj.dy = ((vMax_fy - vMin_fy) * (1.0F / 2048.0f));
  6994.    eTop.dx = ((vMax_fx - vMid_fx) * (1.0F / 2048.0f));
  6995.    eTop.dy = ((vMax_fy - vMid_fy) * (1.0F / 2048.0f));
  6996.    eBot.dx = ((vMid_fx - vMin_fx) * (1.0F / 2048.0f));
  6997.    eBot.dy = ((vMid_fy - vMin_fy) * (1.0F / 2048.0f));
  6998.  
  6999.    /* compute area, oneOverArea and perform backface culling */
  7000.    {
  7001.       const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
  7002.  
  7003.       /* Do backface culling */
  7004.       if (area * bf < 0.0)
  7005.          return;
  7006.  
  7007.       if (IS_INF_OR_NAN(area) || area == 0.0F)
  7008.          return;
  7009.  
  7010.       oneOverArea = 1.0F / area;
  7011.    }
  7012.  
  7013.    span.facing = ctx->_Facing; /* for 2-sided stencil test */
  7014.  
  7015.    /* Edge setup.  For a triangle strip these could be reused... */
  7016.    {
  7017.       eMaj.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  7018.       eMaj.lines = (((((vMax_fy - eMaj.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  7019.       if (eMaj.lines > 0) {
  7020.          GLfloat dxdy = eMaj.dx / eMaj.dy;
  7021.          eMaj.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  7022.          eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
  7023.          eMaj.fx0 = vMin_fx;
  7024.          eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy);
  7025.       }
  7026.       else {
  7027.          return;  /*CULLED*/
  7028.       }
  7029.  
  7030.       eTop.fsy = (((vMid_fy) + 0x00000800 - 1) & (~0x000007FF));
  7031.       eTop.lines = (((((vMax_fy - eTop.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  7032.       if (eTop.lines > 0) {
  7033.          GLfloat dxdy = eTop.dx / eTop.dy;
  7034.          eTop.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  7035.          eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
  7036.          eTop.fx0 = vMid_fx;
  7037.          eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy);
  7038.       }
  7039.  
  7040.       eBot.fsy = (((vMin_fy) + 0x00000800 - 1) & (~0x000007FF));
  7041.       eBot.lines = (((((vMid_fy - eBot.fsy) + 0x00000800 - 1) & (~0x000007FF))) >> 11);
  7042.       if (eBot.lines > 0) {
  7043.          GLfloat dxdy = eBot.dx / eBot.dy;
  7044.          eBot.fdxdy = (((int) ((((dxdy) * 2048.0f) >= 0.0F) ? (((dxdy) * 2048.0f) + 0.5F) : (((dxdy) * 2048.0f) - 0.5F))));
  7045.          eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
  7046.          eBot.fx0 = vMin_fx;
  7047.          eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy);
  7048.       }
  7049.    }
  7050.  
  7051.    /*
  7052.     * Conceptually, we view a triangle as two subtriangles
  7053.     * separated by a perfectly horizontal line.  The edge that is
  7054.     * intersected by this line is one with maximal absolute dy; we
  7055.     * call it a ``major'' edge.  The other two edges are the
  7056.     * ``top'' edge (for the upper subtriangle) and the ``bottom''
  7057.     * edge (for the lower subtriangle).  If either of these two
  7058.     * edges is horizontal or very close to horizontal, the
  7059.     * corresponding subtriangle might cover zero sample points;
  7060.     * we take care to handle such cases, for performance as well
  7061.     * as correctness.
  7062.     *
  7063.     * By stepping rasterization parameters along the major edge,
  7064.     * we can avoid recomputing them at the discontinuity where
  7065.     * the top and bottom edges meet.  However, this forces us to
  7066.     * be able to scan both left-to-right and right-to-left.
  7067.     * Also, we must determine whether the major edge is at the
  7068.     * left or right side of the triangle.  We do this by
  7069.     * computing the magnitude of the cross-product of the major
  7070.     * and top edges.  Since this magnitude depends on the sine of
  7071.     * the angle between the two edges, its sign tells us whether
  7072.     * we turn to the left or to the right when travelling along
  7073.     * the major edge to the top edge, and from this we infer
  7074.     * whether the major edge is on the left or the right.
  7075.     *
  7076.     * Serendipitously, this cross-product magnitude is also a
  7077.     * value we need to compute the iteration parameter
  7078.     * derivatives for the triangle, and it can be used to perform
  7079.     * backface culling because its sign tells us whether the
  7080.     * triangle is clockwise or counterclockwise.  In this code we
  7081.     * refer to it as ``area'' because it's also proportional to
  7082.     * the pixel area of the triangle.
  7083.     */
  7084.  
  7085.    {
  7086.       GLint scan_from_left_to_right;  /* true if scanning left-to-right */
  7087.       GLfloat dzdx, dzdy;
  7088.  
  7089.       /*
  7090.        * Execute user-supplied setup code
  7091.        */
  7092.       if (ctx->OcclusionResult) { return; }
  7093.  
  7094.       scan_from_left_to_right = (oneOverArea < 0.0F);
  7095.  
  7096.  
  7097.       /* compute d?/dx and d?/dy derivatives */
  7098.       span.interpMask |= 0x008;
  7099.       {
  7100.          GLfloat eMaj_dz, eBot_dz;
  7101.          eMaj_dz = vMax->win[2] - vMin->win[2];
  7102.          eBot_dz = vMid->win[2] - vMin->win[2];
  7103.          dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
  7104.          if (dzdx > maxDepth || dzdx < -maxDepth) {
  7105.             /* probably a sliver triangle */
  7106.             dzdx = 0.0;
  7107.             dzdy = 0.0;
  7108.          }
  7109.          else {
  7110.             dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
  7111.          }
  7112.          if (depthBits <= 16)
  7113.             span.zStep = (((int) ((((dzdx) * 2048.0f) >= 0.0F) ? (((dzdx) * 2048.0f) + 0.5F) : (((dzdx) * 2048.0f) - 0.5F))));
  7114.          else
  7115.             span.zStep = (GLint) dzdx;
  7116.       }
  7117.  
  7118.       /*
  7119.        * We always sample at pixel centers.  However, we avoid
  7120.        * explicit half-pixel offsets in this code by incorporating
  7121.        * the proper offset in each of x and y during the
  7122.        * transformation to window coordinates.
  7123.        *
  7124.        * We also apply the usual rasterization rules to prevent
  7125.        * cracks and overlaps.  A pixel is considered inside a
  7126.        * subtriangle if it meets all of four conditions: it is on or
  7127.        * to the right of the left edge, strictly to the left of the
  7128.        * right edge, on or below the top edge, and strictly above
  7129.        * the bottom edge.  (Some edges may be degenerate.)
  7130.        *
  7131.        * The following discussion assumes left-to-right scanning
  7132.        * (that is, the major edge is on the left); the right-to-left
  7133.        * case is a straightforward variation.
  7134.        *
  7135.        * We start by finding the half-integral y coordinate that is
  7136.        * at or below the top of the triangle.  This gives us the
  7137.        * first scan line that could possibly contain pixels that are
  7138.        * inside the triangle.
  7139.        *
  7140.        * Next we creep down the major edge until we reach that y,
  7141.        * and compute the corresponding x coordinate on the edge.
  7142.        * Then we find the half-integral x that lies on or just
  7143.        * inside the edge.  This is the first pixel that might lie in
  7144.        * the interior of the triangle.  (We won't know for sure
  7145.        * until we check the other edges.)
  7146.        *
  7147.        * As we rasterize the triangle, we'll step down the major
  7148.        * edge.  For each step in y, we'll move an integer number
  7149.        * of steps in x.  There are two possible x step sizes, which
  7150.        * we'll call the ``inner'' step (guaranteed to land on the
  7151.        * edge or inside it) and the ``outer'' step (guaranteed to
  7152.        * land on the edge or outside it).  The inner and outer steps
  7153.        * differ by one.  During rasterization we maintain an error
  7154.        * term that indicates our distance from the true edge, and
  7155.        * select either the inner step or the outer step, whichever
  7156.        * gets us to the first pixel that falls inside the triangle.
  7157.        *
  7158.        * All parameters (z, red, etc.) as well as the buffer
  7159.        * addresses for color and z have inner and outer step values,
  7160.        * so that we can increment them appropriately.  This method
  7161.        * eliminates the need to adjust parameters by creeping a
  7162.        * sub-pixel amount into the triangle at each scanline.
  7163.        */
  7164.  
  7165.       {
  7166.          int subTriangle;
  7167.          GLfixed fx;
  7168.          GLfixed fxLeftEdge = 0, fxRightEdge = 0;
  7169.          GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
  7170.          GLfixed fdxOuter;
  7171.          int idxOuter;
  7172.          float dxOuter;
  7173.          GLfixed fError = 0, fdError = 0;
  7174.          float adjx, adjy;
  7175.          GLfixed fy;
  7176.          GLushort *zRow = 0;
  7177.          int dZRowOuter = 0, dZRowInner;  /* offset in bytes */
  7178.          GLfixed fz = 0, fdzOuter = 0, fdzInner;
  7179.  
  7180.          for (subTriangle=0; subTriangle<=1; subTriangle++) {
  7181.             EdgeT *eLeft, *eRight;
  7182.             int setupLeft, setupRight;
  7183.             int lines;
  7184.  
  7185.             if (subTriangle==0) {
  7186.                /* bottom half */
  7187.                if (scan_from_left_to_right) {
  7188.                   eLeft = &eMaj;
  7189.                   eRight = &eBot;
  7190.                   lines = eRight->lines;
  7191.                   setupLeft = 1;
  7192.                   setupRight = 1;
  7193.                }
  7194.                else {
  7195.                   eLeft = &eBot;
  7196.                   eRight = &eMaj;
  7197.                   lines = eLeft->lines;
  7198.                   setupLeft = 1;
  7199.                   setupRight = 1;
  7200.                }
  7201.             }
  7202.             else {
  7203.                /* top half */
  7204.                if (scan_from_left_to_right) {
  7205.                   eLeft = &eMaj;
  7206.                   eRight = &eTop;
  7207.                   lines = eRight->lines;
  7208.                   setupLeft = 0;
  7209.                   setupRight = 1;
  7210.                }
  7211.                else {
  7212.                   eLeft = &eTop;
  7213.                   eRight = &eMaj;
  7214.                   lines = eLeft->lines;
  7215.                   setupLeft = 1;
  7216.                   setupRight = 0;
  7217.                }
  7218.                if (lines == 0)
  7219.                   return;
  7220.             }
  7221.  
  7222.             if (setupLeft && eLeft->lines > 0) {
  7223.                const SWvertex *vLower;
  7224.                GLfixed fsx = eLeft->fsx;
  7225.                fx = (((fsx) + 0x00000800 - 1) & (~0x000007FF));
  7226.                fError = fx - fsx - 0x00000800;
  7227.                fxLeftEdge = fsx - 1;
  7228.                fdxLeftEdge = eLeft->fdxdy;
  7229.                fdxOuter = ((fdxLeftEdge - 1) & (~0x000007FF));
  7230.                fdError = fdxOuter - fdxLeftEdge + 0x00000800;
  7231.                idxOuter = ((fdxOuter) >> 11);
  7232.                dxOuter = (float) idxOuter;
  7233.                (void) dxOuter;
  7234.  
  7235.                fy = eLeft->fsy;
  7236.                span.y = ((fy) >> 11);
  7237.  
  7238.                adjx = (float)(fx - eLeft->fx0);  /* SCALED! */
  7239.                adjy = eLeft->adjy;              /* SCALED! */
  7240.                vLower = eLeft->v0;
  7241.  
  7242.                /*
  7243.                 * Now we need the set of parameter (z, color, etc.) values at
  7244.                 * the point (fx, fy).  This gives us properly-sampled parameter
  7245.                 * values that we can step from pixel to pixel.  Furthermore,
  7246.                 * although we might have intermediate results that overflow
  7247.                 * the normal parameter range when we step temporarily outside
  7248.                 * the triangle, we shouldn't overflow or underflow for any
  7249.                 * pixel that's actually inside the triangle.
  7250.                 */
  7251.  
  7252.                {
  7253.                   GLfloat z0 = vLower->win[2];
  7254.                   if (depthBits <= 16) {
  7255.                      /* interpolate fixed-pt values */
  7256.                      GLfloat tmp = (z0 * 2048.0f +
  7257.                                     dzdx * adjx + dzdy * adjy) + 0x00000400;
  7258.                      if (tmp < 0xffffffff / 2)
  7259.                         fz = (GLfixed) tmp;
  7260.                      else
  7261.                         fz = 0xffffffff / 2;
  7262.                      fdzOuter = (((int) ((((dzdy + dxOuter * dzdx) * 2048.0f) >= 0.0F) ? (((dzdy + dxOuter * dzdx) * 2048.0f) + 0.5F) : (((dzdy + dxOuter * dzdx) * 2048.0f) - 0.5F))));
  7263.                   }
  7264.                   else {
  7265.                      /* interpolate depth values exactly */
  7266.                      fz = (GLint) (z0 + dzdx * ((adjx) * (1.0F / 2048.0f))
  7267.                                    + dzdy * ((adjy) * (1.0F / 2048.0f)));
  7268.                      fdzOuter = (GLint) (dzdy + dxOuter * dzdx);
  7269.                   }
  7270.                   zRow = (GLushort *)
  7271.                     _mesa_zbuffer_address(ctx, ((fxLeftEdge) >> 11), span.y);
  7272.                   dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(GLushort);
  7273.                }
  7274.  
  7275.             } /*if setupLeft*/
  7276.  
  7277.  
  7278.             if (setupRight && eRight->lines>0) {
  7279.                fxRightEdge = eRight->fsx - 1;
  7280.                fdxRightEdge = eRight->fdxdy;
  7281.             }
  7282.  
  7283.             if (lines==0) {
  7284.                continue;
  7285.             }
  7286.  
  7287.  
  7288.             /* Rasterize setup */
  7289.             dZRowInner = dZRowOuter + sizeof(GLushort);
  7290.             fdzInner = fdzOuter + span.zStep;
  7291.  
  7292.             while (lines > 0) {
  7293.                /* initialize the span interpolants to the leftmost value */
  7294.                /* ff = fixed-pt fragment */
  7295.                const GLint right = ((fxRightEdge) >> 11);
  7296.  
  7297.                span.x = ((fxLeftEdge) >> 11);
  7298.  
  7299.                if (right <= span.x)
  7300.                   span.end = 0;
  7301.                else
  7302.                   span.end = right - span.x;
  7303.  
  7304.                span.z = fz;
  7305.  
  7306.  
  7307.  
  7308.  
  7309.                /* This is where we actually generate fragments */
  7310.                if (span.end > 0) {
  7311.                   GLuint i; for (i = 0; i < span.end; i++) { GLdepth z = ((span.z) >> fixedToDepthShift); if (z < zRow[i]) { ctx->OcclusionResult = 0x1; return; } span.z += span.zStep; };
  7312.                }
  7313.  
  7314.                /*
  7315.                 * Advance to the next scan line.  Compute the
  7316.                 * new edge coordinates, and adjust the
  7317.                 * pixel-center x coordinate so that it stays
  7318.                 * on or inside the major edge.
  7319.                 */
  7320.                (span.y)++;
  7321.                lines--;
  7322.  
  7323.                fxLeftEdge += fdxLeftEdge;
  7324.                fxRightEdge += fdxRightEdge;
  7325.  
  7326.  
  7327.                fError += fdError;
  7328.                if (fError >= 0) {
  7329.                   fError -= 0x00000800;
  7330.                   zRow = (GLushort *) ((GLubyte *) zRow + dZRowOuter);
  7331.                   fz += fdzOuter;
  7332.                }
  7333.                else {
  7334.                   zRow = (GLushort *) ((GLubyte *) zRow + dZRowInner);
  7335.                   fz += fdzInner;
  7336.                }
  7337.             } /*while lines>0*/
  7338.  
  7339.          } /* for subTriangle */
  7340.  
  7341.       }
  7342.    }
  7343. }
  7344.  
  7345.  
  7346.  
  7347.  
  7348.  
  7349.  
  7350.  
  7351.  
  7352.  
  7353. static void
  7354. nodraw_triangle( GLcontext *ctx,
  7355.                  const SWvertex *v0,
  7356.                  const SWvertex *v1,
  7357.                  const SWvertex *v2 )
  7358. {
  7359.    (void) (ctx && v0 && v1 && v2);
  7360. }
  7361.  
  7362.  
  7363. /*
  7364.  * This is used when separate specular color is enabled, but not
  7365.  * texturing.  We add the specular color to the primary color,
  7366.  * draw the triangle, then restore the original primary color.
  7367.  * Inefficient, but seldom needed.
  7368.  */
  7369. void _swrast_add_spec_terms_triangle( GLcontext *ctx,
  7370.                                      const SWvertex *v0,
  7371.                                      const SWvertex *v1,
  7372.                                      const SWvertex *v2 )
  7373. {
  7374.    SWvertex *ncv0 = (SWvertex *)v0; /* drop const qualifier */
  7375.    SWvertex *ncv1 = (SWvertex *)v1;
  7376.    SWvertex *ncv2 = (SWvertex *)v2;
  7377.    GLint rSum, gSum, bSum;
  7378.    GLchan c[3][4];
  7379.    /* save original colors */
  7380.    { (c[0])[0] = (ncv0->color)[0]; (c[0])[1] = (ncv0->color)[1]; (c[0])[2] = (ncv0->color)[2]; (c[0])[3] = (ncv0->color)[3]; };
  7381.    { (c[1])[0] = (ncv1->color)[0]; (c[1])[1] = (ncv1->color)[1]; (c[1])[2] = (ncv1->color)[2]; (c[1])[3] = (ncv1->color)[3]; };
  7382.    { (c[2])[0] = (ncv2->color)[0]; (c[2])[1] = (ncv2->color)[1]; (c[2])[2] = (ncv2->color)[2]; (c[2])[3] = (ncv2->color)[3]; };
  7383.    /* sum v0 */
  7384.    rSum = ncv0->color[0] + ncv0->specular[0];
  7385.    gSum = ncv0->color[1] + ncv0->specular[1];
  7386.    bSum = ncv0->color[2] + ncv0->specular[2];
  7387.    ncv0->color[0] = ( (rSum)<(255) ? (rSum) : (255) );
  7388.    ncv0->color[1] = ( (gSum)<(255) ? (gSum) : (255) );
  7389.    ncv0->color[2] = ( (bSum)<(255) ? (bSum) : (255) );
  7390.    /* sum v1 */
  7391.    rSum = ncv1->color[0] + ncv1->specular[0];
  7392.    gSum = ncv1->color[1] + ncv1->specular[1];
  7393.    bSum = ncv1->color[2] + ncv1->specular[2];
  7394.    ncv1->color[0] = ( (rSum)<(255) ? (rSum) : (255) );
  7395.    ncv1->color[1] = ( (gSum)<(255) ? (gSum) : (255) );
  7396.    ncv1->color[2] = ( (bSum)<(255) ? (bSum) : (255) );
  7397.    /* sum v2 */
  7398.    rSum = ncv2->color[0] + ncv2->specular[0];
  7399.    gSum = ncv2->color[1] + ncv2->specular[1];
  7400.    bSum = ncv2->color[2] + ncv2->specular[2];
  7401.    ncv2->color[0] = ( (rSum)<(255) ? (rSum) : (255) );
  7402.    ncv2->color[1] = ( (gSum)<(255) ? (gSum) : (255) );
  7403.    ncv2->color[2] = ( (bSum)<(255) ? (bSum) : (255) );
  7404.    /* draw */
  7405.    ((SWcontext *)ctx->swrast_context)->SpecTriangle( ctx, ncv0, ncv1, ncv2 );
  7406.    /* restore original colors */
  7407.    { (ncv0->color)[0] = (c[0])[0]; (ncv0->color)[1] = (c[0])[1]; (ncv0->color)[2] = (c[0])[2]; (ncv0->color)[3] = (c[0])[3]; };
  7408.    { (ncv1->color)[0] = (c[1])[0]; (ncv1->color)[1] = (c[1])[1]; (ncv1->color)[2] = (c[1])[2]; (ncv1->color)[3] = (c[1])[3]; };
  7409.    { (ncv2->color)[0] = (c[2])[0]; (ncv2->color)[1] = (c[2])[1]; (ncv2->color)[2] = (c[2])[2]; (ncv2->color)[3] = (c[2])[3]; };
  7410. }
  7411.  
  7412.  
  7413.  
  7414.  
  7415.  
  7416.  
  7417.  
  7418.  
  7419.  
  7420. /*
  7421.  * Determine which triangle rendering function to use given the current
  7422.  * rendering context.
  7423.  *
  7424.  * Please update the summary flag _SWRAST_NEW_TRIANGLE if you add or
  7425.  * remove tests to this code.
  7426.  */
  7427. void
  7428. _swrast_choose_triangle( GLcontext *ctx )
  7429. {
  7430.    SWcontext *swrast = ((SWcontext *)ctx->swrast_context);
  7431.    const GLboolean rgbmode = ctx->Visual.rgbMode;
  7432.  
  7433.    if (ctx->Polygon.CullFlag &&
  7434.        ctx->Polygon.CullFaceMode == 0x0408) {
  7435.       swrast->Triangle = nodraw_triangle;;
  7436.       return;
  7437.    }
  7438.  
  7439.    if (ctx->RenderMode==0x1C00) {
  7440.  
  7441.       if (ctx->Polygon.SmoothFlag) {
  7442.          _mesa_set_aa_triangle_function(ctx);
  7443.          ;
  7444.          return;
  7445.       }
  7446.  
  7447.       if (ctx->Depth.OcclusionTest &&
  7448.           ctx->Depth.Test &&
  7449.           ctx->Depth.Mask == 0x0 &&
  7450.           ctx->Depth.Func == 0x0201 &&
  7451.           !ctx->Stencil.Enabled) {
  7452.          if ((rgbmode &&
  7453.               ctx->Color.ColorMask[0] == 0 &&
  7454.               ctx->Color.ColorMask[1] == 0 &&
  7455.               ctx->Color.ColorMask[2] == 0 &&
  7456.               ctx->Color.ColorMask[3] == 0)
  7457.              ||
  7458.              (!rgbmode && ctx->Color.IndexMask == 0)) {
  7459.             swrast->Triangle = occlusion_zless_triangle;;
  7460.             return;
  7461.          }
  7462.       }
  7463.  
  7464.       if (ctx->Texture._EnabledUnits) {
  7465.          /* Ugh, we do a _lot_ of tests to pick the best textured tri func */
  7466.         const struct gl_texture_object *texObj2D;
  7467.          const struct gl_texture_image *texImg;
  7468.          GLenum minFilter, magFilter, envMode;
  7469.          GLint format;
  7470.          texObj2D = ctx->Texture.Unit[0].Current2D;
  7471.          texImg = texObj2D ? texObj2D->Image[texObj2D->BaseLevel] : 0;
  7472.          format = texImg ? texImg->TexFormat->MesaFormat : -1;
  7473.          minFilter = texObj2D ? texObj2D->MinFilter : (GLenum) 0;
  7474.          magFilter = texObj2D ? texObj2D->MagFilter : (GLenum) 0;
  7475.          envMode = ctx->Texture.Unit[0].EnvMode;
  7476.  
  7477.          /* First see if we can used an optimized 2-D texture function */
  7478.          if (ctx->Texture._EnabledUnits == 1
  7479.              && ctx->Texture.Unit[0]._ReallyEnabled == 0x02
  7480.              && texObj2D->WrapS==0x2901
  7481.             && texObj2D->WrapT==0x2901
  7482.              && texImg->Border==0
  7483.              && texImg->Width == texImg->RowStride
  7484.              && (format == MESA_FORMAT_RGB || format == MESA_FORMAT_RGBA)
  7485.             && minFilter == magFilter
  7486.             && ctx->Light.Model.ColorControl == 0x81F9
  7487.             && ctx->Texture.Unit[0].EnvMode != 0x8570) {
  7488.            if (ctx->Hint.PerspectiveCorrection==0x1101) {
  7489.               if (minFilter == 0x2600
  7490.                   && format == MESA_FORMAT_RGB
  7491.                   && (envMode == 0x1E01 || envMode == 0x2101)
  7492.                   && ((swrast->_RasterMask == (0x004 | 0x1000)
  7493.                        && ctx->Depth.Func == 0x0201
  7494.                        && ctx->Depth.Mask == 0x1)
  7495.                       || swrast->_RasterMask == 0x1000)
  7496.                   && ctx->Polygon.StippleFlag == 0x0) {
  7497.                  if (swrast->_RasterMask == (0x004 | 0x1000)) {
  7498.                     swrast->Triangle = simple_z_textured_triangle;
  7499.                  }
  7500.                  else {
  7501.                     swrast->Triangle = simple_textured_triangle;
  7502.                  }
  7503.               }
  7504.               else {
  7505.                   swrast->Triangle = affine_textured_triangle;
  7506.               }
  7507.            }
  7508.            else {
  7509.                swrast->Triangle = persp_textured_triangle;
  7510.            }
  7511.         }
  7512.          else {
  7513.             /* general case textured triangles */
  7514.             if (ctx->Texture._EnabledUnits > 1) {
  7515.                swrast->Triangle = multitextured_triangle;
  7516.             }
  7517.             else {
  7518.                swrast->Triangle = general_textured_triangle;
  7519.             }
  7520.          }
  7521.       }
  7522.       else {
  7523.          ;
  7524.         if (ctx->Light.ShadeModel==0x1D01) {
  7525.            /* smooth shaded, no texturing, stippled or some raster ops */
  7526.             if (rgbmode) {
  7527.               swrast->Triangle = smooth_rgba_triangle;
  7528.             }
  7529.             else {
  7530.                swrast->Triangle = smooth_ci_triangle;
  7531.             }
  7532.         }
  7533.         else {
  7534.            /* flat shaded, no texturing, stippled or some raster ops */
  7535.             if (rgbmode) {
  7536.               swrast->Triangle = flat_rgba_triangle;
  7537.             }
  7538.             else {
  7539.                swrast->Triangle = flat_ci_triangle;;
  7540.             }
  7541.         }
  7542.       }
  7543.    }
  7544.    else if (ctx->RenderMode==0x1C01) {
  7545.       swrast->Triangle = _mesa_feedback_triangle;;
  7546.    }
  7547.    else {
  7548.       /* GL_SELECT mode */
  7549.       swrast->Triangle = _mesa_select_triangle;;
  7550.    }
  7551. }
  7552.