home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / swrast / s_aatriangle.cpp < prev    next >
C/C++ Source or Header  |  2002-12-27  |  82KB  |  2,198 lines

  1. /* $Id: s_aatriangle.c,v 1.26 2002/10/24 23:57:24 brianp Exp $ */
  2. #include "glheader.h"
  3. #include "macros.h"
  4. #include "imports.h"
  5. #include "mmath.h"
  6. #include "s_aatriangle.h"
  7. #include "s_context.h"
  8. #include "s_span.h"
  9.  
  10. #define FIST_MAGIC ((((65536.0 * 65536.0 * 16)+(65536.0 * 0.5))* 65536.0))
  11.  
  12.  
  13. /*
  14.  * Compute coefficients of a plane using the X,Y coords of the v0, v1, v2
  15.  * vertices and the given Z values.
  16.  * A point (x,y,z) lies on plane iff a*x+b*y+c*z+d = 0.
  17.  */
  18. static   void INLINE
  19. compute_plane(const GLfloat v0[], const GLfloat v1[], const GLfloat v2[],
  20.               GLfloat z0, GLfloat z1, GLfloat z2, GLfloat plane[4])
  21. {
  22.    const GLfloat px = v1[0] - v0[0];
  23.    const GLfloat py = v1[1] - v0[1];
  24.    const GLfloat pz = z1 - z0;
  25.  
  26.    const GLfloat qx = v2[0] - v0[0];
  27.    const GLfloat qy = v2[1] - v0[1];
  28.    const GLfloat qz = z2 - z0;
  29.  
  30.    /* Crossproduct "(a,b,c):= dv1 x dv2" is orthogonal to plane. */
  31.    const GLfloat a = py * qz - pz * qy;
  32.    const GLfloat b = pz * qx - px * qz;
  33.    const GLfloat c = px * qy - py * qx;
  34.    /* Point on the plane = "r*(a,b,c) + w", with fixed "r" depending
  35.       on the distance of plane from origin and arbitrary "w" parallel
  36.       to the plane. */
  37.    /* The scalar product "(r*(a,b,c)+w)*(a,b,c)" is "r*(a^2+b^2+c^2)",
  38.       which is equal to "-d" below. */
  39.    const GLfloat d = -(a * v0[0] + b * v0[1] + c * z0);
  40.  
  41.    plane[0] = a;
  42.    plane[1] = b;
  43.    plane[2] = c;
  44.    plane[3] = d;
  45. }
  46.  
  47.  
  48. /*
  49.  * Compute coefficients of a plane with a constant Z value.
  50.  */
  51. static void INLINE
  52. constant_plane(GLfloat value, GLfloat plane[4])
  53. {
  54.    plane[0] = 0.0;
  55.    plane[1] = 0.0;
  56.    plane[2] = -1.0;
  57.    plane[3] = value;
  58. }
  59.  
  60.  
  61. /*
  62.  * Solve plane equation for Z at (X,Y).
  63.  */
  64. static  GLfloat INLINE
  65. solve_plane(GLfloat x, GLfloat y, const GLfloat plane[4])
  66. {
  67.    return (plane[3] + plane[0] * x + plane[1] * y) / -plane[2];
  68. }
  69.  
  70.  
  71. /*
  72.  * Return 1 / solve_plane().
  73.  */
  74. static  GLfloat  INLINE
  75. solve_plane_recip(GLfloat x, GLfloat y, const GLfloat plane[4])
  76. {
  77.    const GLfloat denom = plane[3] + plane[0] * x + plane[1] * y;
  78.    if (denom == 0.0F)
  79.       return 0.0F;
  80.    else
  81.       return -plane[2] / denom;
  82. }
  83.  
  84.  
  85. /*
  86.  * Solve plane and return clamped GLchan value.
  87.  */
  88. static  GLchan INLINE
  89. solve_plane_chan(GLfloat x, GLfloat y, const GLfloat plane[4])
  90. {
  91.    GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2] + 0.5F;
  92.    if (z < 0.0F)
  93.       return 0;
  94.    else if (z > 255.0F)
  95.       return (GLchan) 255.0F;
  96.    return (GLchan) (GLint) z;
  97. }
  98.  
  99.  
  100. #if 0
  101. /*
  102.  * Compute how much (area) of the given pixel is inside the triangle.
  103.  * Vertices MUST be specified in counter-clockwise order.
  104.  * Return:  coverage in [0, 1].
  105.  */
  106. /* static */ GLfloat
  107. compute_coveragef(const GLfloat v0[3], const GLfloat v1[3],
  108.                   const GLfloat v2[3], GLint winx, GLint winy)
  109. {
  110.    /* Given a position [0,3]x[0,3] return the sub-pixel sample position.
  111.     * Contributed by Ray Tice.
  112.     *
  113.     * Jitter sample positions -
  114.     * - average should be .5 in x & y for each column
  115.     * - each of the 16 rows and columns should be used once
  116.     * - the rectangle formed by the first four points
  117.     *   should contain the other points
  118.     * - the distrubition should be fairly even in any given direction
  119.     *
  120.     * The pattern drawn below isn't optimal, but it's better than a regular
  121.     * grid.  In the drawing, the center of each subpixel is surrounded by
  122.     * four dots.  The "x" marks the jittered position relative to the
  123.     * subpixel center.
  124.     */
  125.    static const GLfloat samples[16][2] = {
  126.       /* start with the four corners */
  127.       { (0.5+0*4+2)/16, (0.5+0*4+0)/16 },
  128.       { (0.5+3*4+3)/16, (0.5+0*4+2)/16 },
  129.       { (0.5+0*4+0)/16, (0.5+3*4+1)/16 },
  130.       { (0.5+3*4+1)/16, (0.5+3*4+3)/16 },
  131.       /* continue with interior samples */
  132.       { (0.5+1*4+1)/16, (0.5+0*4+1)/16 },
  133.       { (0.5+2*4+0)/16, (0.5+0*4+3)/16 },
  134.       { (0.5+0*4+3)/16, (0.5+1*4+3)/16 },
  135.       { (0.5+1*4+2)/16, (0.5+1*4+0)/16 },
  136.       { (0.5+2*4+3)/16, (0.5+1*4+2)/16 },
  137.       { (0.5+3*4+2)/16, (0.5+1*4+1)/16 },
  138.       { (0.5+0*4+1)/16, (0.5+2*4+2)/16 },
  139.       { (0.5+1*4+0)/16, (0.5+2*4+1)/16 },
  140.       { (0.5+2*4+1)/16, (0.5+2*4+3)/16 },
  141.       { (0.5+3*4+0)/16, (0.5+2*4+0)/16 },
  142.       { (0.5+1*4+3)/16, (0.5+3*4+0)/16 },
  143.       { (0.5+2*4+2)/16, (0.5+3*4+2)/16 }
  144.    };
  145.  
  146.    const GLfloat x = (GLfloat) winx;
  147.    const GLfloat y = (GLfloat) winy;
  148.    const GLfloat dx0 = v1[0] - v0[0];
  149.    const GLfloat dy0 = v1[1] - v0[1];
  150.    const GLfloat dx1 = v2[0] - v1[0];
  151.    const GLfloat dy1 = v2[1] - v1[1];
  152.    const GLfloat dx2 = v0[0] - v2[0];
  153.    const GLfloat dy2 = v0[1] - v2[1];
  154.    GLint stop = 4, i;
  155.    GLfloat insideCount = 16.0F;
  156.  
  157.  
  158.    for (i = 0; i < stop; i++) {
  159.       const GLfloat sx = x + samples[i][0];
  160.       const GLfloat sy = y + samples[i][1];
  161.       const GLfloat fx0 = sx - v0[0];
  162.       const GLfloat fy0 = sy - v0[1];
  163.       const GLfloat fx1 = sx - v1[0];
  164.       const GLfloat fy1 = sy - v1[1];
  165.       const GLfloat fx2 = sx - v2[0];
  166.       const GLfloat fy2 = sy - v2[1];
  167.       /* cross product determines if sample is inside or outside each edge */
  168.       GLfloat cross0 = (dx0 * fy0 - dy0 * fx0);
  169.       GLfloat cross1 = (dx1 * fy1 - dy1 * fx1);
  170.       GLfloat cross2 = (dx2 * fy2 - dy2 * fx2);
  171.       /* Check if the sample is exactly on an edge.  If so, let cross be a
  172.        * positive or negative value depending on the direction of the edge.
  173.        */
  174.       if (cross0 == 0.0F)
  175.          cross0 = dx0 + dy0;
  176.       if (cross1 == 0.0F)
  177.          cross1 = dx1 + dy1;
  178.       if (cross2 == 0.0F)
  179.          cross2 = dx2 + dy2;
  180.       if (cross0 < 0.0F || cross1 < 0.0F || cross2 < 0.0F) {
  181.          /* point is outside triangle */
  182.          insideCount -= 1.0F;
  183.          stop = 16;
  184.       }
  185.    }
  186.    if (stop == 4)
  187.       return 1.0F;
  188.    else
  189.       return insideCount * (1.0F / 16.0F);
  190. }
  191. #else
  192. /* EVG code */
  193.  
  194. static  GLfloat
  195. compute_coveragef(const GLfloat v0[3], const GLfloat v1[3],
  196.                   const GLfloat v2[3], GLint winx, GLint winy)
  197. {
  198.    static const GLfloat samples[16][2] = {
  199.       /* start with the four corners */
  200.       { (0.5+0*4+2)/16, (0.5+0*4+0)/16 },
  201.       { (0.5+3*4+3)/16, (0.5+0*4+2)/16 },
  202.       { (0.5+0*4+0)/16, (0.5+3*4+1)/16 },
  203.       { (0.5+3*4+1)/16, (0.5+3*4+3)/16 },
  204.       /* continue with interior samples */
  205.       { (0.5+1*4+1)/16, (0.5+0*4+1)/16 },
  206.       { (0.5+2*4+0)/16, (0.5+0*4+3)/16 },
  207.       { (0.5+0*4+3)/16, (0.5+1*4+3)/16 },
  208.       { (0.5+1*4+2)/16, (0.5+1*4+0)/16 },
  209.       { (0.5+2*4+3)/16, (0.5+1*4+2)/16 },
  210.       { (0.5+3*4+2)/16, (0.5+1*4+1)/16 },
  211.       { (0.5+0*4+1)/16, (0.5+2*4+2)/16 },
  212.       { (0.5+1*4+0)/16, (0.5+2*4+1)/16 },
  213.       { (0.5+2*4+1)/16, (0.5+2*4+3)/16 },
  214.       { (0.5+3*4+0)/16, (0.5+2*4+0)/16 },
  215.       { (0.5+1*4+3)/16, (0.5+3*4+0)/16 },
  216.       { (0.5+2*4+2)/16, (0.5+3*4+2)/16 }
  217.    };
  218.  
  219.    const GLfloat x = (GLfloat) winx;
  220.    const GLfloat y = (GLfloat) winy;
  221.    const GLfloat dx0 = v1[0] - v0[0];
  222.    const GLfloat dy0 = v1[1] - v0[1];
  223.    const GLfloat dx1 = v2[0] - v1[0];
  224.    const GLfloat dy1 = v2[1] - v1[1];
  225. /* const */ GLfloat dx2 = v0[0] - v2[0];
  226. /* const */ GLfloat dy2 = v0[1] - v2[1];
  227.    GLfloat cross0,cross1,cross2;
  228.    GLint stop = 4, i;
  229.    GLfloat insideCount = 16.0F;
  230.  
  231.  
  232.    for (i = 0; i < stop; i++) {
  233.       const GLfloat sx = x + samples[i][0];
  234.       const GLfloat sy = y + samples[i][1];
  235. //      const GLfloat fx0 = sx - v0[0];
  236. //      const GLfloat fy0 = sy - v0[1];
  237. //      const GLfloat fx1 = sx - v1[0];
  238. //      const GLfloat fy1 = sy - v1[1];
  239. //      const GLfloat fx2 = sx - v2[0];
  240. //      const GLfloat fy2 = sy - v2[1];
  241.  
  242. //      fx0 = sx - v0[0];
  243. //      fy0 = sy - v0[1];
  244.       /* cross product determines if sample is inside or outside each edge */
  245.       cross0 = (dx0 * (sy - v0[1]) - dy0 * (sx - v0[0]));
  246.       /* Check if the sample is exactly on an edge.  If so, let cross be a
  247.        * positive or negative value depending on the direction of the edge.
  248.        */
  249.       if (cross0 == 0.0F)
  250.          cross0 = dx0 + dy0;
  251.       if (cross0 < 0.0F) {
  252.          /* point is outside triangle */
  253.          insideCount--;
  254.          stop = 16;
  255.          continue;
  256.       }
  257. //      fx1 = sx - v1[0];
  258. //      fy1 = sy - v1[1];
  259.  
  260. //      cross1 = (dx1 * fy1 - dy1 * fx1);
  261.       cross1 = (dx1 * (sy - v1[1]) - dy1 * (sx - v1[0]));
  262.  
  263.       if (cross1 == 0.0F)
  264.          cross1 = dx1 + dy1;
  265.       if (cross1 < 0.0F) {
  266.          /* point is outside triangle */
  267.          insideCount--;
  268.          stop = 16;
  269.          continue;
  270.       }
  271. //      fx2 = sx - v2[0];
  272. //      fy2 = sy - v2[1];
  273. //    cross2 = (dx2 * fy2 - dy2 * fx2);
  274.       cross2 = (dx2 * (sy - v2[1]) - dy2 * (sx - v2[0]));
  275.       if (cross2 == 0.0F)
  276.          cross2 = dx2 + dy2;
  277.       if (cross2 < 0.0F) {
  278.          /* point is outside triangle */
  279.          insideCount--;
  280.          stop = 16;
  281.       }
  282.    }
  283.  
  284.    if (stop == 4)
  285.       return 1.0F;
  286.    else
  287.       return insideCount * (1.0F / 16.0F);
  288.  
  289. }
  290.  
  291. #endif
  292.  
  293.  
  294. /*
  295.  * Compute how much (area) of the given pixel is inside the triangle.
  296.  * Vertices MUST be specified in counter-clockwise order.
  297.  * Return:  coverage in [0, 15].
  298.  */
  299. static GLint
  300. compute_coveragei(const GLfloat v0[3], const GLfloat v1[3],
  301.                   const GLfloat v2[3], GLint winx, GLint winy)
  302. {
  303.    /* NOTE: 15 samples instead of 16. */
  304.    static const GLfloat samples[15][2] = {
  305.       /* start with the four corners */
  306.       { (0.5+0*4+2)/16, (0.5+0*4+0)/16 },
  307.       { (0.5+3*4+3)/16, (0.5+0*4+2)/16 },
  308.       { (0.5+0*4+0)/16, (0.5+3*4+1)/16 },
  309.       { (0.5+3*4+1)/16, (0.5+3*4+3)/16 },
  310.       /* continue with interior samples */
  311.       { (0.5+1*4+1)/16, (0.5+0*4+1)/16 },
  312.       { (0.5+2*4+0)/16, (0.5+0*4+3)/16 },
  313.       { (0.5+0*4+3)/16, (0.5+1*4+3)/16 },
  314.       { (0.5+1*4+2)/16, (0.5+1*4+0)/16 },
  315.       { (0.5+2*4+3)/16, (0.5+1*4+2)/16 },
  316.       { (0.5+3*4+2)/16, (0.5+1*4+1)/16 },
  317.       { (0.5+0*4+1)/16, (0.5+2*4+2)/16 },
  318.       { (0.5+1*4+0)/16, (0.5+2*4+1)/16 },
  319.       { (0.5+2*4+1)/16, (0.5+2*4+3)/16 },
  320.       { (0.5+3*4+0)/16, (0.5+2*4+0)/16 },
  321.       { (0.5+1*4+3)/16, (0.5+3*4+0)/16 }
  322.    };
  323.    const GLfloat x = (GLfloat) winx;
  324.    const GLfloat y = (GLfloat) winy;
  325.    const GLfloat dx0 = v1[0] - v0[0];
  326.    const GLfloat dy0 = v1[1] - v0[1];
  327.    const GLfloat dx1 = v2[0] - v1[0];
  328.    const GLfloat dy1 = v2[1] - v1[1];
  329.    const GLfloat dx2 = v0[0] - v2[0];
  330.    const GLfloat dy2 = v0[1] - v2[1];
  331.    GLint stop = 4, i;
  332.    GLint insideCount = 15;
  333.  
  334.  
  335.    for (i = 0; i < stop; i++) {
  336.       const GLfloat sx = x + samples[i][0];
  337.       const GLfloat sy = y + samples[i][1];
  338.       const GLfloat fx0 = sx - v0[0];
  339.       const GLfloat fy0 = sy - v0[1];
  340.       const GLfloat fx1 = sx - v1[0];
  341.       const GLfloat fy1 = sy - v1[1];
  342.       const GLfloat fx2 = sx - v2[0];
  343.       const GLfloat fy2 = sy - v2[1];
  344.       /* cross product determines if sample is inside or outside each edge */
  345.       GLfloat cross0 = (dx0 * fy0 - dy0 * fx0);
  346.       GLfloat cross1 = (dx1 * fy1 - dy1 * fx1);
  347.       GLfloat cross2 = (dx2 * fy2 - dy2 * fx2);
  348.       /* Check if the sample is exactly on an edge.  If so, let cross be a
  349.        * positive or negative value depending on the direction of the edge.
  350.        */
  351.       if (cross0 == 0.0F)
  352.          cross0 = dx0 + dy0;
  353.       if (cross1 == 0.0F)
  354.          cross1 = dx1 + dy1;
  355.       if (cross2 == 0.0F)
  356.          cross2 = dx2 + dy2;
  357.       if (cross0 < 0.0F || cross1 < 0.0F || cross2 < 0.0F) {
  358.          /* point is outside triangle */
  359.          insideCount--;
  360.          stop = 15;
  361.       }
  362.    }
  363.    if (stop == 4)
  364.       return 15;
  365.    else
  366.       return insideCount;
  367. }
  368. /****************************/
  369. #if 0
  370.  
  371. //EK DEBUG
  372. int debug_write(int *buff, int n);
  373.  
  374.  
  375. /* static */
  376. void
  377. rgba_aa_tri(GLcontext *ctx,
  378.            const SWvertex *v0,
  379.            const SWvertex *v1,
  380.            const SWvertex *v2)
  381. {
  382.  
  383. /*void triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv )*/
  384. {
  385.    const GLfloat *p0 = v0->win;
  386.    const GLfloat *p1 = v1->win;
  387.    const GLfloat *p2 = v2->win;
  388.    const SWvertex *vMin, *vMid, *vMax;
  389.    GLint iyMin, iyMax;
  390.    GLfloat yMin, yMax;
  391.    GLboolean ltor;
  392.    GLfloat majDx, majDy;  /* major (i.e. long) edge dx and dy */
  393.  
  394.    struct sw_span span;
  395.  
  396.    GLfloat zPlane[4];
  397.    GLfloat fogPlane[4];
  398.    GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];
  399.    GLfloat bf = ((SWcontext *)ctx->swrast_context)->_backface_sign;
  400.  
  401. // {
  402. //      _mesa_debug(ctx, "rgba_aa_tri_start: (%f,%f,%f),(%f,%f,%f),(%f,%f,%f)\n",
  403. //        v0->win[0],v0->win[1],v0->win[2],
  404. //        v1->win[0],v1->win[1],v1->win[2],
  405. //        v2->win[0],v2->win[1],v2->win[2] );
  406. //
  407. // }
  408. //printf(__FUNCTION__"ctx=%p,pv1=%p,pv2=%p,v3=%p",   ctx, v0,v1,v2);
  409. //            printf(",v1=%i,v2=%i,3=%i\n",  *v0,*v1,*v2);
  410.   { int tmp[4];
  411.     tmp[0] = 0;
  412.     if(ctx) tmp[0] = 1;
  413.     tmp[1] = 0;
  414.     if(v0) tmp[1] = 1;
  415.     tmp[2] = 0;
  416.     if(v1) tmp[2] = 1;
  417.     tmp[3] = 0;
  418.     if(v1) tmp[3] = 1;
  419.  
  420.    debug_write(tmp, 4);
  421.   }
  422.    do {
  423.     (span).primitive = (0x0009);
  424.     (span).interpMask = (0);
  425.     (span).arrayMask = (0x100);
  426.     (span).start = 0;
  427.     (span).end = (0);
  428.     (span).facing = 0;
  429.     (span).array = ((SWcontext *)ctx->swrast_context)->SpanArrays;
  430.    } while (0);
  431.  
  432.    /* determine bottom to top order of vertices */
  433.    {
  434.       GLfloat y0 = v0->win[1];
  435.       GLfloat y1 = v1->win[1];
  436.       GLfloat y2 = v2->win[1];
  437.       if (y0 <= y1) {
  438.         if (y1 <= y2) {
  439.            vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
  440.         }
  441.         else if (y2 <= y0) {
  442.            vMin = v2;   vMid = v0;   vMax = v1;   /* y2<=y0<=y1 */
  443.         }
  444.         else {
  445.            vMin = v0;   vMid = v2;   vMax = v1;  bf = -bf; /* y0<=y2<=y1 */
  446.         }
  447.       }
  448.       else {
  449.         if (y0 <= y2) {
  450.            vMin = v1;   vMid = v0;   vMax = v2;  bf = -bf; /* y1<=y0<=y2 */
  451.         }
  452.         else if (y2 <= y1) {
  453.            vMin = v2;   vMid = v1;   vMax = v0;  bf = -bf; /* y2<=y1<=y0 */
  454.         }
  455.         else {
  456.            vMin = v1;   vMid = v2;   vMax = v0;   /* y1<=y2<=y0 */
  457.         }
  458.       }
  459.    }
  460.  
  461.    majDx = vMax->win[0] - vMin->win[0];
  462.    majDy = vMax->win[1] - vMin->win[1];
  463.  
  464.    {
  465.       const GLfloat botDx = vMid->win[0] - vMin->win[0];
  466.       const GLfloat botDy = vMid->win[1] - vMin->win[1];
  467.       const GLfloat area = majDx * botDy - botDx * majDy;
  468.       ltor = (GLboolean) (area < 0.0F);
  469.       /* Do backface culling */
  470.       if (area * bf < 0 || area == 0 || IS_INF_OR_NAN(area))
  471.         return;
  472.    }
  473.  
  474.    ctx->OcclusionResult = 0x1;
  475.  
  476.    /* Plane equation setup:
  477.     * We evaluate plane equations at window (x,y) coordinates in order
  478.     * to compute color, Z, fog, texcoords, etc.  This isn't terribly
  479.     * efficient but it's easy and reliable.
  480.     */
  481.    compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
  482.    span.arrayMask |= 0x008;
  483.    compute_plane(p0, p1, p2, v0->fog, v1->fog, v2->fog, fogPlane);
  484.    span.arrayMask |= 0x010;
  485.    if (ctx->Light.ShadeModel == 0x1D01) {
  486.       compute_plane(p0, p1, p2, v0->color[RCOMP], v1->color[RCOMP], v2->color[RCOMP], rPlane);
  487.       compute_plane(p0, p1, p2, v0->color[GCOMP], v1->color[GCOMP], v2->color[GCOMP], gPlane);
  488.       compute_plane(p0, p1, p2, v0->color[BCOMP], v1->color[BCOMP], v2->color[BCOMP], bPlane);
  489.       compute_plane(p0, p1, p2, v0->color[ACOMP], v1->color[ACOMP], v2->color[ACOMP], aPlane);
  490.    }
  491.    else {
  492.       constant_plane(v2->color[RCOMP], rPlane);
  493.       constant_plane(v2->color[GCOMP], gPlane);
  494.       constant_plane(v2->color[BCOMP], bPlane);
  495.       constant_plane(v2->color[ACOMP], aPlane);
  496.    }
  497.    span.arrayMask |= 0x001;
  498.  
  499.    /* Begin bottom-to-top scan over the triangle.
  500.     * The long edge will either be on the left or right side of the
  501.     * triangle.  We always scan from the long edge toward the shorter
  502.     * edges, stopping when we find that coverage = 0.  If the long edge
  503.     * is on the left we scan left-to-right.  Else, we scan right-to-left.
  504.     */
  505.    yMin = vMin->win[1];
  506.    yMax = vMax->win[1];
  507.    iyMin = (GLint) yMin;
  508.    iyMax = (GLint) yMax + 1;
  509.  
  510.    if (ltor) {
  511.       /* scan left to right */
  512.       const GLfloat *pMin = vMin->win;
  513.       const GLfloat *pMid = vMid->win;
  514.       const GLfloat *pMax = vMax->win;
  515.       const GLfloat dxdy = majDx / majDy;
  516.       const GLfloat xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
  517.       GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
  518.       GLint iy;
  519.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  520.          GLint ix, startX = (GLint) (x - xAdj);
  521.          GLuint count;
  522.          GLfloat coverage = 0.0F;
  523.  
  524.          /* skip over fragments with zero coverage */
  525.          while (startX < 2048) {
  526.             coverage = compute_coveragef(pMin, pMid, pMax, startX, iy);
  527.             if (coverage > 0.0F)
  528.                break;
  529.             startX++;
  530.          }
  531.  
  532.          /* enter interior of triangle */
  533.          ix = startX;
  534.          count = 0;
  535.          while (coverage > 0.0F) {
  536.             /* (cx,cy) = center of fragment */
  537.             const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
  538.             struct span_arrays *array = span.array;
  539.             array->coverage[count] = coverage;
  540.             array->z[count] = (GLdepth) solve_plane(cx, cy, zPlane);
  541.            array->fog[count] = solve_plane(cx, cy, fogPlane);
  542.             array->rgba[count][RCOMP] = solve_plane_chan(cx, cy, rPlane);
  543.             array->rgba[count][GCOMP] = solve_plane_chan(cx, cy, gPlane);
  544.             array->rgba[count][BCOMP] = solve_plane_chan(cx, cy, bPlane);
  545.             array->rgba[count][ACOMP] = solve_plane_chan(cx, cy, aPlane);
  546.             ix++;
  547.             count++;
  548.             coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
  549.          }
  550.  
  551.          if (ix <= startX)
  552.             continue;
  553.  
  554.          span.x = startX;
  555.          span.y = iy;
  556.          span.end = (GLuint) ix - (GLuint) startX;
  557.          ;
  558.          _mesa_write_rgba_span(ctx, &span);
  559.       }
  560.    }
  561.    else {
  562.       /* scan right to left */
  563.       const GLfloat *pMin = vMin->win;
  564.       const GLfloat *pMid = vMid->win;
  565.       const GLfloat *pMax = vMax->win;
  566.       const GLfloat dxdy = majDx / majDy;
  567.       const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
  568.       GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
  569.       GLint iy;
  570.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  571.          GLint ix, left, startX = (GLint) (x + xAdj);
  572.          GLuint count, n;
  573.          GLfloat coverage = 0.0F;
  574.  
  575.          /* make sure we're not past the window edge */
  576.          if (startX >= ctx->DrawBuffer->_Xmax) {
  577.             startX = ctx->DrawBuffer->_Xmax - 1;
  578.          }
  579.  
  580.          /* skip fragments with zero coverage */
  581.          while (startX >= 0) {
  582.             coverage = compute_coveragef(pMin, pMax, pMid, startX, iy);
  583.             if (coverage > 0.0F)
  584.                break;
  585.             startX--;
  586.          }
  587.  
  588.          /* enter interior of triangle */
  589.          ix = startX;
  590.          count = 0;
  591.          while (coverage > 0.0F) {
  592.             /* (cx,cy) = center of fragment */
  593.             const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
  594.             struct span_arrays *array = span.array;
  595.             array->coverage[ix] = coverage;
  596.             array->z[ix] = (GLdepth) solve_plane(cx, cy, zPlane);
  597.             array->fog[ix] = solve_plane(cx, cy, fogPlane);
  598.             array->rgba[ix][RCOMP] = solve_plane_chan(cx, cy, rPlane);
  599.             array->rgba[ix][GCOMP] = solve_plane_chan(cx, cy, gPlane);
  600.             array->rgba[ix][BCOMP] = solve_plane_chan(cx, cy, bPlane);
  601.             array->rgba[ix][ACOMP] = solve_plane_chan(cx, cy, aPlane);
  602.             ix--;
  603.             count++;
  604.             coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
  605.          }
  606.  
  607.          if (startX <= ix)
  608.             continue;
  609.  
  610.          n = (GLuint) startX - (GLuint) ix;
  611.  
  612.          left = ix + 1;
  613.  
  614.          /* shift all values to the left */
  615.          /* XXX this is temporary */
  616.          {
  617.             struct span_arrays *array = span.array;
  618.             GLint j;
  619.             for (j = 0; j < (GLint) n; j++) {
  620.                (array->rgba[j])[0] = (array->rgba[j + left])[0];
  621.                (array->rgba[j])[1] = (array->rgba[j + left])[1];
  622.                (array->rgba[j])[2] = (array->rgba[j + left])[2];
  623.                (array->rgba[j])[3] = (array->rgba[j + left])[3];
  624.                array->z[j] = array->z[j + left];
  625.                array->fog[j] = array->fog[j + left];
  626.                array->coverage[j] = array->coverage[j + left];
  627.             }
  628.          }
  629.  
  630.          span.x = left;
  631.          span.y = iy;
  632.          span.end = n;
  633.          ;
  634.          _mesa_write_rgba_span(ctx, &span);
  635.       }
  636.    }
  637.  
  638. // {
  639. //      _mesa_debug(ctx, "rgba_aa_tri_End  : (%f,%f,%f),(%f,%f,%f),(%f,%f,%f)\n",
  640. //        v0->win[0],v0->win[1],v0->win[2],
  641. //        v1->win[0],v1->win[1],v1->win[2],
  642. //        v2->win[0],v2->win[1],v2->win[2] );
  643. //
  644. // }
  645.  
  646. }
  647.  
  648.  
  649. }
  650. #else
  651.  
  652. F_swrast_tri_func rgba_aa_tri;
  653.  
  654. //void
  655. //rgba_aa_tri(GLcontext *ctx,
  656. //           const SWvertex *v0,
  657. //           const SWvertex *v1,
  658. //           const SWvertex *v2);
  659.  
  660. #endif
  661. /************************************************/
  662.  
  663.  
  664. static void
  665. index_aa_tri(GLcontext *ctx,
  666.             const SWvertex *v0,
  667.             const SWvertex *v1,
  668.             const SWvertex *v2)
  669. {
  670. {
  671.    const GLfloat *p0 = v0->win;
  672.    const GLfloat *p1 = v1->win;
  673.    const GLfloat *p2 = v2->win;
  674.    const SWvertex *vMin, *vMid, *vMax;
  675.    GLint iyMin, iyMax;
  676.    GLfloat yMin, yMax;
  677.    GLboolean ltor;
  678.    GLfloat majDx, majDy;  /* major (i.e. long) edge dx and dy */
  679.  
  680.    struct sw_span span;
  681.  
  682.    GLfloat zPlane[4];
  683.    GLfloat fogPlane[4];
  684.    GLfloat iPlane[4];
  685.    GLfloat bf = ((SWcontext *)ctx->swrast_context)->_backface_sign;
  686.  
  687.  
  688.    do { (span).primitive = (0x0009); (span).interpMask = (0); (span).arrayMask = (0x100); (span).start = 0; (span).end = (0); (span).facing = 0; (span).array = ((SWcontext *)ctx->swrast_context)->SpanArrays; } while (0);
  689.  
  690.    /* determine bottom to top order of vertices */
  691.    {
  692.       GLfloat y0 = v0->win[1];
  693.       GLfloat y1 = v1->win[1];
  694.       GLfloat y2 = v2->win[1];
  695.       if (y0 <= y1) {
  696.         if (y1 <= y2) {
  697.            vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
  698.         }
  699.         else if (y2 <= y0) {
  700.            vMin = v2;   vMid = v0;   vMax = v1;   /* y2<=y0<=y1 */
  701.         }
  702.         else {
  703.            vMin = v0;   vMid = v2;   vMax = v1;  bf = -bf; /* y0<=y2<=y1 */
  704.         }
  705.       }
  706.       else {
  707.         if (y0 <= y2) {
  708.            vMin = v1;   vMid = v0;   vMax = v2;  bf = -bf; /* y1<=y0<=y2 */
  709.         }
  710.         else if (y2 <= y1) {
  711.            vMin = v2;   vMid = v1;   vMax = v0;  bf = -bf; /* y2<=y1<=y0 */
  712.         }
  713.         else {
  714.            vMin = v1;   vMid = v2;   vMax = v0;   /* y1<=y2<=y0 */
  715.         }
  716.       }
  717.    }
  718.  
  719.    majDx = vMax->win[0] - vMin->win[0];
  720.    majDy = vMax->win[1] - vMin->win[1];
  721.  
  722.    {
  723.       const GLfloat botDx = vMid->win[0] - vMin->win[0];
  724.       const GLfloat botDy = vMid->win[1] - vMin->win[1];
  725.       const GLfloat area = majDx * botDy - botDx * majDy;
  726.       ltor = (GLboolean) (area < 0.0F);
  727.       /* Do backface culling */
  728.       if (area * bf < 0 || area == 0 || IS_INF_OR_NAN(area))
  729.         return;
  730.    }
  731.  
  732.    ctx->OcclusionResult = 0x1;
  733.  
  734.    /* Plane equation setup:
  735.     * We evaluate plane equations at window (x,y) coordinates in order
  736.     * to compute color, Z, fog, texcoords, etc.  This isn't terribly
  737.     * efficient but it's easy and reliable.
  738.     */
  739.    compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
  740.    span.arrayMask |= 0x008;
  741.    compute_plane(p0, p1, p2, v0->fog, v1->fog, v2->fog, fogPlane);
  742.    span.arrayMask |= 0x010;
  743.    if (ctx->Light.ShadeModel == 0x1D01) {
  744.       compute_plane(p0, p1, p2, (GLfloat) v0->index,
  745.                     (GLfloat) v1->index, (GLfloat) v2->index, iPlane);
  746.    }
  747.    else {
  748.       constant_plane((GLfloat) v2->index, iPlane);
  749.    }
  750.    span.arrayMask |= 0x004;
  751.  
  752.    /* Begin bottom-to-top scan over the triangle.
  753.     * The long edge will either be on the left or right side of the
  754.     * triangle.  We always scan from the long edge toward the shorter
  755.     * edges, stopping when we find that coverage = 0.  If the long edge
  756.     * is on the left we scan left-to-right.  Else, we scan right-to-left.
  757.     */
  758.    yMin = vMin->win[1];
  759.    yMax = vMax->win[1];
  760.    iyMin = (GLint) yMin;
  761.    iyMax = (GLint) yMax + 1;
  762.  
  763.    if (ltor) {
  764.       /* scan left to right */
  765.       const GLfloat *pMin = vMin->win;
  766.       const GLfloat *pMid = vMid->win;
  767.       const GLfloat *pMax = vMax->win;
  768.       const GLfloat dxdy = majDx / majDy;
  769.       const GLfloat xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
  770.       GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
  771.       GLint iy;
  772.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  773.          GLint ix, startX = (GLint) (x - xAdj);
  774.          GLuint count;
  775.          GLfloat coverage = 0.0F;
  776.  
  777.          /* skip over fragments with zero coverage */
  778.          while (startX < 2048) {
  779.             coverage = compute_coveragef(pMin, pMid, pMax, startX, iy);
  780.             if (coverage > 0.0F)
  781.                break;
  782.             startX++;
  783.          }
  784.  
  785.          /* enter interior of triangle */
  786.          ix = startX;
  787.          count = 0;
  788.          while (coverage > 0.0F) {
  789.             /* (cx,cy) = center of fragment */
  790.             const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
  791.             struct span_arrays *array = span.array;
  792.             array->coverage[count] = (GLfloat) compute_coveragei(pMin, pMid, pMax, ix, iy);
  793.             array->z[count] = (GLdepth) solve_plane(cx, cy, zPlane);
  794.            array->fog[count] = solve_plane(cx, cy, fogPlane);
  795.             array->index[count] = (GLint) solve_plane(cx, cy, iPlane);
  796.             ix++;
  797.             count++;
  798.             coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
  799.          }
  800.  
  801.          if (ix <= startX)
  802.             continue;
  803.  
  804.          span.x = startX;
  805.          span.y = iy;
  806.          span.end = (GLuint) ix - (GLuint) startX;
  807.          ;
  808.          _mesa_write_index_span(ctx, &span);
  809.       }
  810.    }
  811.    else {
  812.       /* scan right to left */
  813.       const GLfloat *pMin = vMin->win;
  814.       const GLfloat *pMid = vMid->win;
  815.       const GLfloat *pMax = vMax->win;
  816.       const GLfloat dxdy = majDx / majDy;
  817.       const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
  818.       GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
  819.       GLint iy;
  820.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  821.          GLint ix, left, startX = (GLint) (x + xAdj);
  822.          GLuint count, n;
  823.          GLfloat coverage = 0.0F;
  824.  
  825.          /* make sure we're not past the window edge */
  826.          if (startX >= ctx->DrawBuffer->_Xmax) {
  827.             startX = ctx->DrawBuffer->_Xmax - 1;
  828.          }
  829.  
  830.          /* skip fragments with zero coverage */
  831.          while (startX >= 0) {
  832.             coverage = compute_coveragef(pMin, pMax, pMid, startX, iy);
  833.             if (coverage > 0.0F)
  834.                break;
  835.             startX--;
  836.          }
  837.  
  838.          /* enter interior of triangle */
  839.          ix = startX;
  840.          count = 0;
  841.          while (coverage > 0.0F) {
  842.             /* (cx,cy) = center of fragment */
  843.             const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
  844.             struct span_arrays *array = span.array;
  845.             array->coverage[ix] = (GLfloat) compute_coveragei(pMin, pMax, pMid, ix, iy);
  846.             array->z[ix] = (GLdepth) solve_plane(cx, cy, zPlane);
  847.             array->fog[ix] = solve_plane(cx, cy, fogPlane);
  848.             array->index[ix] = (GLint) solve_plane(cx, cy, iPlane);
  849.             ix--;
  850.             count++;
  851.             coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
  852.          }
  853.  
  854.          if (startX <= ix)
  855.             continue;
  856.  
  857.          n = (GLuint) startX - (GLuint) ix;
  858.  
  859.          left = ix + 1;
  860.  
  861.          /* shift all values to the left */
  862.          /* XXX this is temporary */
  863.          {
  864.             struct span_arrays *array = span.array;
  865.             GLint j;
  866.             for (j = 0; j < (GLint) n; j++) {
  867.                array->index[j] = array->index[j + left];
  868.                array->z[j] = array->z[j + left];
  869.                array->fog[j] = array->fog[j + left];
  870.                array->coverage[j] = array->coverage[j + left];
  871.             }
  872.          }
  873.  
  874.          span.x = left;
  875.          span.y = iy;
  876.          span.end = n;
  877.          ;
  878.          _mesa_write_index_span(ctx, &span);
  879.       }
  880.    }
  881. }
  882.  
  883.  
  884.  
  885.  
  886. }
  887.  
  888.  
  889. /*
  890.  * Compute mipmap level of detail.
  891.  * XXX we should really include the R coordinate in this computation
  892.  * in order to do 3-D texture mipmapping.
  893.  */
  894. static  GLfloat
  895. compute_lambda(const GLfloat sPlane[4], const GLfloat tPlane[4],
  896.                const GLfloat qPlane[4], GLfloat cx, GLfloat cy,
  897.                GLfloat invQ, GLfloat texWidth, GLfloat texHeight)
  898. {
  899.    const GLfloat s = solve_plane(cx, cy, sPlane);
  900.    const GLfloat t = solve_plane(cx, cy, tPlane);
  901.    const GLfloat invQ_x1 = solve_plane_recip(cx+1.0F, cy, qPlane);
  902.    const GLfloat invQ_y1 = solve_plane_recip(cx, cy+1.0F, qPlane);
  903.    const GLfloat s_x1 = s - sPlane[0] / sPlane[2];
  904.    const GLfloat s_y1 = s - sPlane[1] / sPlane[2];
  905.    const GLfloat t_x1 = t - tPlane[0] / tPlane[2];
  906.    const GLfloat t_y1 = t - tPlane[1] / tPlane[2];
  907.    GLfloat dsdx = s_x1 * invQ_x1 - s * invQ;
  908.    GLfloat dsdy = s_y1 * invQ_y1 - s * invQ;
  909.    GLfloat dtdx = t_x1 * invQ_x1 - t * invQ;
  910.    GLfloat dtdy = t_y1 * invQ_y1 - t * invQ;
  911.    GLfloat maxU, maxV, rho, lambda;
  912.    dsdx = ((GLfloat)__fabs( (dsdx) ));
  913.    dsdy = ((GLfloat)__fabs( (dsdy) ));
  914.    dtdx = ((GLfloat)__fabs( (dtdx) ));
  915.    dtdy = ((GLfloat)__fabs( (dtdy) ));
  916.    maxU = ( (dsdx)>(dsdy) ? (dsdx) : (dsdy) ) * texWidth;
  917.    maxV = ( (dtdx)>(dtdy) ? (dtdx) : (dtdy) ) * texHeight;
  918.    rho = ( (maxU)>(maxV) ? (maxU) : (maxV) );
  919.    lambda = LOG2(rho);
  920.    return lambda;
  921. }
  922.  
  923.  
  924. static void
  925. tex_aa_tri(GLcontext *ctx,
  926.           const SWvertex *v0,
  927.           const SWvertex *v1,
  928.           const SWvertex *v2)
  929. {
  930.    const GLfloat *p0 = v0->win;
  931.    const GLfloat *p1 = v1->win;
  932.    const GLfloat *p2 = v2->win;
  933.    const SWvertex *vMin, *vMid, *vMax;
  934.    GLint iyMin, iyMax;
  935.    GLfloat yMin, yMax;
  936.    GLboolean ltor;
  937.    GLfloat majDx, majDy;  /* major (i.e. long) edge dx and dy */
  938.  
  939.    struct sw_span span;
  940.  
  941.    GLfloat zPlane[4];
  942.    GLfloat fogPlane[4];
  943.    GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];
  944.    GLfloat sPlane[4], tPlane[4], uPlane[4], vPlane[4];
  945.    GLfloat texWidth, texHeight;
  946.    GLfloat bf = ((SWcontext *)ctx->swrast_context)->_backface_sign;
  947.  
  948.  
  949.    do { (span).primitive = (0x0009); (span).interpMask = (0); (span).arrayMask = (0x100); (span).start = 0; (span).end = (0); (span).facing = 0; (span).array = ((SWcontext *)ctx->swrast_context)->SpanArrays; } while (0);
  950.  
  951.    /* determine bottom to top order of vertices */
  952.    {
  953.       GLfloat y0 = v0->win[1];
  954.       GLfloat y1 = v1->win[1];
  955.       GLfloat y2 = v2->win[1];
  956.       if (y0 <= y1) {
  957.         if (y1 <= y2) {
  958.            vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
  959.         }
  960.         else if (y2 <= y0) {
  961.            vMin = v2;   vMid = v0;   vMax = v1;   /* y2<=y0<=y1 */
  962.         }
  963.         else {
  964.            vMin = v0;   vMid = v2;   vMax = v1;  bf = -bf; /* y0<=y2<=y1 */
  965.         }
  966.       }
  967.       else {
  968.         if (y0 <= y2) {
  969.            vMin = v1;   vMid = v0;   vMax = v2;  bf = -bf; /* y1<=y0<=y2 */
  970.         }
  971.         else if (y2 <= y1) {
  972.            vMin = v2;   vMid = v1;   vMax = v0;  bf = -bf; /* y2<=y1<=y0 */
  973.         }
  974.         else {
  975.            vMin = v1;   vMid = v2;   vMax = v0;   /* y1<=y2<=y0 */
  976.         }
  977.       }
  978.    }
  979.  
  980.    majDx = vMax->win[0] - vMin->win[0];
  981.    majDy = vMax->win[1] - vMin->win[1];
  982.  
  983.    {
  984.       const GLfloat botDx = vMid->win[0] - vMin->win[0];
  985.       const GLfloat botDy = vMid->win[1] - vMin->win[1];
  986.       const GLfloat area = majDx * botDy - botDx * majDy;
  987.       ltor = (GLboolean) (area < 0.0F);
  988.       /* Do backface culling */
  989.       if (area * bf < 0 || area == 0 || IS_INF_OR_NAN(area))
  990.         return;
  991.    }
  992.  
  993.    ctx->OcclusionResult = 0x1;
  994.  
  995.    /* Plane equation setup:
  996.     * We evaluate plane equations at window (x,y) coordinates in order
  997.     * to compute color, Z, fog, texcoords, etc.  This isn't terribly
  998.     * efficient but it's easy and reliable.
  999.     */
  1000.    compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
  1001.    span.arrayMask |= 0x008;
  1002.    compute_plane(p0, p1, p2, v0->fog, v1->fog, v2->fog, fogPlane);
  1003.    span.arrayMask |= 0x010;
  1004.    if (ctx->Light.ShadeModel == 0x1D01) {
  1005.       compute_plane(p0, p1, p2, v0->color[RCOMP], v1->color[RCOMP], v2->color[RCOMP], rPlane);
  1006.       compute_plane(p0, p1, p2, v0->color[GCOMP], v1->color[GCOMP], v2->color[GCOMP], gPlane);
  1007.       compute_plane(p0, p1, p2, v0->color[BCOMP], v1->color[BCOMP], v2->color[BCOMP], bPlane);
  1008.       compute_plane(p0, p1, p2, v0->color[ACOMP], v1->color[ACOMP], v2->color[ACOMP], aPlane);
  1009.    }
  1010.    else {
  1011.       constant_plane(v2->color[RCOMP], rPlane);
  1012.       constant_plane(v2->color[GCOMP], gPlane);
  1013.       constant_plane(v2->color[BCOMP], bPlane);
  1014.       constant_plane(v2->color[ACOMP], aPlane);
  1015.    }
  1016.    span.arrayMask |= 0x001;
  1017.    {
  1018.       const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
  1019.       const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];
  1020.       const GLfloat invW0 = v0->win[3];
  1021.       const GLfloat invW1 = v1->win[3];
  1022.       const GLfloat invW2 = v2->win[3];
  1023.       const GLfloat s0 = v0->texcoord[0][0] * invW0;
  1024.       const GLfloat s1 = v1->texcoord[0][0] * invW1;
  1025.       const GLfloat s2 = v2->texcoord[0][0] * invW2;
  1026.       const GLfloat t0 = v0->texcoord[0][1] * invW0;
  1027.       const GLfloat t1 = v1->texcoord[0][1] * invW1;
  1028.       const GLfloat t2 = v2->texcoord[0][1] * invW2;
  1029.       const GLfloat r0 = v0->texcoord[0][2] * invW0;
  1030.       const GLfloat r1 = v1->texcoord[0][2] * invW1;
  1031.       const GLfloat r2 = v2->texcoord[0][2] * invW2;
  1032.       const GLfloat q0 = v0->texcoord[0][3] * invW0;
  1033.       const GLfloat q1 = v1->texcoord[0][3] * invW1;
  1034.       const GLfloat q2 = v2->texcoord[0][3] * invW2;
  1035.       compute_plane(p0, p1, p2, s0, s1, s2, sPlane);
  1036.       compute_plane(p0, p1, p2, t0, t1, t2, tPlane);
  1037.       compute_plane(p0, p1, p2, r0, r1, r2, uPlane);
  1038.       compute_plane(p0, p1, p2, q0, q1, q2, vPlane);
  1039.       texWidth = (GLfloat) texImage->Width;
  1040.       texHeight = (GLfloat) texImage->Height;
  1041.    }
  1042.    span.arrayMask |= (0x020 | 0x080);
  1043.  
  1044.    /* Begin bottom-to-top scan over the triangle.
  1045.     * The long edge will either be on the left or right side of the
  1046.     * triangle.  We always scan from the long edge toward the shorter
  1047.     * edges, stopping when we find that coverage = 0.  If the long edge
  1048.     * is on the left we scan left-to-right.  Else, we scan right-to-left.
  1049.     */
  1050.    yMin = vMin->win[1];
  1051.    yMax = vMax->win[1];
  1052.    iyMin = (GLint) yMin;
  1053.    iyMax = (GLint) yMax + 1;
  1054.  
  1055.    if (ltor) {
  1056.       /* scan left to right */
  1057.       const GLfloat *pMin = vMin->win;
  1058.       const GLfloat *pMid = vMid->win;
  1059.       const GLfloat *pMax = vMax->win;
  1060.       const GLfloat dxdy = majDx / majDy;
  1061.       const GLfloat xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
  1062.       GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
  1063.       GLint iy;
  1064.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  1065.          GLint ix, startX = (GLint) (x - xAdj);
  1066.          GLuint count;
  1067.          GLfloat coverage = 0.0F;
  1068.  
  1069.          /* skip over fragments with zero coverage */
  1070.          while (startX < 2048) {
  1071.             coverage = compute_coveragef(pMin, pMid, pMax, startX, iy);
  1072.             if (coverage > 0.0F)
  1073.                break;
  1074.             startX++;
  1075.          }
  1076.  
  1077.          /* enter interior of triangle */
  1078.          ix = startX;
  1079.          count = 0;
  1080.          while (coverage > 0.0F) {
  1081.             /* (cx,cy) = center of fragment */
  1082.             const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
  1083.             struct span_arrays *array = span.array;
  1084.             array->coverage[count] = coverage;
  1085.             array->z[count] = (GLdepth) solve_plane(cx, cy, zPlane);
  1086.            array->fog[count] = solve_plane(cx, cy, fogPlane);
  1087.             array->rgba[count][RCOMP] = solve_plane_chan(cx, cy, rPlane);
  1088.             array->rgba[count][GCOMP] = solve_plane_chan(cx, cy, gPlane);
  1089.             array->rgba[count][BCOMP] = solve_plane_chan(cx, cy, bPlane);
  1090.             array->rgba[count][ACOMP] = solve_plane_chan(cx, cy, aPlane);
  1091.             {
  1092.                const GLfloat invQ = solve_plane_recip(cx, cy, vPlane);
  1093.                array->texcoords[0][count][0] = solve_plane(cx, cy, sPlane) * invQ;
  1094.                array->texcoords[0][count][1] = solve_plane(cx, cy, tPlane) * invQ;
  1095.                array->texcoords[0][count][2] = solve_plane(cx, cy, uPlane) * invQ;
  1096.                array->lambda[0][count] = compute_lambda(sPlane, tPlane, vPlane,
  1097.                                                       cx, cy, invQ,
  1098.                                                       texWidth, texHeight);
  1099.             }
  1100.             ix++;
  1101.             count++;
  1102.             coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
  1103.          }
  1104.  
  1105.          if (ix <= startX)
  1106.             continue;
  1107.  
  1108.          span.x = startX;
  1109.          span.y = iy;
  1110.          span.end = (GLuint) ix - (GLuint) startX;
  1111.          ;
  1112.          _mesa_write_texture_span(ctx, &span);
  1113.       }
  1114.    }
  1115.    else {
  1116.       /* scan right to left */
  1117.       const GLfloat *pMin = vMin->win;
  1118.       const GLfloat *pMid = vMid->win;
  1119.       const GLfloat *pMax = vMax->win;
  1120.       const GLfloat dxdy = majDx / majDy;
  1121.       const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
  1122.       GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
  1123.       GLint iy;
  1124.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  1125.          GLint ix, left, startX = (GLint) (x + xAdj);
  1126.          GLuint count, n;
  1127.          GLfloat coverage = 0.0F;
  1128.  
  1129.          /* make sure we're not past the window edge */
  1130.          if (startX >= ctx->DrawBuffer->_Xmax) {
  1131.             startX = ctx->DrawBuffer->_Xmax - 1;
  1132.          }
  1133.  
  1134.          /* skip fragments with zero coverage */
  1135.          while (startX >= 0) {
  1136.             coverage = compute_coveragef(pMin, pMax, pMid, startX, iy);
  1137.             if (coverage > 0.0F)
  1138.                break;
  1139.             startX--;
  1140.          }
  1141.  
  1142.          /* enter interior of triangle */
  1143.          ix = startX;
  1144.          count = 0;
  1145.          while (coverage > 0.0F) {
  1146.             /* (cx,cy) = center of fragment */
  1147.             const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
  1148.             struct span_arrays *array = span.array;
  1149.             array->coverage[ix] = coverage;
  1150.             array->z[ix] = (GLdepth) solve_plane(cx, cy, zPlane);
  1151.             array->fog[ix] = solve_plane(cx, cy, fogPlane);
  1152.             array->rgba[ix][RCOMP] = solve_plane_chan(cx, cy, rPlane);
  1153.             array->rgba[ix][GCOMP] = solve_plane_chan(cx, cy, gPlane);
  1154.             array->rgba[ix][BCOMP] = solve_plane_chan(cx, cy, bPlane);
  1155.             array->rgba[ix][ACOMP] = solve_plane_chan(cx, cy, aPlane);
  1156.             {
  1157.                const GLfloat invQ = solve_plane_recip(cx, cy, vPlane);
  1158.                array->texcoords[0][ix][0] = solve_plane(cx, cy, sPlane) * invQ;
  1159.                array->texcoords[0][ix][1] = solve_plane(cx, cy, tPlane) * invQ;
  1160.                array->texcoords[0][ix][2] = solve_plane(cx, cy, uPlane) * invQ;
  1161.                array->lambda[0][ix] = compute_lambda(sPlane, tPlane, vPlane,
  1162.                                           cx, cy, invQ, texWidth, texHeight);
  1163.             }
  1164.             ix--;
  1165.             count++;
  1166.             coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
  1167.          }
  1168.  
  1169.          if (startX <= ix)
  1170.             continue;
  1171.  
  1172.          n = (GLuint) startX - (GLuint) ix;
  1173.  
  1174.          left = ix + 1;
  1175.  
  1176.          /* shift all values to the left */
  1177.          /* XXX this is temporary */
  1178.          {
  1179.             struct span_arrays *array = span.array;
  1180.             GLint j;
  1181.             for (j = 0; j < (GLint) n; j++) {
  1182.                 (array->rgba[j])[0] = (array->rgba[j + left])[0];
  1183.                 (array->rgba[j])[1] = (array->rgba[j + left])[1];
  1184.                 (array->rgba[j])[2] = (array->rgba[j + left])[2];
  1185.                 (array->rgba[j])[3] = (array->rgba[j + left])[3];
  1186.                array->z[j] = array->z[j + left];
  1187.                array->fog[j] = array->fog[j + left];
  1188.                (array->texcoords[0][j])[0] = (array->texcoords[0][j + left])[0];
  1189.                (array->texcoords[0][j])[1] = (array->texcoords[0][j + left])[1];
  1190.                (array->texcoords[0][j])[2] = (array->texcoords[0][j + left])[2];
  1191.                (array->texcoords[0][j])[3] = (array->texcoords[0][j + left])[3];
  1192.                array->lambda[0][j] = array->lambda[0][j + left];
  1193.                array->coverage[j] = array->coverage[j + left];
  1194.             }
  1195.          }
  1196.  
  1197.          span.x = left;
  1198.          span.y = iy;
  1199.          span.end = n;
  1200.          ;
  1201.          _mesa_write_texture_span(ctx, &span);
  1202.       }
  1203.    }
  1204.  
  1205. }
  1206.  
  1207.  
  1208. static void
  1209. spec_tex_aa_tri(GLcontext *ctx,
  1210.                const SWvertex *v0,
  1211.                const SWvertex *v1,
  1212.                const SWvertex *v2)
  1213. {
  1214.    const GLfloat *p0 = v0->win;
  1215.    const GLfloat *p1 = v1->win;
  1216.    const GLfloat *p2 = v2->win;
  1217.    const SWvertex *vMin, *vMid, *vMax;
  1218.    GLint iyMin, iyMax;
  1219.    GLfloat yMin, yMax;
  1220.    GLboolean ltor;
  1221.    GLfloat majDx, majDy;  /* major (i.e. long) edge dx and dy */
  1222.  
  1223.    struct sw_span span;
  1224.  
  1225.    GLfloat zPlane[4];
  1226.    GLfloat fogPlane[4];
  1227.    GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];
  1228.    GLfloat srPlane[4], sgPlane[4], sbPlane[4];
  1229.    GLfloat sPlane[4], tPlane[4], uPlane[4], vPlane[4];
  1230.    GLfloat texWidth, texHeight;
  1231.    GLfloat bf = ((SWcontext *)ctx->swrast_context)->_backface_sign;
  1232.  
  1233.  
  1234.    do { (span).primitive = (0x0009); (span).interpMask = (0); (span).arrayMask = (0x100); (span).start = 0; (span).end = (0); (span).facing = 0; (span).array = ((SWcontext *)ctx->swrast_context)->SpanArrays; } while (0);
  1235.  
  1236.    /* determine bottom to top order of vertices */
  1237.    {
  1238.       GLfloat y0 = v0->win[1];
  1239.       GLfloat y1 = v1->win[1];
  1240.       GLfloat y2 = v2->win[1];
  1241.       if (y0 <= y1) {
  1242.         if (y1 <= y2) {
  1243.            vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
  1244.         }
  1245.         else if (y2 <= y0) {
  1246.            vMin = v2;   vMid = v0;   vMax = v1;   /* y2<=y0<=y1 */
  1247.         }
  1248.         else {
  1249.            vMin = v0;   vMid = v2;   vMax = v1;  bf = -bf; /* y0<=y2<=y1 */
  1250.         }
  1251.       }
  1252.       else {
  1253.         if (y0 <= y2) {
  1254.            vMin = v1;   vMid = v0;   vMax = v2;  bf = -bf; /* y1<=y0<=y2 */
  1255.         }
  1256.         else if (y2 <= y1) {
  1257.            vMin = v2;   vMid = v1;   vMax = v0;  bf = -bf; /* y2<=y1<=y0 */
  1258.         }
  1259.         else {
  1260.            vMin = v1;   vMid = v2;   vMax = v0;   /* y1<=y2<=y0 */
  1261.         }
  1262.       }
  1263.    }
  1264.  
  1265.    majDx = vMax->win[0] - vMin->win[0];
  1266.    majDy = vMax->win[1] - vMin->win[1];
  1267.  
  1268.    {
  1269.       const GLfloat botDx = vMid->win[0] - vMin->win[0];
  1270.       const GLfloat botDy = vMid->win[1] - vMin->win[1];
  1271.       const GLfloat area = majDx * botDy - botDx * majDy;
  1272.       ltor = (GLboolean) (area < 0.0F);
  1273.       /* Do backface culling */
  1274.       if (area * bf < 0 || area == 0 || IS_INF_OR_NAN(area))
  1275.         return;
  1276.    }
  1277.  
  1278.    ctx->OcclusionResult = 0x1;
  1279.  
  1280.    /* Plane equation setup:
  1281.     * We evaluate plane equations at window (x,y) coordinates in order
  1282.     * to compute color, Z, fog, texcoords, etc.  This isn't terribly
  1283.     * efficient but it's easy and reliable.
  1284.     */
  1285.    compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
  1286.    span.arrayMask |= 0x008;
  1287.    compute_plane(p0, p1, p2, v0->fog, v1->fog, v2->fog, fogPlane);
  1288.    span.arrayMask |= 0x010;
  1289.    if (ctx->Light.ShadeModel == 0x1D01) {
  1290.       compute_plane(p0, p1, p2, v0->color[RCOMP], v1->color[RCOMP], v2->color[RCOMP], rPlane);
  1291.       compute_plane(p0, p1, p2, v0->color[GCOMP], v1->color[GCOMP], v2->color[GCOMP], gPlane);
  1292.       compute_plane(p0, p1, p2, v0->color[BCOMP], v1->color[BCOMP], v2->color[BCOMP], bPlane);
  1293.       compute_plane(p0, p1, p2, v0->color[ACOMP], v1->color[ACOMP], v2->color[ACOMP], aPlane);
  1294.    }
  1295.    else {
  1296.       constant_plane(v2->color[RCOMP], rPlane);
  1297.       constant_plane(v2->color[GCOMP], gPlane);
  1298.       constant_plane(v2->color[BCOMP], bPlane);
  1299.       constant_plane(v2->color[ACOMP], aPlane);
  1300.    }
  1301.    span.arrayMask |= 0x001;
  1302.    if (ctx->Light.ShadeModel == 0x1D01) {
  1303.       compute_plane(p0, p1, p2, v0->specular[RCOMP], v1->specular[RCOMP], v2->specular[RCOMP],srPlane);
  1304.       compute_plane(p0, p1, p2, v0->specular[GCOMP], v1->specular[GCOMP], v2->specular[GCOMP],sgPlane);
  1305.       compute_plane(p0, p1, p2, v0->specular[BCOMP], v1->specular[BCOMP], v2->specular[BCOMP],sbPlane);
  1306.    }
  1307.    else {
  1308.       constant_plane(v2->specular[RCOMP], srPlane);
  1309.       constant_plane(v2->specular[GCOMP], sgPlane);
  1310.       constant_plane(v2->specular[BCOMP], sbPlane);
  1311.    }
  1312.    span.arrayMask |= 0x002;
  1313.    {
  1314.       const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
  1315.       const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];
  1316.       const GLfloat invW0 = v0->win[3];
  1317.       const GLfloat invW1 = v1->win[3];
  1318.       const GLfloat invW2 = v2->win[3];
  1319.       const GLfloat s0 = v0->texcoord[0][0] * invW0;
  1320.       const GLfloat s1 = v1->texcoord[0][0] * invW1;
  1321.       const GLfloat s2 = v2->texcoord[0][0] * invW2;
  1322.       const GLfloat t0 = v0->texcoord[0][1] * invW0;
  1323.       const GLfloat t1 = v1->texcoord[0][1] * invW1;
  1324.       const GLfloat t2 = v2->texcoord[0][1] * invW2;
  1325.       const GLfloat r0 = v0->texcoord[0][2] * invW0;
  1326.       const GLfloat r1 = v1->texcoord[0][2] * invW1;
  1327.       const GLfloat r2 = v2->texcoord[0][2] * invW2;
  1328.       const GLfloat q0 = v0->texcoord[0][3] * invW0;
  1329.       const GLfloat q1 = v1->texcoord[0][3] * invW1;
  1330.       const GLfloat q2 = v2->texcoord[0][3] * invW2;
  1331.       compute_plane(p0, p1, p2, s0, s1, s2, sPlane);
  1332.       compute_plane(p0, p1, p2, t0, t1, t2, tPlane);
  1333.       compute_plane(p0, p1, p2, r0, r1, r2, uPlane);
  1334.       compute_plane(p0, p1, p2, q0, q1, q2, vPlane);
  1335.       texWidth = (GLfloat) texImage->Width;
  1336.       texHeight = (GLfloat) texImage->Height;
  1337.    }
  1338.    span.arrayMask |= (0x020 | 0x080);
  1339.  
  1340.    /* Begin bottom-to-top scan over the triangle.
  1341.     * The long edge will either be on the left or right side of the
  1342.     * triangle.  We always scan from the long edge toward the shorter
  1343.     * edges, stopping when we find that coverage = 0.  If the long edge
  1344.     * is on the left we scan left-to-right.  Else, we scan right-to-left.
  1345.     */
  1346.    yMin = vMin->win[1];
  1347.    yMax = vMax->win[1];
  1348.    iyMin = (GLint) yMin;
  1349.    iyMax = (GLint) yMax + 1;
  1350.  
  1351.    if (ltor) {
  1352.       /* scan left to right */
  1353.       const GLfloat *pMin = vMin->win;
  1354.       const GLfloat *pMid = vMid->win;
  1355.       const GLfloat *pMax = vMax->win;
  1356.       const GLfloat dxdy = majDx / majDy;
  1357.       const GLfloat xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
  1358.       GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
  1359.       GLint iy;
  1360.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  1361.          GLint ix, startX = (GLint) (x - xAdj);
  1362.          GLuint count;
  1363.          GLfloat coverage = 0.0F;
  1364.  
  1365.          /* skip over fragments with zero coverage */
  1366.          while (startX < 2048) {
  1367.             coverage = compute_coveragef(pMin, pMid, pMax, startX, iy);
  1368.             if (coverage > 0.0F)
  1369.                break;
  1370.             startX++;
  1371.          }
  1372.  
  1373.          /* enter interior of triangle */
  1374.          ix = startX;
  1375.          count = 0;
  1376.          while (coverage > 0.0F) {
  1377.             /* (cx,cy) = center of fragment */
  1378.             const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
  1379.             struct span_arrays *array = span.array;
  1380.             array->coverage[count] = coverage;
  1381.             array->z[count] = (GLdepth) solve_plane(cx, cy, zPlane);
  1382.            array->fog[count] = solve_plane(cx, cy, fogPlane);
  1383.             array->rgba[count][RCOMP] = solve_plane_chan(cx, cy, rPlane);
  1384.             array->rgba[count][GCOMP] = solve_plane_chan(cx, cy, gPlane);
  1385.             array->rgba[count][BCOMP] = solve_plane_chan(cx, cy, bPlane);
  1386.             array->rgba[count][ACOMP] = solve_plane_chan(cx, cy, aPlane);
  1387.             array->spec[count][RCOMP] = solve_plane_chan(cx, cy, srPlane);
  1388.             array->spec[count][GCOMP] = solve_plane_chan(cx, cy, sgPlane);
  1389.             array->spec[count][BCOMP] = solve_plane_chan(cx, cy, sbPlane);
  1390.             {
  1391.                const GLfloat invQ = solve_plane_recip(cx, cy, vPlane);
  1392.                array->texcoords[0][count][0] = solve_plane(cx, cy, sPlane) * invQ;
  1393.                array->texcoords[0][count][1] = solve_plane(cx, cy, tPlane) * invQ;
  1394.                array->texcoords[0][count][2] = solve_plane(cx, cy, uPlane) * invQ;
  1395.                array->lambda[0][count] = compute_lambda(sPlane, tPlane, vPlane,
  1396.                                                       cx, cy, invQ,
  1397.                                                       texWidth, texHeight);
  1398.             }
  1399.             ix++;
  1400.             count++;
  1401.             coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
  1402.          }
  1403.  
  1404.          if (ix <= startX)
  1405.             continue;
  1406.  
  1407.          span.x = startX;
  1408.          span.y = iy;
  1409.          span.end = (GLuint) ix - (GLuint) startX;
  1410.          _mesa_write_texture_span(ctx, &span);
  1411.       }
  1412.    }
  1413.    else {
  1414.       /* scan right to left */
  1415.       const GLfloat *pMin = vMin->win;
  1416.       const GLfloat *pMid = vMid->win;
  1417.       const GLfloat *pMax = vMax->win;
  1418.       const GLfloat dxdy = majDx / majDy;
  1419.       const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
  1420.       GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
  1421.       GLint iy;
  1422.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  1423.          GLint ix, left, startX = (GLint) (x + xAdj);
  1424.          GLuint count, n;
  1425.          GLfloat coverage = 0.0F;
  1426.  
  1427.          /* make sure we're not past the window edge */
  1428.          if (startX >= ctx->DrawBuffer->_Xmax) {
  1429.             startX = ctx->DrawBuffer->_Xmax - 1;
  1430.          }
  1431.  
  1432.          /* skip fragments with zero coverage */
  1433.          while (startX >= 0) {
  1434.             coverage = compute_coveragef(pMin, pMax, pMid, startX, iy);
  1435.             if (coverage > 0.0F)
  1436.                break;
  1437.             startX--;
  1438.          }
  1439.  
  1440.          /* enter interior of triangle */
  1441.          ix = startX;
  1442.          count = 0;
  1443.          while (coverage > 0.0F) {
  1444.             /* (cx,cy) = center of fragment */
  1445.             const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
  1446.             struct span_arrays *array = span.array;
  1447.             array->coverage[ix] = coverage;
  1448.             array->z[ix] = (GLdepth) solve_plane(cx, cy, zPlane);
  1449.             array->fog[ix] = solve_plane(cx, cy, fogPlane);
  1450.             array->rgba[ix][RCOMP] = solve_plane_chan(cx, cy, rPlane);
  1451.             array->rgba[ix][GCOMP] = solve_plane_chan(cx, cy, gPlane);
  1452.             array->rgba[ix][BCOMP] = solve_plane_chan(cx, cy, bPlane);
  1453.             array->rgba[ix][ACOMP] = solve_plane_chan(cx, cy, aPlane);
  1454.             array->spec[ix][RCOMP] = solve_plane_chan(cx, cy, srPlane);
  1455.             array->spec[ix][GCOMP] = solve_plane_chan(cx, cy, sgPlane);
  1456.             array->spec[ix][BCOMP] = solve_plane_chan(cx, cy, sbPlane);
  1457.             {
  1458.                const GLfloat invQ = solve_plane_recip(cx, cy, vPlane);
  1459.                array->texcoords[0][ix][0] = solve_plane(cx, cy, sPlane) * invQ;
  1460.                array->texcoords[0][ix][1] = solve_plane(cx, cy, tPlane) * invQ;
  1461.                array->texcoords[0][ix][2] = solve_plane(cx, cy, uPlane) * invQ;
  1462.                array->lambda[0][ix] = compute_lambda(sPlane, tPlane, vPlane,
  1463.                                           cx, cy, invQ, texWidth, texHeight);
  1464.             }
  1465.             ix--;
  1466.             count++;
  1467.             coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
  1468.          }
  1469.  
  1470.          if (startX <= ix)
  1471.             continue;
  1472.  
  1473.          n = (GLuint) startX - (GLuint) ix;
  1474.  
  1475.          left = ix + 1;
  1476.  
  1477.          /* shift all values to the left */
  1478.          /* XXX this is temporary */
  1479.          {
  1480.             struct span_arrays *array = span.array;
  1481.             GLint j;
  1482.             for (j = 0; j < (GLint) n; j++) {
  1483.                 (array->rgba[j])[0] = (array->rgba[j + left])[0];
  1484.                (array->rgba[j])[1] = (array->rgba[j + left])[1];
  1485.                (array->rgba[j])[2] = (array->rgba[j + left])[2];
  1486.                (array->rgba[j])[3] = (array->rgba[j + left])[3];
  1487.                 (array->spec[j])[0] = (array->spec[j + left])[0];
  1488.                (array->spec[j])[1] = (array->spec[j + left])[1];
  1489.                (array->spec[j])[2] = (array->spec[j + left])[2];
  1490.                (array->spec[j])[3] = (array->spec[j + left])[3];
  1491.                array->z[j] = array->z[j + left];
  1492.                array->fog[j] = array->fog[j + left];
  1493.                do { (array->texcoords[0][j])[0] = (array->texcoords[0][j + left])[0]; (array->texcoords[0][j])[1] = (array->texcoords[0][j + left])[1]; (array->texcoords[0][j])[2] = (array->texcoords[0][j + left])[2]; (array->texcoords[0][j])[3] = (array->texcoords[0][j + left])[3]; } while (0);
  1494.                array->lambda[0][j] = array->lambda[0][j + left];
  1495.                array->coverage[j] = array->coverage[j + left];
  1496.             }
  1497.          }
  1498.  
  1499.          span.x = left;
  1500.          span.y = iy;
  1501.          span.end = n;
  1502.          _mesa_write_texture_span(ctx, &span);
  1503.       }
  1504.    }
  1505. }
  1506.  
  1507.  
  1508. static void
  1509. multitex_aa_tri(GLcontext *ctx,
  1510.                const SWvertex *v0,
  1511.                const SWvertex *v1,
  1512.                const SWvertex *v2)
  1513. {
  1514.    const GLfloat *p0 = v0->win;
  1515.    const GLfloat *p1 = v1->win;
  1516.    const GLfloat *p2 = v2->win;
  1517.    const SWvertex *vMin, *vMid, *vMax;
  1518.    GLint iyMin, iyMax;
  1519.    GLfloat yMin, yMax;
  1520.    GLboolean ltor;
  1521.    GLfloat majDx, majDy;  /* major (i.e. long) edge dx and dy */
  1522.  
  1523.    struct sw_span span;
  1524.  
  1525.    GLfloat zPlane[4];
  1526.    GLfloat fogPlane[4];
  1527.    GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];
  1528.    GLfloat sPlane[8][4];  /* texture S */
  1529.    GLfloat tPlane[8][4];  /* texture T */
  1530.    GLfloat uPlane[8][4];  /* texture R */
  1531.    GLfloat vPlane[8][4];  /* texture Q */
  1532.    GLfloat texWidth[8], texHeight[8];
  1533.    GLfloat bf = ((SWcontext *)ctx->swrast_context)->_backface_sign;
  1534.  
  1535.  
  1536.    do { (span).primitive = (0x0009); (span).interpMask = (0); (span).arrayMask = (0x100); (span).start = 0; (span).end = (0); (span).facing = 0; (span).array = ((SWcontext *)ctx->swrast_context)->SpanArrays; } while (0);
  1537.  
  1538.    /* determine bottom to top order of vertices */
  1539.    {
  1540.       GLfloat y0 = v0->win[1];
  1541.       GLfloat y1 = v1->win[1];
  1542.       GLfloat y2 = v2->win[1];
  1543.       if (y0 <= y1) {
  1544.         if (y1 <= y2) {
  1545.            vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
  1546.         }
  1547.         else if (y2 <= y0) {
  1548.            vMin = v2;   vMid = v0;   vMax = v1;   /* y2<=y0<=y1 */
  1549.         }
  1550.         else {
  1551.            vMin = v0;   vMid = v2;   vMax = v1;  bf = -bf; /* y0<=y2<=y1 */
  1552.         }
  1553.       }
  1554.       else {
  1555.         if (y0 <= y2) {
  1556.            vMin = v1;   vMid = v0;   vMax = v2;  bf = -bf; /* y1<=y0<=y2 */
  1557.         }
  1558.         else if (y2 <= y1) {
  1559.            vMin = v2;   vMid = v1;   vMax = v0;  bf = -bf; /* y2<=y1<=y0 */
  1560.         }
  1561.         else {
  1562.            vMin = v1;   vMid = v2;   vMax = v0;   /* y1<=y2<=y0 */
  1563.         }
  1564.       }
  1565.    }
  1566.  
  1567.    majDx = vMax->win[0] - vMin->win[0];
  1568.    majDy = vMax->win[1] - vMin->win[1];
  1569.  
  1570.    {
  1571.       const GLfloat botDx = vMid->win[0] - vMin->win[0];
  1572.       const GLfloat botDy = vMid->win[1] - vMin->win[1];
  1573.       const GLfloat area = majDx * botDy - botDx * majDy;
  1574.       ltor = (GLboolean) (area < 0.0F);
  1575.       /* Do backface culling */
  1576.       if (area * bf < 0 || area == 0 || IS_INF_OR_NAN(area))
  1577.         return;
  1578.    }
  1579.  
  1580.    ctx->OcclusionResult = 0x1;
  1581.  
  1582.    /* Plane equation setup:
  1583.     * We evaluate plane equations at window (x,y) coordinates in order
  1584.     * to compute color, Z, fog, texcoords, etc.  This isn't terribly
  1585.     * efficient but it's easy and reliable.
  1586.     */
  1587.    compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
  1588.    span.arrayMask |= 0x008;
  1589.    compute_plane(p0, p1, p2, v0->fog, v1->fog, v2->fog, fogPlane);
  1590.    span.arrayMask |= 0x010;
  1591.    if (ctx->Light.ShadeModel == 0x1D01) {
  1592.       compute_plane(p0, p1, p2, v0->color[RCOMP], v1->color[RCOMP], v2->color[RCOMP], rPlane);
  1593.       compute_plane(p0, p1, p2, v0->color[GCOMP], v1->color[GCOMP], v2->color[GCOMP], gPlane);
  1594.       compute_plane(p0, p1, p2, v0->color[BCOMP], v1->color[BCOMP], v2->color[BCOMP], bPlane);
  1595.       compute_plane(p0, p1, p2, v0->color[ACOMP], v1->color[ACOMP], v2->color[ACOMP], aPlane);
  1596.    }
  1597.    else {
  1598.       constant_plane(v2->color[RCOMP], rPlane);
  1599.       constant_plane(v2->color[GCOMP], gPlane);
  1600.       constant_plane(v2->color[BCOMP], bPlane);
  1601.       constant_plane(v2->color[ACOMP], aPlane);
  1602.    }
  1603.    span.arrayMask |= 0x001;
  1604.    {
  1605.       GLuint u;
  1606.       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  1607.          if (ctx->Texture.Unit[u]._ReallyEnabled) {
  1608.             const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;
  1609.             const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];
  1610.             const GLfloat invW0 = v0->win[3];
  1611.             const GLfloat invW1 = v1->win[3];
  1612.             const GLfloat invW2 = v2->win[3];
  1613.             const GLfloat s0 = v0->texcoord[u][0] * invW0;
  1614.             const GLfloat s1 = v1->texcoord[u][0] * invW1;
  1615.             const GLfloat s2 = v2->texcoord[u][0] * invW2;
  1616.             const GLfloat t0 = v0->texcoord[u][1] * invW0;
  1617.             const GLfloat t1 = v1->texcoord[u][1] * invW1;
  1618.             const GLfloat t2 = v2->texcoord[u][1] * invW2;
  1619.             const GLfloat r0 = v0->texcoord[u][2] * invW0;
  1620.             const GLfloat r1 = v1->texcoord[u][2] * invW1;
  1621.             const GLfloat r2 = v2->texcoord[u][2] * invW2;
  1622.             const GLfloat q0 = v0->texcoord[u][3] * invW0;
  1623.             const GLfloat q1 = v1->texcoord[u][3] * invW1;
  1624.             const GLfloat q2 = v2->texcoord[u][3] * invW2;
  1625.             compute_plane(p0, p1, p2, s0, s1, s2, sPlane[u]);
  1626.             compute_plane(p0, p1, p2, t0, t1, t2, tPlane[u]);
  1627.             compute_plane(p0, p1, p2, r0, r1, r2, uPlane[u]);
  1628.             compute_plane(p0, p1, p2, q0, q1, q2, vPlane[u]);
  1629.             texWidth[u]  = (GLfloat) texImage->Width;
  1630.             texHeight[u] = (GLfloat) texImage->Height;
  1631.          }
  1632.       }
  1633.    }
  1634.    span.arrayMask |= (0x020 | 0x080);
  1635.  
  1636.    /* Begin bottom-to-top scan over the triangle.
  1637.     * The long edge will either be on the left or right side of the
  1638.     * triangle.  We always scan from the long edge toward the shorter
  1639.     * edges, stopping when we find that coverage = 0.  If the long edge
  1640.     * is on the left we scan left-to-right.  Else, we scan right-to-left.
  1641.     */
  1642.    yMin = vMin->win[1];
  1643.    yMax = vMax->win[1];
  1644.    iyMin = (GLint) yMin;
  1645.    iyMax = (GLint) yMax + 1;
  1646.  
  1647.    if (ltor) {
  1648.       /* scan left to right */
  1649.       const GLfloat *pMin = vMin->win;
  1650.       const GLfloat *pMid = vMid->win;
  1651.       const GLfloat *pMax = vMax->win;
  1652.       const GLfloat dxdy = majDx / majDy;
  1653.       const GLfloat xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
  1654.       GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
  1655.       GLint iy;
  1656.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  1657.          GLint ix, startX = (GLint) (x - xAdj);
  1658.          GLuint count;
  1659.          GLfloat coverage = 0.0F;
  1660.  
  1661.          /* skip over fragments with zero coverage */
  1662.          while (startX < 2048) {
  1663.             coverage = compute_coveragef(pMin, pMid, pMax, startX, iy);
  1664.             if (coverage > 0.0F)
  1665.                break;
  1666.             startX++;
  1667.          }
  1668.  
  1669.          /* enter interior of triangle */
  1670.          ix = startX;
  1671.          count = 0;
  1672.          while (coverage > 0.0F) {
  1673.             /* (cx,cy) = center of fragment */
  1674.             const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
  1675.             struct span_arrays *array = span.array;
  1676.             array->coverage[count] = coverage;
  1677.             array->z[count] = (GLdepth) solve_plane(cx, cy, zPlane);
  1678.            array->fog[count] = solve_plane(cx, cy, fogPlane);
  1679.             array->rgba[count][RCOMP] = solve_plane_chan(cx, cy, rPlane);
  1680.             array->rgba[count][GCOMP] = solve_plane_chan(cx, cy, gPlane);
  1681.             array->rgba[count][BCOMP] = solve_plane_chan(cx, cy, bPlane);
  1682.             array->rgba[count][ACOMP] = solve_plane_chan(cx, cy, aPlane);
  1683.             {
  1684.                GLuint unit;
  1685.                for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
  1686.                   if (ctx->Texture.Unit[unit]._ReallyEnabled) {
  1687.                      GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]);
  1688.                      array->texcoords[unit][count][0] = solve_plane(cx, cy, sPlane[unit]) * invQ;
  1689.                      array->texcoords[unit][count][1] = solve_plane(cx, cy, tPlane[unit]) * invQ;
  1690.                      array->texcoords[unit][count][2] = solve_plane(cx, cy, uPlane[unit]) * invQ;
  1691.                      array->lambda[unit][count] = compute_lambda(sPlane[unit],
  1692.                                       tPlane[unit], vPlane[unit], cx, cy, invQ,
  1693.                                       texWidth[unit], texHeight[unit]);
  1694.                   }
  1695.                }
  1696.             }
  1697.             ix++;
  1698.             count++;
  1699.             coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
  1700.          }
  1701.  
  1702.          if (ix <= startX)
  1703.             continue;
  1704.  
  1705.          span.x = startX;
  1706.          span.y = iy;
  1707.          span.end = (GLuint) ix - (GLuint) startX;
  1708.          ;
  1709.          _mesa_write_texture_span(ctx, &span);
  1710.       }
  1711.    }
  1712.    else {
  1713.       /* scan right to left */
  1714.       const GLfloat *pMin = vMin->win;
  1715.       const GLfloat *pMid = vMid->win;
  1716.       const GLfloat *pMax = vMax->win;
  1717.       const GLfloat dxdy = majDx / majDy;
  1718.       const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
  1719.       GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
  1720.       GLint iy;
  1721.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  1722.          GLint ix, left, startX = (GLint) (x + xAdj);
  1723.          GLuint count, n;
  1724.          GLfloat coverage = 0.0F;
  1725.  
  1726.          /* make sure we're not past the window edge */
  1727.          if (startX >= ctx->DrawBuffer->_Xmax) {
  1728.             startX = ctx->DrawBuffer->_Xmax - 1;
  1729.          }
  1730.  
  1731.          /* skip fragments with zero coverage */
  1732.          while (startX >= 0) {
  1733.             coverage = compute_coveragef(pMin, pMax, pMid, startX, iy);
  1734.             if (coverage > 0.0F)
  1735.                break;
  1736.             startX--;
  1737.          }
  1738.  
  1739.          /* enter interior of triangle */
  1740.          ix = startX;
  1741.          count = 0;
  1742.          while (coverage > 0.0F) {
  1743.             /* (cx,cy) = center of fragment */
  1744.             const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
  1745.             struct span_arrays *array = span.array;
  1746.             array->coverage[ix] = coverage;
  1747.             array->z[ix] = (GLdepth) solve_plane(cx, cy, zPlane);
  1748.             array->fog[ix] = solve_plane(cx, cy, fogPlane);
  1749.             array->rgba[ix][RCOMP] = solve_plane_chan(cx, cy, rPlane);
  1750.             array->rgba[ix][GCOMP] = solve_plane_chan(cx, cy, gPlane);
  1751.             array->rgba[ix][BCOMP] = solve_plane_chan(cx, cy, bPlane);
  1752.             array->rgba[ix][ACOMP] = solve_plane_chan(cx, cy, aPlane);
  1753.             {
  1754.                GLuint unit;
  1755.                for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
  1756.                   if (ctx->Texture.Unit[unit]._ReallyEnabled) {
  1757.                      GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]);
  1758.                      array->texcoords[unit][ix][0] = solve_plane(cx, cy, sPlane[unit]) * invQ;
  1759.                      array->texcoords[unit][ix][1] = solve_plane(cx, cy, tPlane[unit]) * invQ;
  1760.                      array->texcoords[unit][ix][2] = solve_plane(cx, cy, uPlane[unit]) * invQ;
  1761.                      array->lambda[unit][ix] = compute_lambda(sPlane[unit],
  1762.                                                             tPlane[unit],
  1763.                                                             vPlane[unit],
  1764.                                                             cx, cy, invQ,
  1765.                                                             texWidth[unit],
  1766.                                                             texHeight[unit]);
  1767.                   }
  1768.                }
  1769.             }
  1770.             ix--;
  1771.             count++;
  1772.             coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
  1773.          }
  1774.  
  1775.          if (startX <= ix)
  1776.             continue;
  1777.  
  1778.          n = (GLuint) startX - (GLuint) ix;
  1779.  
  1780.          left = ix + 1;
  1781.  
  1782.          /* shift all values to the left */
  1783.          /* XXX this is temporary */
  1784.          {
  1785.             struct span_arrays *array = span.array;
  1786.             GLint j;
  1787.             for (j = 0; j < (GLint) n; j++) {
  1788.                (array->rgba[j])[0] = (array->rgba[j + left])[0];
  1789.                (array->rgba[j])[1] = (array->rgba[j + left])[1];
  1790.                (array->rgba[j])[2] = (array->rgba[j + left])[2];
  1791.                (array->rgba[j])[3] = (array->rgba[j + left])[3];
  1792.                array->z[j] = array->z[j + left];
  1793.                array->fog[j] = array->fog[j + left];
  1794.                array->lambda[0][j] = array->lambda[0][j + left];
  1795.                array->coverage[j] = array->coverage[j + left];
  1796.             }
  1797.          }
  1798.          /* shift texcoords */
  1799.          {
  1800.             struct span_arrays *array = span.array;
  1801.             GLuint unit;
  1802.             for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
  1803.                if (ctx->Texture.Unit[unit]._ReallyEnabled) {
  1804.                   GLint j;
  1805.                   for (j = 0; j < (GLint) n; j++) {
  1806.                     array->texcoords[unit][j][0] = array->texcoords[unit][j + left][0];
  1807.                      array->texcoords[unit][j][1] = array->texcoords[unit][j + left][1];
  1808.                      array->texcoords[unit][j][2] = array->texcoords[unit][j + left][2];
  1809.                      array->lambda[unit][j] = array->lambda[unit][j + left];
  1810.                   }
  1811.                }
  1812.             }
  1813.          }
  1814.  
  1815.          span.x = left;
  1816.          span.y = iy;
  1817.          span.end = n;
  1818.          _mesa_write_texture_span(ctx, &span);
  1819.       }
  1820.    }
  1821. }
  1822.  
  1823.  
  1824.  
  1825. static void
  1826. spec_multitex_aa_tri(GLcontext *ctx,
  1827.                     const SWvertex *v0,
  1828.                     const SWvertex *v1,
  1829.                     const SWvertex *v2)
  1830. {
  1831.    const GLfloat *p0 = v0->win;
  1832.    const GLfloat *p1 = v1->win;
  1833.    const GLfloat *p2 = v2->win;
  1834.    const SWvertex *vMin, *vMid, *vMax;
  1835.    GLint iyMin, iyMax;
  1836.    GLfloat yMin, yMax;
  1837.    GLboolean ltor;
  1838.    GLfloat majDx, majDy;  /* major (i.e. long) edge dx and dy */
  1839.  
  1840.    struct sw_span span;
  1841.  
  1842.    GLfloat zPlane[4];
  1843.    GLfloat fogPlane[4];
  1844.    GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];
  1845.    GLfloat srPlane[4], sgPlane[4], sbPlane[4];
  1846.    GLfloat sPlane[8][4];  /* texture S */
  1847.    GLfloat tPlane[8][4];  /* texture T */
  1848.    GLfloat uPlane[8][4];  /* texture R */
  1849.    GLfloat vPlane[8][4];  /* texture Q */
  1850.    GLfloat texWidth[8], texHeight[8];
  1851.    GLfloat bf = ((SWcontext *)ctx->swrast_context)->_backface_sign;
  1852.  
  1853.  
  1854.    do { (span).primitive = (0x0009); (span).interpMask = (0); (span).arrayMask = (0x100); (span).start = 0; (span).end = (0); (span).facing = 0; (span).array = ((SWcontext *)ctx->swrast_context)->SpanArrays; } while (0);
  1855.  
  1856.    /* determine bottom to top order of vertices */
  1857.    {
  1858.       GLfloat y0 = v0->win[1];
  1859.       GLfloat y1 = v1->win[1];
  1860.       GLfloat y2 = v2->win[1];
  1861.       if (y0 <= y1) {
  1862.         if (y1 <= y2) {
  1863.            vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
  1864.         }
  1865.         else if (y2 <= y0) {
  1866.            vMin = v2;   vMid = v0;   vMax = v1;   /* y2<=y0<=y1 */
  1867.         }
  1868.         else {
  1869.            vMin = v0;   vMid = v2;   vMax = v1;  bf = -bf; /* y0<=y2<=y1 */
  1870.         }
  1871.       }
  1872.       else {
  1873.         if (y0 <= y2) {
  1874.            vMin = v1;   vMid = v0;   vMax = v2;  bf = -bf; /* y1<=y0<=y2 */
  1875.         }
  1876.         else if (y2 <= y1) {
  1877.            vMin = v2;   vMid = v1;   vMax = v0;  bf = -bf; /* y2<=y1<=y0 */
  1878.         }
  1879.         else {
  1880.            vMin = v1;   vMid = v2;   vMax = v0;   /* y1<=y2<=y0 */
  1881.         }
  1882.       }
  1883.    }
  1884.  
  1885.    majDx = vMax->win[0] - vMin->win[0];
  1886.    majDy = vMax->win[1] - vMin->win[1];
  1887.  
  1888.    {
  1889.       const GLfloat botDx = vMid->win[0] - vMin->win[0];
  1890.       const GLfloat botDy = vMid->win[1] - vMin->win[1];
  1891.       const GLfloat area = majDx * botDy - botDx * majDy;
  1892.       ltor = (GLboolean) (area < 0.0F);
  1893.       /* Do backface culling */
  1894.       if (area * bf < 0 || area == 0 || IS_INF_OR_NAN(area))
  1895.         return;
  1896.    }
  1897.  
  1898.    ctx->OcclusionResult = 0x1;
  1899.  
  1900.    /* Plane equation setup:
  1901.     * We evaluate plane equations at window (x,y) coordinates in order
  1902.     * to compute color, Z, fog, texcoords, etc.  This isn't terribly
  1903.     * efficient but it's easy and reliable.
  1904.     */
  1905.    compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
  1906.    span.arrayMask |= 0x008;
  1907.    compute_plane(p0, p1, p2, v0->fog, v1->fog, v2->fog, fogPlane);
  1908.    span.arrayMask |= 0x010;
  1909.    if (ctx->Light.ShadeModel == 0x1D01) {
  1910.       compute_plane(p0, p1, p2, v0->color[RCOMP], v1->color[RCOMP], v2->color[RCOMP], rPlane);
  1911.       compute_plane(p0, p1, p2, v0->color[GCOMP], v1->color[GCOMP], v2->color[GCOMP], gPlane);
  1912.       compute_plane(p0, p1, p2, v0->color[BCOMP], v1->color[BCOMP], v2->color[BCOMP], bPlane);
  1913.       compute_plane(p0, p1, p2, v0->color[ACOMP], v1->color[ACOMP], v2->color[ACOMP], aPlane);
  1914.    }
  1915.    else {
  1916.       constant_plane(v2->color[RCOMP], rPlane);
  1917.       constant_plane(v2->color[GCOMP], gPlane);
  1918.       constant_plane(v2->color[BCOMP], bPlane);
  1919.       constant_plane(v2->color[ACOMP], aPlane);
  1920.    }
  1921.    span.arrayMask |= 0x001;
  1922.    if (ctx->Light.ShadeModel == 0x1D01) {
  1923.       compute_plane(p0, p1, p2, v0->specular[RCOMP], v1->specular[RCOMP], v2->specular[RCOMP],srPlane);
  1924.       compute_plane(p0, p1, p2, v0->specular[GCOMP], v1->specular[GCOMP], v2->specular[GCOMP],sgPlane);
  1925.       compute_plane(p0, p1, p2, v0->specular[BCOMP], v1->specular[BCOMP], v2->specular[BCOMP],sbPlane);
  1926.    }
  1927.    else {
  1928.       constant_plane(v2->specular[RCOMP], srPlane);
  1929.       constant_plane(v2->specular[GCOMP], sgPlane);
  1930.       constant_plane(v2->specular[BCOMP], sbPlane);
  1931.    }
  1932.    span.arrayMask |= 0x002;
  1933.    {
  1934.       GLuint u;
  1935.       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  1936.          if (ctx->Texture.Unit[u]._ReallyEnabled) {
  1937.             const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;
  1938.             const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];
  1939.             const GLfloat invW0 = v0->win[3];
  1940.             const GLfloat invW1 = v1->win[3];
  1941.             const GLfloat invW2 = v2->win[3];
  1942.             const GLfloat s0 = v0->texcoord[u][0] * invW0;
  1943.             const GLfloat s1 = v1->texcoord[u][0] * invW1;
  1944.             const GLfloat s2 = v2->texcoord[u][0] * invW2;
  1945.             const GLfloat t0 = v0->texcoord[u][1] * invW0;
  1946.             const GLfloat t1 = v1->texcoord[u][1] * invW1;
  1947.             const GLfloat t2 = v2->texcoord[u][1] * invW2;
  1948.             const GLfloat r0 = v0->texcoord[u][2] * invW0;
  1949.             const GLfloat r1 = v1->texcoord[u][2] * invW1;
  1950.             const GLfloat r2 = v2->texcoord[u][2] * invW2;
  1951.             const GLfloat q0 = v0->texcoord[u][3] * invW0;
  1952.             const GLfloat q1 = v1->texcoord[u][3] * invW1;
  1953.             const GLfloat q2 = v2->texcoord[u][3] * invW2;
  1954.             compute_plane(p0, p1, p2, s0, s1, s2, sPlane[u]);
  1955.             compute_plane(p0, p1, p2, t0, t1, t2, tPlane[u]);
  1956.             compute_plane(p0, p1, p2, r0, r1, r2, uPlane[u]);
  1957.             compute_plane(p0, p1, p2, q0, q1, q2, vPlane[u]);
  1958.             texWidth[u]  = (GLfloat) texImage->Width;
  1959.             texHeight[u] = (GLfloat) texImage->Height;
  1960.          }
  1961.       }
  1962.    }
  1963.    span.arrayMask |= (0x020 | 0x080);
  1964.  
  1965.    /* Begin bottom-to-top scan over the triangle.
  1966.     * The long edge will either be on the left or right side of the
  1967.     * triangle.  We always scan from the long edge toward the shorter
  1968.     * edges, stopping when we find that coverage = 0.  If the long edge
  1969.     * is on the left we scan left-to-right.  Else, we scan right-to-left.
  1970.     */
  1971.    yMin = vMin->win[1];
  1972.    yMax = vMax->win[1];
  1973.    iyMin = (GLint) yMin;
  1974.    iyMax = (GLint) yMax + 1;
  1975.  
  1976.    if (ltor) {
  1977.       /* scan left to right */
  1978.       const GLfloat *pMin = vMin->win;
  1979.       const GLfloat *pMid = vMid->win;
  1980.       const GLfloat *pMax = vMax->win;
  1981.       const GLfloat dxdy = majDx / majDy;
  1982.       const GLfloat xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
  1983.       GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
  1984.       GLint iy;
  1985.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  1986.          GLint ix, startX = (GLint) (x - xAdj);
  1987.          GLuint count;
  1988.          GLfloat coverage = 0.0F;
  1989.  
  1990.          /* skip over fragments with zero coverage */
  1991.          while (startX < 2048) {
  1992.             coverage = compute_coveragef(pMin, pMid, pMax, startX, iy);
  1993.             if (coverage > 0.0F)
  1994.                break;
  1995.             startX++;
  1996.          }
  1997.  
  1998.          /* enter interior of triangle */
  1999.          ix = startX;
  2000.          count = 0;
  2001.          while (coverage > 0.0F) {
  2002.             /* (cx,cy) = center of fragment */
  2003.             const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
  2004.             struct span_arrays *array = span.array;
  2005.             array->coverage[count] = coverage;
  2006.             array->z[count] = (GLdepth) solve_plane(cx, cy, zPlane);
  2007.            array->fog[count] = solve_plane(cx, cy, fogPlane);
  2008.             array->rgba[count][RCOMP] = solve_plane_chan(cx, cy, rPlane);
  2009.             array->rgba[count][GCOMP] = solve_plane_chan(cx, cy, gPlane);
  2010.             array->rgba[count][BCOMP] = solve_plane_chan(cx, cy, bPlane);
  2011.             array->rgba[count][ACOMP] = solve_plane_chan(cx, cy, aPlane);
  2012.             array->spec[count][RCOMP] = solve_plane_chan(cx, cy, srPlane);
  2013.             array->spec[count][GCOMP] = solve_plane_chan(cx, cy, sgPlane);
  2014.             array->spec[count][BCOMP] = solve_plane_chan(cx, cy, sbPlane);
  2015.             {
  2016.                GLuint unit;
  2017.                for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
  2018.                   if (ctx->Texture.Unit[unit]._ReallyEnabled) {
  2019.                      GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]);
  2020.                      array->texcoords[unit][count][0] = solve_plane(cx, cy, sPlane[unit]) * invQ;
  2021.                      array->texcoords[unit][count][1] = solve_plane(cx, cy, tPlane[unit]) * invQ;
  2022.                      array->texcoords[unit][count][2] = solve_plane(cx, cy, uPlane[unit]) * invQ;
  2023.                      array->lambda[unit][count] = compute_lambda(sPlane[unit],
  2024.                                       tPlane[unit], vPlane[unit], cx, cy, invQ,
  2025.                                       texWidth[unit], texHeight[unit]);
  2026.                   }
  2027.                }
  2028.             }
  2029.             ix++;
  2030.             count++;
  2031.             coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
  2032.          }
  2033.  
  2034.          if (ix <= startX)
  2035.             continue;
  2036.  
  2037.          span.x = startX;
  2038.          span.y = iy;
  2039.          span.end = (GLuint) ix - (GLuint) startX;
  2040.          ;
  2041.          _mesa_write_texture_span(ctx, &span);
  2042.       }
  2043.    }
  2044.    else {
  2045.       /* scan right to left */
  2046.       const GLfloat *pMin = vMin->win;
  2047.       const GLfloat *pMid = vMid->win;
  2048.       const GLfloat *pMax = vMax->win;
  2049.       const GLfloat dxdy = majDx / majDy;
  2050.       const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
  2051.       GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
  2052.       GLint iy;
  2053.       for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
  2054.          GLint ix, left, startX = (GLint) (x + xAdj);
  2055.          GLuint count, n;
  2056.          GLfloat coverage = 0.0F;
  2057.  
  2058.          /* make sure we're not past the window edge */
  2059.          if (startX >= ctx->DrawBuffer->_Xmax) {
  2060.             startX = ctx->DrawBuffer->_Xmax - 1;
  2061.          }
  2062.  
  2063.          /* skip fragments with zero coverage */
  2064.          while (startX >= 0) {
  2065.             coverage = compute_coveragef(pMin, pMax, pMid, startX, iy);
  2066.             if (coverage > 0.0F)
  2067.                break;
  2068.             startX--;
  2069.          }
  2070.  
  2071.          /* enter interior of triangle */
  2072.          ix = startX;
  2073.          count = 0;
  2074.          while (coverage > 0.0F) {
  2075.             /* (cx,cy) = center of fragment */
  2076.             const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
  2077.             struct span_arrays *array = span.array;
  2078.             array->coverage[ix] = coverage;
  2079.             array->z[ix] = (GLdepth) solve_plane(cx, cy, zPlane);
  2080.             array->fog[ix] = solve_plane(cx, cy, fogPlane);
  2081.             array->rgba[ix][RCOMP] = solve_plane_chan(cx, cy, rPlane);
  2082.             array->rgba[ix][GCOMP] = solve_plane_chan(cx, cy, gPlane);
  2083.             array->rgba[ix][BCOMP] = solve_plane_chan(cx, cy, bPlane);
  2084.             array->rgba[ix][ACOMP] = solve_plane_chan(cx, cy, aPlane);
  2085.             array->spec[ix][RCOMP] = solve_plane_chan(cx, cy, srPlane);
  2086.             array->spec[ix][GCOMP] = solve_plane_chan(cx, cy, sgPlane);
  2087.             array->spec[ix][BCOMP] = solve_plane_chan(cx, cy, sbPlane);
  2088.             {
  2089.                GLuint unit;
  2090.                for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
  2091.                   if (ctx->Texture.Unit[unit]._ReallyEnabled) {
  2092.                      GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]);
  2093.                      array->texcoords[unit][ix][0] = solve_plane(cx, cy, sPlane[unit]) * invQ;
  2094.                      array->texcoords[unit][ix][1] = solve_plane(cx, cy, tPlane[unit]) * invQ;
  2095.                      array->texcoords[unit][ix][2] = solve_plane(cx, cy, uPlane[unit]) * invQ;
  2096.                      array->lambda[unit][ix] = compute_lambda(sPlane[unit],
  2097.                                                             tPlane[unit],
  2098.                                                             vPlane[unit],
  2099.                                                             cx, cy, invQ,
  2100.                                                             texWidth[unit],
  2101.                                                             texHeight[unit]);
  2102.                   }
  2103.                }
  2104.             }
  2105.             ix--;
  2106.             count++;
  2107.             coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
  2108.          }
  2109.  
  2110.          if (startX <= ix)
  2111.             continue;
  2112.  
  2113.          n = (GLuint) startX - (GLuint) ix;
  2114.  
  2115.          left = ix + 1;
  2116.  
  2117.          /* shift all values to the left */
  2118.          /* XXX this is temporary */
  2119.          {
  2120.             struct span_arrays *array = span.array;
  2121.             GLint j;
  2122.             for (j = 0; j < (GLint) n; j++) {
  2123.                (array->rgba[j])[0] = (array->rgba[j + left])[0];
  2124.                (array->rgba[j])[1] = (array->rgba[j + left])[1];
  2125.               (array->rgba[j])[2] = (array->rgba[j + left])[2];
  2126.               (array->rgba[j])[3] = (array->rgba[j + left])[3];
  2127.                (array->spec[j])[0] = (array->spec[j + left])[0];
  2128.               (array->spec[j])[1] = (array->spec[j + left])[1];
  2129.               (array->spec[j])[2] = (array->spec[j + left])[2];
  2130.               (array->spec[j])[3] = (array->spec[j + left])[3];
  2131.                array->z[j] = array->z[j + left];
  2132.                array->fog[j] = array->fog[j + left];
  2133.                array->lambda[0][j] = array->lambda[0][j + left];
  2134.                array->coverage[j] = array->coverage[j + left];
  2135.             }
  2136.          }
  2137.          /* shift texcoords */
  2138.          {
  2139.             struct span_arrays *array = span.array;
  2140.             GLuint unit;
  2141.             for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
  2142.                if (ctx->Texture.Unit[unit]._ReallyEnabled) {
  2143.                   GLint j;
  2144.                   for (j = 0; j < (GLint) n; j++) {
  2145.                     array->texcoords[unit][j][0] = array->texcoords[unit][j + left][0];
  2146.                      array->texcoords[unit][j][1] = array->texcoords[unit][j + left][1];
  2147.                      array->texcoords[unit][j][2] = array->texcoords[unit][j + left][2];
  2148.                      array->lambda[unit][j] = array->lambda[unit][j + left];
  2149.                   }
  2150.                }
  2151.             }
  2152.          }
  2153.  
  2154.          span.x = left;
  2155.          span.y = iy;
  2156.          span.end = n;
  2157.          _mesa_write_texture_span(ctx, &span);
  2158.       }
  2159.    }
  2160. }
  2161.  
  2162.  
  2163. /*
  2164.  * Examine GL state and set swrast->Triangle to an
  2165.  * appropriate antialiased triangle rasterizer function.
  2166.  */
  2167. void
  2168. _mesa_set_aa_triangle_function(GLcontext *ctx)
  2169. {
  2170.  
  2171.    if (ctx->Texture._EnabledUnits != 0) {
  2172.       if (ctx->_TriangleCaps & 0x2) {
  2173.          if (ctx->Texture._EnabledUnits > 1) {
  2174.             ((SWcontext *)ctx->swrast_context)->Triangle = spec_multitex_aa_tri;
  2175.          }
  2176.          else {
  2177.             ((SWcontext *)ctx->swrast_context)->Triangle = spec_tex_aa_tri;
  2178.          }
  2179.       }
  2180.       else {
  2181.          if (ctx->Texture._EnabledUnits > 1) {
  2182.             ((SWcontext *)ctx->swrast_context)->Triangle = multitex_aa_tri;
  2183.          }
  2184.          else {
  2185.             ((SWcontext *)ctx->swrast_context)->Triangle = tex_aa_tri;
  2186.          }
  2187.       }
  2188.    }
  2189.    else if (ctx->Visual.rgbMode) {
  2190.       ((SWcontext *)ctx->swrast_context)->Triangle = rgba_aa_tri;
  2191.    }
  2192.    else {
  2193.       ((SWcontext *)ctx->swrast_context)->Triangle = index_aa_tri;
  2194.    }
  2195.  
  2196.    ;
  2197. }
  2198.