s_tritemp.h revision 0bdf216dd06d5136b8529297297aa962bab548c2
1/*
2 * Mesa 3-D graphics library
3 * Version:  6.5.3
4 *
5 * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25/*
26 * Triangle Rasterizer Template
27 *
28 * This file is #include'd to generate custom triangle rasterizers.
29 *
30 * The following macros may be defined to indicate what auxillary information
31 * must be interpolated across the triangle:
32 *    INTERP_Z        - if defined, interpolate vertex Z values
33 *    INTERP_W        - if defined, interpolate vertex W values
34 *    INTERP_FOG      - if defined, interpolate fog values
35 *    INTERP_RGB      - if defined, interpolate RGB values
36 *    INTERP_ALPHA    - if defined, interpolate Alpha values (req's INTERP_RGB)
37 *    INTERP_SPEC     - if defined, interpolate specular RGB values
38 *    INTERP_INDEX    - if defined, interpolate color index values
39 *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
40 *                         (fast, simple 2-D texture mapping)
41 *    INTERP_TEX      - if defined, interpolate texcoords and varying vars
42 *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
43 *
44 * When one can directly address pixels in the color buffer the following
45 * macros can be defined and used to compute pixel addresses during
46 * rasterization (see pRow):
47 *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
48 *    BYTES_PER_ROW       - number of bytes per row in the color buffer
49 *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
50 *                          Y==0 at bottom of screen and increases upward.
51 *
52 * Similarly, for direct depth buffer access, this type is used for depth
53 * buffer addressing:
54 *    DEPTH_TYPE          - either GLushort or GLuint
55 *
56 * Optionally, one may provide one-time setup code per triangle:
57 *    SETUP_CODE    - code which is to be executed once per triangle
58 *    CLEANUP_CODE    - code to execute at end of triangle
59 *
60 * The following macro MUST be defined:
61 *    RENDER_SPAN(span) - code to write a span of pixels.
62 *
63 * This code was designed for the origin to be in the lower-left corner.
64 *
65 * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
66 *
67 *
68 * Some notes on rasterization accuracy:
69 *
70 * This code uses fixed point arithmetic (the GLfixed type) to iterate
71 * over the triangle edges and interpolate ancillary data (such as Z,
72 * color, secondary color, etc).  The number of fractional bits in
73 * GLfixed and the value of SUB_PIXEL_BITS has a direct bearing on the
74 * accuracy of rasterization.
75 *
76 * If SUB_PIXEL_BITS=4 then we'll snap the vertices to the nearest
77 * 1/16 of a pixel.  If we're walking up a long, nearly vertical edge
78 * (dx=1/16, dy=1024) we'll need 4 + 10 = 14 fractional bits in
79 * GLfixed to walk the edge without error.  If the maximum viewport
80 * height is 4K pixels, then we'll need 4 + 12 = 16 fractional bits.
81 *
82 * Historically, Mesa has used 11 fractional bits in GLfixed, snaps
83 * vertices to 1/16 pixel and allowed a maximum viewport height of 2K
84 * pixels.  11 fractional bits is actually insufficient for accurately
85 * rasterizing some triangles.  More recently, the maximum viewport
86 * height was increased to 4K pixels.  Thus, Mesa should be using 16
87 * fractional bits in GLfixed.  Unfortunately, there may be some issues
88 * with setting FIXED_FRAC_BITS=16, such as multiplication overflow.
89 * This will have to be examined in some detail...
90 *
91 * For now, if you find rasterization errors, particularly with tall,
92 * sliver triangles, try increasing FIXED_FRAC_BITS and/or decreasing
93 * SUB_PIXEL_BITS.
94 */
95
96/*
97 * ColorTemp is used for intermediate color values.
98 */
99#if CHAN_TYPE == GL_FLOAT
100#define ColorTemp GLfloat
101#else
102#define ColorTemp GLint  /* same as GLfixed */
103#endif
104
105
106/*
107 * Walk triangle edges with GLfixed or GLdouble
108 */
109#if TRIANGLE_WALK_DOUBLE
110#define GLinterp        GLdouble
111#define InterpToInt(X)  ((GLint) (X))
112#define INTERP_ONE      1.0
113#else
114#define GLinterp        GLfixed
115#define InterpToInt(X)  FixedToInt(X)
116#define INTERP_ONE      FIXED_ONE
117#endif
118
119
120/*
121 * Some code we unfortunately need to prevent negative interpolated colors.
122 */
123#ifndef CLAMP_INTERPOLANT
124#define CLAMP_INTERPOLANT(CHANNEL, CHANNELSTEP, LEN)		\
125do {								\
126   GLfixed endVal = span.CHANNEL + (LEN) * span.CHANNELSTEP;	\
127   if (endVal < 0) {						\
128      span.CHANNEL -= endVal;					\
129   }								\
130   if (span.CHANNEL < 0) {					\
131      span.CHANNEL = 0;						\
132   }								\
133} while (0)
134#endif
135
136
137static void NAME(GLcontext *ctx, const SWvertex *v0,
138                                 const SWvertex *v1,
139                                 const SWvertex *v2 )
140{
141   typedef struct {
142      const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
143#if TRIANGLE_WALK_DOUBLE
144      GLdouble dx;	/* X(v1) - X(v0) */
145      GLdouble dy;	/* Y(v1) - Y(v0) */
146      GLdouble dxdy;	/* dx/dy */
147      GLdouble adjy;	/* adjust from v[0]->fy to fsy, scaled */
148      GLdouble fsx;	/* first sample point x coord */
149      GLdouble fsy;
150      GLdouble fx0;	/*X of lower endpoint */
151#else
152      GLfloat dx;	/* X(v1) - X(v0) */
153      GLfloat dy;	/* Y(v1) - Y(v0) */
154      GLfloat dxdy;	/* dx/dy */
155      GLfixed fdxdy;	/* dx/dy in fixed-point */
156      GLfloat adjy;	/* adjust from v[0]->fy to fsy, scaled */
157      GLfixed fsx;	/* first sample point x coord */
158      GLfixed fsy;
159      GLfixed fx0;	/* fixed pt X of lower endpoint */
160#endif
161      GLint lines;	/* number of lines to be sampled on this edge */
162   } EdgeT;
163
164   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
165#ifdef INTERP_Z
166   const GLint depthBits = ctx->DrawBuffer->Visual.depthBits;
167   const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0;
168   const GLfloat maxDepth = ctx->DrawBuffer->_DepthMaxF;
169#define FixedToDepth(F)  ((F) >> fixedToDepthShift)
170#endif
171   EdgeT eMaj, eTop, eBot;
172   GLfloat oneOverArea;
173   const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
174   GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign;
175#if !TRIANGLE_WALK_DOUBLE
176   const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */
177#endif
178   GLinterp vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
179
180   SWspan span;
181
182   (void) swrast;
183
184   INIT_SPAN(span, GL_POLYGON, 0, 0, 0);
185   span.y = 0; /* silence warnings */
186
187#ifdef INTERP_Z
188   (void) fixedToDepthShift;
189#endif
190
191   /*
192   printf("%s()\n", __FUNCTION__);
193   printf("  %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
194   printf("  %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
195   printf("  %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
196   */
197   /*
198   ASSERT(v0->win[2] >= 0.0);
199   ASSERT(v1->win[2] >= 0.0);
200   ASSERT(v2->win[2] >= 0.0);
201   */
202   /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
203    * And find the order of the 3 vertices along the Y axis.
204    */
205   {
206#if TRIANGLE_WALK_DOUBLE
207      const GLdouble fy0 = v0->win[1] - 0.5;
208      const GLdouble fy1 = v1->win[1] - 0.5;
209      const GLdouble fy2 = v2->win[1] - 0.5;
210#else
211      const GLfixed fy0 = FloatToFixed(v0->win[1] - 0.5F) & snapMask;
212      const GLfixed fy1 = FloatToFixed(v1->win[1] - 0.5F) & snapMask;
213      const GLfixed fy2 = FloatToFixed(v2->win[1] - 0.5F) & snapMask;
214#endif
215      if (fy0 <= fy1) {
216         if (fy1 <= fy2) {
217            /* y0 <= y1 <= y2 */
218            vMin = v0;   vMid = v1;   vMax = v2;
219            vMin_fy = fy0;  vMid_fy = fy1;  vMax_fy = fy2;
220         }
221         else if (fy2 <= fy0) {
222            /* y2 <= y0 <= y1 */
223            vMin = v2;   vMid = v0;   vMax = v1;
224            vMin_fy = fy2;  vMid_fy = fy0;  vMax_fy = fy1;
225         }
226         else {
227            /* y0 <= y2 <= y1 */
228            vMin = v0;   vMid = v2;   vMax = v1;
229            vMin_fy = fy0;  vMid_fy = fy2;  vMax_fy = fy1;
230            bf = -bf;
231         }
232      }
233      else {
234         if (fy0 <= fy2) {
235            /* y1 <= y0 <= y2 */
236            vMin = v1;   vMid = v0;   vMax = v2;
237            vMin_fy = fy1;  vMid_fy = fy0;  vMax_fy = fy2;
238            bf = -bf;
239         }
240         else if (fy2 <= fy1) {
241            /* y2 <= y1 <= y0 */
242            vMin = v2;   vMid = v1;   vMax = v0;
243            vMin_fy = fy2;  vMid_fy = fy1;  vMax_fy = fy0;
244            bf = -bf;
245         }
246         else {
247            /* y1 <= y2 <= y0 */
248            vMin = v1;   vMid = v2;   vMax = v0;
249            vMin_fy = fy1;  vMid_fy = fy2;  vMax_fy = fy0;
250         }
251      }
252
253      /* fixed point X coords */
254#if TRIANGLE_WALK_DOUBLE
255      vMin_fx = vMin->win[0] + 0.5;
256      vMid_fx = vMid->win[0] + 0.5;
257      vMax_fx = vMax->win[0] + 0.5;
258#else
259      vMin_fx = FloatToFixed(vMin->win[0] + 0.5F) & snapMask;
260      vMid_fx = FloatToFixed(vMid->win[0] + 0.5F) & snapMask;
261      vMax_fx = FloatToFixed(vMax->win[0] + 0.5F) & snapMask;
262#endif
263   }
264
265   /* vertex/edge relationship */
266   eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
267   eTop.v0 = vMid;   eTop.v1 = vMax;
268   eBot.v0 = vMin;   eBot.v1 = vMid;
269
270   /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
271#if TRIANGLE_WALK_DOUBLE
272   eMaj.dx = vMax_fx - vMin_fx;
273   eMaj.dy = vMax_fy - vMin_fy;
274   eTop.dx = vMax_fx - vMid_fx;
275   eTop.dy = vMax_fy - vMid_fy;
276   eBot.dx = vMid_fx - vMin_fx;
277   eBot.dy = vMid_fy - vMin_fy;
278#else
279   eMaj.dx = FixedToFloat(vMax_fx - vMin_fx);
280   eMaj.dy = FixedToFloat(vMax_fy - vMin_fy);
281   eTop.dx = FixedToFloat(vMax_fx - vMid_fx);
282   eTop.dy = FixedToFloat(vMax_fy - vMid_fy);
283   eBot.dx = FixedToFloat(vMid_fx - vMin_fx);
284   eBot.dy = FixedToFloat(vMid_fy - vMin_fy);
285#endif
286
287   /* compute area, oneOverArea and perform backface culling */
288   {
289#if TRIANGLE_WALK_DOUBLE
290      const GLdouble area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
291#else
292      const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
293#endif
294      /* Do backface culling */
295      if (area * bf < 0.0)
296         return;
297
298      if (IS_INF_OR_NAN(area) || area == 0.0F)
299         return;
300
301      oneOverArea = 1.0F / area;
302   }
303
304
305   span.facing = ctx->_Facing; /* for 2-sided stencil test */
306
307   /* Edge setup.  For a triangle strip these could be reused... */
308   {
309#if TRIANGLE_WALK_DOUBLE
310      eMaj.fsy = CEILF(vMin_fy);
311      eMaj.lines = (GLint) CEILF(vMax_fy - eMaj.fsy);
312#else
313      eMaj.fsy = FixedCeil(vMin_fy);
314      eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy));
315#endif
316      if (eMaj.lines > 0) {
317         eMaj.dxdy = eMaj.dx / eMaj.dy;
318#if TRIANGLE_WALK_DOUBLE
319         eMaj.adjy = (eMaj.fsy - vMin_fy) * FIXED_SCALE;  /* SCALED! */
320         eMaj.fx0 = vMin_fx;
321         eMaj.fsx = eMaj.fx0 + (eMaj.adjy * eMaj.dxdy) / (GLdouble) FIXED_SCALE;
322#else
323         eMaj.fdxdy = SignedFloatToFixed(eMaj.dxdy);
324         eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
325         eMaj.fx0 = vMin_fx;
326         eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * eMaj.dxdy);
327#endif
328      }
329      else {
330         return;  /*CULLED*/
331      }
332
333#if TRIANGLE_WALK_DOUBLE
334      eTop.fsy = CEILF(vMid_fy);
335      eTop.lines = (GLint) CEILF(vMax_fy - eTop.fsy);
336#else
337      eTop.fsy = FixedCeil(vMid_fy);
338      eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy));
339#endif
340      if (eTop.lines > 0) {
341         eTop.dxdy = eTop.dx / eTop.dy;
342#if TRIANGLE_WALK_DOUBLE
343         eTop.adjy = (eTop.fsy - vMid_fy) * FIXED_SCALE; /* SCALED! */
344         eTop.fx0 = vMid_fx;
345         eTop.fsx = eTop.fx0 + (eTop.adjy * eTop.dxdy) / (GLdouble) FIXED_SCALE;
346#else
347         eTop.fdxdy = SignedFloatToFixed(eTop.dxdy);
348         eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
349         eTop.fx0 = vMid_fx;
350         eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * eTop.dxdy);
351#endif
352      }
353
354#if TRIANGLE_WALK_DOUBLE
355      eBot.fsy = CEILF(vMin_fy);
356      eBot.lines = (GLint) CEILF(vMid_fy - eBot.fsy);
357#else
358      eBot.fsy = FixedCeil(vMin_fy);
359      eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy));
360#endif
361      if (eBot.lines > 0) {
362         eBot.dxdy = eBot.dx / eBot.dy;
363#if TRIANGLE_WALK_DOUBLE
364         eBot.adjy = (eBot.fsy - vMin_fy) * FIXED_SCALE;  /* SCALED! */
365         eBot.fx0 = vMin_fx;
366         eBot.fsx = eBot.fx0 + (eBot.adjy * eBot.dxdy) / (GLdouble) FIXED_SCALE;
367#else
368         eBot.fdxdy = SignedFloatToFixed(eBot.dxdy);
369         eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
370         eBot.fx0 = vMin_fx;
371         eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * eBot.dxdy);
372#endif
373      }
374   }
375
376   /*
377    * Conceptually, we view a triangle as two subtriangles
378    * separated by a perfectly horizontal line.  The edge that is
379    * intersected by this line is one with maximal absolute dy; we
380    * call it a ``major'' edge.  The other two edges are the
381    * ``top'' edge (for the upper subtriangle) and the ``bottom''
382    * edge (for the lower subtriangle).  If either of these two
383    * edges is horizontal or very close to horizontal, the
384    * corresponding subtriangle might cover zero sample points;
385    * we take care to handle such cases, for performance as well
386    * as correctness.
387    *
388    * By stepping rasterization parameters along the major edge,
389    * we can avoid recomputing them at the discontinuity where
390    * the top and bottom edges meet.  However, this forces us to
391    * be able to scan both left-to-right and right-to-left.
392    * Also, we must determine whether the major edge is at the
393    * left or right side of the triangle.  We do this by
394    * computing the magnitude of the cross-product of the major
395    * and top edges.  Since this magnitude depends on the sine of
396    * the angle between the two edges, its sign tells us whether
397    * we turn to the left or to the right when travelling along
398    * the major edge to the top edge, and from this we infer
399    * whether the major edge is on the left or the right.
400    *
401    * Serendipitously, this cross-product magnitude is also a
402    * value we need to compute the iteration parameter
403    * derivatives for the triangle, and it can be used to perform
404    * backface culling because its sign tells us whether the
405    * triangle is clockwise or counterclockwise.  In this code we
406    * refer to it as ``area'' because it's also proportional to
407    * the pixel area of the triangle.
408    */
409
410   {
411      GLint scan_from_left_to_right;  /* true if scanning left-to-right */
412#ifdef INTERP_INDEX
413      GLfloat didx, didy;
414#endif
415
416      /*
417       * Execute user-supplied setup code
418       */
419#ifdef SETUP_CODE
420      SETUP_CODE
421#endif
422
423      scan_from_left_to_right = (oneOverArea < 0.0F);
424
425
426      /* compute d?/dx and d?/dy derivatives */
427#ifdef INTERP_Z
428      span.interpMask |= SPAN_Z;
429      {
430         GLfloat eMaj_dz = vMax->win[2] - vMin->win[2];
431         GLfloat eBot_dz = vMid->win[2] - vMin->win[2];
432         span.attrStepX[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
433         if (span.attrStepX[FRAG_ATTRIB_WPOS][2] > maxDepth || span.attrStepX[FRAG_ATTRIB_WPOS][2] < -maxDepth) {
434            /* probably a sliver triangle */
435            span.attrStepX[FRAG_ATTRIB_WPOS][2] = 0.0;
436            span.attrStepY[FRAG_ATTRIB_WPOS][2] = 0.0;
437         }
438         else {
439            span.attrStepY[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
440         }
441         if (depthBits <= 16)
442            span.zStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_WPOS][2]);
443         else
444            span.zStep = (GLint) span.attrStepX[FRAG_ATTRIB_WPOS][2];
445      }
446#endif
447#ifdef INTERP_W
448      span.interpMask |= SPAN_W;
449      {
450         const GLfloat eMaj_dw = vMax->win[3] - vMin->win[3];
451         const GLfloat eBot_dw = vMid->win[3] - vMin->win[3];
452         span.attrStepX[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw);
453         span.attrStepY[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx);
454      }
455#endif
456#ifdef INTERP_FOG
457      span.interpMask |= SPAN_FOG;
458      {
459#  ifdef INTERP_W
460         const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3];
461         const GLfloat eMaj_dfog = vMax->fog * wMax - vMin->fog * wMin;
462         const GLfloat eBot_dfog = vMid->fog * wMid - vMin->fog * wMin;
463#  else
464         const GLfloat eMaj_dfog = vMax->fog - vMin->fog;
465         const GLfloat eBot_dfog = vMid->fog - vMin->fog;
466#  endif
467         span.attrStepX[FRAG_ATTRIB_FOGC][0] = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
468         span.attrStepY[FRAG_ATTRIB_FOGC][0] = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
469      }
470#endif
471#ifdef INTERP_RGB
472      span.interpMask |= SPAN_RGBA;
473      if (ctx->Light.ShadeModel == GL_SMOOTH) {
474         GLfloat eMaj_dr = (GLfloat) ((ColorTemp) vMax->color[RCOMP] - (ColorTemp) vMin->color[RCOMP]);
475         GLfloat eBot_dr = (GLfloat) ((ColorTemp) vMid->color[RCOMP] - (ColorTemp) vMin->color[RCOMP]);
476         GLfloat eMaj_dg = (GLfloat) ((ColorTemp) vMax->color[GCOMP] - (ColorTemp) vMin->color[GCOMP]);
477         GLfloat eBot_dg = (GLfloat) ((ColorTemp) vMid->color[GCOMP] - (ColorTemp) vMin->color[GCOMP]);
478         GLfloat eMaj_db = (GLfloat) ((ColorTemp) vMax->color[BCOMP] - (ColorTemp) vMin->color[BCOMP]);
479         GLfloat eBot_db = (GLfloat) ((ColorTemp) vMid->color[BCOMP] - (ColorTemp) vMin->color[BCOMP]);
480#  ifdef INTERP_ALPHA
481         GLfloat eMaj_da = (GLfloat) ((ColorTemp) vMax->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]);
482         GLfloat eBot_da = (GLfloat) ((ColorTemp) vMid->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]);
483#  endif
484         span.attrStepX[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
485         span.attrStepY[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
486         span.attrStepX[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
487         span.attrStepY[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
488         span.attrStepX[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
489         span.attrStepY[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
490#  if CHAN_TYPE == GL_FLOAT
491         span.redStep   = span.attrStepX[FRAG_ATTRIB_COL0][0];
492         span.greenStep = span.attrStepX[FRAG_ATTRIB_COL0][1];
493         span.blueStep  = span.attrStepX[FRAG_ATTRIB_COL0][2];
494#  else
495         span.redStep   = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][0]);
496         span.greenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][1]);
497         span.blueStep  = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][2]);
498#  endif /* GL_FLOAT */
499#  ifdef INTERP_ALPHA
500         span.attrStepX[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
501         span.attrStepX[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
502#    if CHAN_TYPE == GL_FLOAT
503         span.alphaStep = span.attrStepX[FRAG_ATTRIB_COL0][3];
504#    else
505         span.alphaStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3]);
506#    endif /* GL_FLOAT */
507#  endif /* INTERP_ALPHA */
508      }
509      else {
510         ASSERT(ctx->Light.ShadeModel == GL_FLAT);
511         span.interpMask |= SPAN_FLAT;
512         span.attrStepX[FRAG_ATTRIB_COL0][0] = span.attrStepY[FRAG_ATTRIB_COL0][0] = 0.0F;
513         span.attrStepX[FRAG_ATTRIB_COL0][1] = span.attrStepY[FRAG_ATTRIB_COL0][1] = 0.0F;
514         span.attrStepX[FRAG_ATTRIB_COL0][2] = span.attrStepY[FRAG_ATTRIB_COL0][2] = 0.0F;
515#    if CHAN_TYPE == GL_FLOAT
516	 span.redStep   = 0.0F;
517	 span.greenStep = 0.0F;
518	 span.blueStep  = 0.0F;
519#    else
520	 span.redStep   = 0;
521	 span.greenStep = 0;
522	 span.blueStep  = 0;
523#    endif /* GL_FLOAT */
524#  ifdef INTERP_ALPHA
525         span.attrStepX[FRAG_ATTRIB_COL0][3] = span.attrStepX[FRAG_ATTRIB_COL0][3] = 0.0F;
526#    if CHAN_TYPE == GL_FLOAT
527	 span.alphaStep = 0.0F;
528#    else
529	 span.alphaStep = 0;
530#    endif /* GL_FLOAT */
531#  endif
532      }
533#endif /* INTERP_RGB */
534#ifdef INTERP_SPEC
535      span.interpMask |= SPAN_SPEC;
536      if (ctx->Light.ShadeModel == GL_SMOOTH) {
537         GLfloat eMaj_dsr = (GLfloat) ((ColorTemp) vMax->specular[RCOMP] - (ColorTemp) vMin->specular[RCOMP]);
538         GLfloat eBot_dsr = (GLfloat) ((ColorTemp) vMid->specular[RCOMP] - (ColorTemp) vMin->specular[RCOMP]);
539         GLfloat eMaj_dsg = (GLfloat) ((ColorTemp) vMax->specular[GCOMP] - (ColorTemp) vMin->specular[GCOMP]);
540         GLfloat eBot_dsg = (GLfloat) ((ColorTemp) vMid->specular[GCOMP] - (ColorTemp) vMin->specular[GCOMP]);
541         GLfloat eMaj_dsb = (GLfloat) ((ColorTemp) vMax->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]);
542         GLfloat eBot_dsb = (GLfloat) ((ColorTemp) vMid->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]);
543         span.attrStepX[FRAG_ATTRIB_COL1][0] = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr);
544         span.attrStepY[FRAG_ATTRIB_COL1][0] = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx);
545         span.attrStepX[FRAG_ATTRIB_COL1][1] = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg);
546         span.attrStepY[FRAG_ATTRIB_COL1][1] = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx);
547         span.attrStepX[FRAG_ATTRIB_COL1][2] = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb);
548         span.attrStepY[FRAG_ATTRIB_COL1][2] = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx);
549#  if CHAN_TYPE == GL_FLOAT
550         span.specRedStep   = span.attrStepX[FRAG_ATTRIB_COL1][0];
551         span.specGreenStep = span.attrStepX[FRAG_ATTRIB_COL1][1];
552         span.specBlueStep  = span.attrStepX[FRAG_ATTRIB_COL1][2];
553#  else
554         span.specRedStep   = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][0]);
555         span.specGreenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][1]);
556         span.specBlueStep  = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][2]);
557#  endif
558      }
559      else {
560         span.attrStepX[FRAG_ATTRIB_COL1][0] = span.attrStepY[FRAG_ATTRIB_COL1][0] = 0.0F;
561         span.attrStepX[FRAG_ATTRIB_COL1][1] = span.attrStepY[FRAG_ATTRIB_COL1][1] = 0.0F;
562         span.attrStepX[FRAG_ATTRIB_COL1][2] = span.attrStepY[FRAG_ATTRIB_COL1][2] = 0.0F;
563#  if CHAN_TYPE == GL_FLOAT
564	 span.specRedStep   = 0.0F;
565	 span.specGreenStep = 0.0F;
566	 span.specBlueStep  = 0.0F;
567#  else
568	 span.specRedStep   = 0;
569	 span.specGreenStep = 0;
570	 span.specBlueStep  = 0;
571#  endif
572      }
573#endif /* INTERP_SPEC */
574#ifdef INTERP_INDEX
575      span.interpMask |= SPAN_INDEX;
576      if (ctx->Light.ShadeModel == GL_SMOOTH) {
577         GLfloat eMaj_di = vMax->index - vMin->index;
578         GLfloat eBot_di = vMid->index - vMin->index;
579         didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di);
580         didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx);
581         span.indexStep = SignedFloatToFixed(didx);
582      }
583      else {
584         span.interpMask |= SPAN_FLAT;
585         didx = didy = 0.0F;
586         span.indexStep = 0;
587      }
588#endif
589#ifdef INTERP_INT_TEX
590      span.interpMask |= SPAN_INT_TEXTURE;
591      {
592         GLfloat eMaj_ds = (vMax->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE;
593         GLfloat eBot_ds = (vMid->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE;
594         GLfloat eMaj_dt = (vMax->attrib[FRAG_ATTRIB_TEX0][1] - vMin->attrib[FRAG_ATTRIB_TEX0][1]) * T_SCALE;
595         GLfloat eBot_dt = (vMid->attrib[FRAG_ATTRIB_TEX0][1] - vMin->attrib[FRAG_ATTRIB_TEX0][1]) * T_SCALE;
596         span.attrStepX[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
597         span.attrStepY[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
598         span.attrStepX[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
599         span.attrStepY[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
600         span.intTexStep[0] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][0]);
601         span.intTexStep[1] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][1]);
602      }
603#endif
604#ifdef INTERP_TEX
605      span.interpMask |= (SPAN_TEXTURE | SPAN_VARYING);
606      {
607         /* win[3] is 1/W */
608         const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3];
609         ATTRIB_LOOP_BEGIN
610            GLfloat eMaj_ds = vMax->attrib[attr][0] * wMax - vMin->attrib[attr][0] * wMin;
611            GLfloat eBot_ds = vMid->attrib[attr][0] * wMid - vMin->attrib[attr][0] * wMin;
612            GLfloat eMaj_dt = vMax->attrib[attr][1] * wMax - vMin->attrib[attr][1] * wMin;
613            GLfloat eBot_dt = vMid->attrib[attr][1] * wMid - vMin->attrib[attr][1] * wMin;
614            GLfloat eMaj_du = vMax->attrib[attr][2] * wMax - vMin->attrib[attr][2] * wMin;
615            GLfloat eBot_du = vMid->attrib[attr][2] * wMid - vMin->attrib[attr][2] * wMin;
616            GLfloat eMaj_dv = vMax->attrib[attr][3] * wMax - vMin->attrib[attr][3] * wMin;
617            GLfloat eBot_dv = vMid->attrib[attr][3] * wMid - vMin->attrib[attr][3] * wMin;
618            span.attrStepX[attr][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
619            span.attrStepY[attr][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
620            span.attrStepX[attr][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
621            span.attrStepY[attr][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
622            span.attrStepX[attr][2] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
623            span.attrStepY[attr][2] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
624            span.attrStepX[attr][3] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
625            span.attrStepY[attr][3] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
626         ATTRIB_LOOP_END
627      }
628#endif
629
630      /*
631       * We always sample at pixel centers.  However, we avoid
632       * explicit half-pixel offsets in this code by incorporating
633       * the proper offset in each of x and y during the
634       * transformation to window coordinates.
635       *
636       * We also apply the usual rasterization rules to prevent
637       * cracks and overlaps.  A pixel is considered inside a
638       * subtriangle if it meets all of four conditions: it is on or
639       * to the right of the left edge, strictly to the left of the
640       * right edge, on or below the top edge, and strictly above
641       * the bottom edge.  (Some edges may be degenerate.)
642       *
643       * The following discussion assumes left-to-right scanning
644       * (that is, the major edge is on the left); the right-to-left
645       * case is a straightforward variation.
646       *
647       * We start by finding the half-integral y coordinate that is
648       * at or below the top of the triangle.  This gives us the
649       * first scan line that could possibly contain pixels that are
650       * inside the triangle.
651       *
652       * Next we creep down the major edge until we reach that y,
653       * and compute the corresponding x coordinate on the edge.
654       * Then we find the half-integral x that lies on or just
655       * inside the edge.  This is the first pixel that might lie in
656       * the interior of the triangle.  (We won't know for sure
657       * until we check the other edges.)
658       *
659       * As we rasterize the triangle, we'll step down the major
660       * edge.  For each step in y, we'll move an integer number
661       * of steps in x.  There are two possible x step sizes, which
662       * we'll call the ``inner'' step (guaranteed to land on the
663       * edge or inside it) and the ``outer'' step (guaranteed to
664       * land on the edge or outside it).  The inner and outer steps
665       * differ by one.  During rasterization we maintain an error
666       * term that indicates our distance from the true edge, and
667       * select either the inner step or the outer step, whichever
668       * gets us to the first pixel that falls inside the triangle.
669       *
670       * All parameters (z, red, etc.) as well as the buffer
671       * addresses for color and z have inner and outer step values,
672       * so that we can increment them appropriately.  This method
673       * eliminates the need to adjust parameters by creeping a
674       * sub-pixel amount into the triangle at each scanline.
675       */
676
677      {
678         GLint subTriangle;
679         GLinterp fxLeftEdge = 0, fxRightEdge = 0;
680         GLinterp fdxLeftEdge = 0, fdxRightEdge = 0;
681         GLinterp fError = 0, fdError = 0;
682#ifdef PIXEL_ADDRESS
683         PIXEL_TYPE *pRow = NULL;
684         GLint dPRowOuter = 0, dPRowInner;  /* offset in bytes */
685#endif
686#ifdef INTERP_Z
687#  ifdef DEPTH_TYPE
688         struct gl_renderbuffer *zrb
689            = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
690         DEPTH_TYPE *zRow = NULL;
691         GLint dZRowOuter = 0, dZRowInner;  /* offset in bytes */
692#  endif
693         GLuint zLeft = 0;
694         GLfixed fdzOuter = 0, fdzInner;
695#endif
696#ifdef INTERP_W
697         GLfloat wLeft = 0, dwOuter = 0, dwInner;
698#endif
699#ifdef INTERP_FOG
700         GLfloat fogLeft = 0, dfogOuter = 0, dfogInner;
701#endif
702#ifdef INTERP_RGB
703         ColorTemp rLeft = 0, fdrOuter = 0, fdrInner;
704         ColorTemp gLeft = 0, fdgOuter = 0, fdgInner;
705         ColorTemp bLeft = 0, fdbOuter = 0, fdbInner;
706#endif
707#ifdef INTERP_ALPHA
708         ColorTemp aLeft = 0, fdaOuter = 0, fdaInner;
709#endif
710#ifdef INTERP_SPEC
711         ColorTemp srLeft=0, dsrOuter=0, dsrInner;
712         ColorTemp sgLeft=0, dsgOuter=0, dsgInner;
713         ColorTemp sbLeft=0, dsbOuter=0, dsbInner;
714#endif
715#ifdef INTERP_INDEX
716         GLfixed iLeft=0, diOuter=0, diInner;
717#endif
718#ifdef INTERP_INT_TEX
719         GLfixed sLeft=0, dsOuter=0, dsInner;
720         GLfixed tLeft=0, dtOuter=0, dtInner;
721#endif
722#ifdef INTERP_TEX
723         GLfloat sLeft[FRAG_ATTRIB_MAX];
724         GLfloat tLeft[FRAG_ATTRIB_MAX];
725         GLfloat uLeft[FRAG_ATTRIB_MAX];
726         GLfloat vLeft[FRAG_ATTRIB_MAX];
727         GLfloat dsOuter[FRAG_ATTRIB_MAX], dsInner[FRAG_ATTRIB_MAX];
728         GLfloat dtOuter[FRAG_ATTRIB_MAX], dtInner[FRAG_ATTRIB_MAX];
729         GLfloat duOuter[FRAG_ATTRIB_MAX], duInner[FRAG_ATTRIB_MAX];
730         GLfloat dvOuter[FRAG_ATTRIB_MAX], dvInner[FRAG_ATTRIB_MAX];
731#endif
732
733         for (subTriangle=0; subTriangle<=1; subTriangle++) {
734            EdgeT *eLeft, *eRight;
735            int setupLeft, setupRight;
736            int lines;
737
738            if (subTriangle==0) {
739               /* bottom half */
740               if (scan_from_left_to_right) {
741                  eLeft = &eMaj;
742                  eRight = &eBot;
743                  lines = eRight->lines;
744                  setupLeft = 1;
745                  setupRight = 1;
746               }
747               else {
748                  eLeft = &eBot;
749                  eRight = &eMaj;
750                  lines = eLeft->lines;
751                  setupLeft = 1;
752                  setupRight = 1;
753               }
754            }
755            else {
756               /* top half */
757               if (scan_from_left_to_right) {
758                  eLeft = &eMaj;
759                  eRight = &eTop;
760                  lines = eRight->lines;
761                  setupLeft = 0;
762                  setupRight = 1;
763               }
764               else {
765                  eLeft = &eTop;
766                  eRight = &eMaj;
767                  lines = eLeft->lines;
768                  setupLeft = 1;
769                  setupRight = 0;
770               }
771               if (lines == 0)
772                  return;
773            }
774
775            if (setupLeft && eLeft->lines > 0) {
776               const SWvertex *vLower = eLeft->v0;
777#if TRIANGLE_WALK_DOUBLE
778               const GLdouble fsy = eLeft->fsy;
779               const GLdouble fsx = eLeft->fsx;
780               const GLdouble fx = CEILF(fsx);
781               const GLdouble adjx = (fx - eLeft->fx0) * FIXED_SCALE;  /* SCALED! */
782#else
783               const GLfixed fsy = eLeft->fsy;
784               const GLfixed fsx = eLeft->fsx;  /* no fractional part */
785               const GLfixed fx = FixedCeil(fsx);  /* no fractional part */
786               const GLfixed adjx = (GLinterp) (fx - eLeft->fx0); /* SCALED! */
787#endif
788               const GLinterp adjy = (GLinterp) eLeft->adjy;      /* SCALED! */
789               GLint idxOuter;
790#if TRIANGLE_WALK_DOUBLE
791               GLdouble dxOuter;
792
793               fError = fx - fsx - 1.0;
794               fxLeftEdge = fsx;
795               fdxLeftEdge = eLeft->dxdy;
796               dxOuter = FLOORF(fdxLeftEdge);
797               fdError = dxOuter - fdxLeftEdge + 1.0;
798               idxOuter = (GLint) dxOuter;
799               span.y = (GLint) fsy;
800#else
801               GLfloat dxOuter;
802               GLfixed fdxOuter;
803
804               fError = fx - fsx - FIXED_ONE;
805               fxLeftEdge = fsx - FIXED_EPSILON;
806               fdxLeftEdge = eLeft->fdxdy;
807               fdxOuter = FixedFloor(fdxLeftEdge - FIXED_EPSILON);
808               fdError = fdxOuter - fdxLeftEdge + FIXED_ONE;
809               idxOuter = FixedToInt(fdxOuter);
810               dxOuter = (GLfloat) idxOuter;
811               span.y = FixedToInt(fsy);
812#endif
813
814               /* silence warnings on some compilers */
815               (void) dxOuter;
816               (void) adjx;
817               (void) adjy;
818               (void) vLower;
819
820#ifdef PIXEL_ADDRESS
821               {
822                  pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(InterpToInt(fxLeftEdge), span.y);
823                  dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE);
824                  /* negative because Y=0 at bottom and increases upward */
825               }
826#endif
827               /*
828                * Now we need the set of parameter (z, color, etc.) values at
829                * the point (fx, fsy).  This gives us properly-sampled parameter
830                * values that we can step from pixel to pixel.  Furthermore,
831                * although we might have intermediate results that overflow
832                * the normal parameter range when we step temporarily outside
833                * the triangle, we shouldn't overflow or underflow for any
834                * pixel that's actually inside the triangle.
835                */
836
837#ifdef INTERP_Z
838               {
839                  GLfloat z0 = vLower->win[2];
840                  if (depthBits <= 16) {
841                     /* interpolate fixed-pt values */
842                     GLfloat tmp = (z0 * FIXED_SCALE
843                                    + span.attrStepX[FRAG_ATTRIB_WPOS][2] * adjx
844                                    + span.attrStepY[FRAG_ATTRIB_WPOS][2] * adjy) + FIXED_HALF;
845                     if (tmp < MAX_GLUINT / 2)
846                        zLeft = (GLfixed) tmp;
847                     else
848                        zLeft = MAX_GLUINT / 2;
849                     fdzOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
850                  }
851                  else {
852                     /* interpolate depth values w/out scaling */
853                     zLeft = (GLuint) (z0 + span.attrStepX[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjx)
854                                          + span.attrStepY[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjy));
855                     fdzOuter = (GLint) (span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
856                  }
857#  ifdef DEPTH_TYPE
858                  zRow = (DEPTH_TYPE *)
859                    zrb->GetPointer(ctx, zrb, InterpToInt(fxLeftEdge), span.y);
860                  dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE);
861#  endif
862               }
863#endif
864#ifdef INTERP_W
865               wLeft = vLower->win[3] + (span.attrStepX[FRAG_ATTRIB_WPOS][3] * adjx + span.attrStepY[FRAG_ATTRIB_WPOS][3] * adjy) * (1.0F/FIXED_SCALE);
866               dwOuter = span.attrStepY[FRAG_ATTRIB_WPOS][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][3];
867#endif
868#ifdef INTERP_FOG
869#  ifdef INTERP_W
870               fogLeft = vLower->fog * vLower->win[3] + (span.attrStepX[FRAG_ATTRIB_FOGC][0] * adjx + span.attrStepY[FRAG_ATTRIB_FOGC][0] * adjy) * (1.0F/FIXED_SCALE);
871#  else
872               fogLeft = vLower->fog + (span.attrStepX[FRAG_ATTRIB_FOGC][0] * adjx + span.attrStepY[FRAG_ATTRIB_FOGC][0] * adjy) * (1.0F/FIXED_SCALE);
873#  endif
874               dfogOuter = span.attrStepY[FRAG_ATTRIB_FOGC][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_FOGC][0];
875#endif
876#ifdef INTERP_RGB
877               if (ctx->Light.ShadeModel == GL_SMOOTH) {
878#  if CHAN_TYPE == GL_FLOAT
879                  rLeft = vLower->color[RCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) * (1.0F / FIXED_SCALE);
880                  gLeft = vLower->color[GCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) * (1.0F / FIXED_SCALE);
881                  bLeft = vLower->color[BCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) * (1.0F / FIXED_SCALE);
882                  fdrOuter = span.attrStepY[FRAG_ATTRIB_COL0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0];
883                  fdgOuter = span.attrStepY[FRAG_ATTRIB_COL0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1];
884                  fdbOuter = span.attrStepY[FRAG_ATTRIB_COL0][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2];
885#  else
886                  rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) + FIXED_HALF;
887                  gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) + FIXED_HALF;
888                  bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) + FIXED_HALF;
889                  fdrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0]);
890                  fdgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1]);
891                  fdbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2]);
892#  endif
893#  ifdef INTERP_ALPHA
894#    if CHAN_TYPE == GL_FLOAT
895                  aLeft = vLower->color[ACOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjy) * (1.0F / FIXED_SCALE);
896                  fdaOuter = span.attrStepX[FRAG_ATTRIB_COL0][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3];
897#    else
898                  aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjy) + FIXED_HALF;
899                  fdaOuter = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]);
900#    endif
901#  endif
902               }
903               else {
904                  ASSERT(ctx->Light.ShadeModel == GL_FLAT);
905#  if CHAN_TYPE == GL_FLOAT
906                  rLeft = v2->color[RCOMP];
907                  gLeft = v2->color[GCOMP];
908                  bLeft = v2->color[BCOMP];
909                  fdrOuter = fdgOuter = fdbOuter = 0.0F;
910#  else
911                  rLeft = ChanToFixed(v2->color[RCOMP]);
912                  gLeft = ChanToFixed(v2->color[GCOMP]);
913                  bLeft = ChanToFixed(v2->color[BCOMP]);
914                  fdrOuter = fdgOuter = fdbOuter = 0;
915#  endif
916#  ifdef INTERP_ALPHA
917#    if CHAN_TYPE == GL_FLOAT
918                  aLeft = v2->color[ACOMP];
919                  fdaOuter = 0.0F;
920#    else
921                  aLeft = ChanToFixed(v2->color[ACOMP]);
922                  fdaOuter = 0;
923#    endif
924#  endif
925               }
926#endif /* INTERP_RGB */
927
928
929#ifdef INTERP_SPEC
930               if (ctx->Light.ShadeModel == GL_SMOOTH) {
931#  if CHAN_TYPE == GL_FLOAT
932                  srLeft = vLower->specular[RCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][0] * adjy) * (1.0F / FIXED_SCALE);
933                  sgLeft = vLower->specular[GCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][1] * adjy) * (1.0F / FIXED_SCALE);
934                  sbLeft = vLower->specular[BCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][2] * adjy) * (1.0F / FIXED_SCALE);
935                  dsrOuter = span.attrStepY[FRAG_ATTRIB_COL1][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][0];
936                  dsgOuter = span.attrStepY[FRAG_ATTRIB_COL1][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][1];
937                  dsbOuter = span.attrStepY[FRAG_ATTRIB_COL1][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][2];
938#  else
939                  srLeft = (GLfixed) (ChanToFixed(vLower->specular[RCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][0] * adjy) + FIXED_HALF;
940                  sgLeft = (GLfixed) (ChanToFixed(vLower->specular[GCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][1] * adjy) + FIXED_HALF;
941                  sbLeft = (GLfixed) (ChanToFixed(vLower->specular[BCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][2] * adjy) + FIXED_HALF;
942                  dsrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][0]);
943                  dsgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][1]);
944                  dsbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][2]);
945#  endif
946               }
947               else {
948                  ASSERT(ctx->Light.ShadeModel == GL_FLAT);
949#if  CHAN_TYPE == GL_FLOAT
950                  srLeft = v2->specular[RCOMP];
951                  sgLeft = v2->specular[GCOMP];
952                  sbLeft = v2->specular[BCOMP];
953                  dsrOuter = dsgOuter = dsbOuter = 0.0F;
954#  else
955                  srLeft = ChanToFixed(v2->specular[RCOMP]);
956                  sgLeft = ChanToFixed(v2->specular[GCOMP]);
957                  sbLeft = ChanToFixed(v2->specular[BCOMP]);
958                  dsrOuter = dsgOuter = dsbOuter = 0;
959#  endif
960               }
961#endif
962
963#ifdef INTERP_INDEX
964               if (ctx->Light.ShadeModel == GL_SMOOTH) {
965                  iLeft = (GLfixed)(vLower->index * FIXED_SCALE
966                                 + didx * adjx + didy * adjy) + FIXED_HALF;
967                  diOuter = SignedFloatToFixed(didy + dxOuter * didx);
968               }
969               else {
970                  ASSERT(ctx->Light.ShadeModel == GL_FLAT);
971                  iLeft = FloatToFixed(v2->index);
972                  diOuter = 0;
973               }
974#endif
975#ifdef INTERP_INT_TEX
976               {
977                  GLfloat s0, t0;
978                  s0 = vLower->attrib[FRAG_ATTRIB_TEX0][0] * S_SCALE;
979                  sLeft = (GLfixed)(s0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][0] * adjx
980                                 + span.attrStepY[FRAG_ATTRIB_TEX0][0] * adjy) + FIXED_HALF;
981                  dsOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][0]);
982
983                  t0 = vLower->attrib[FRAG_ATTRIB_TEX0][1] * T_SCALE;
984                  tLeft = (GLfixed)(t0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][1] * adjx
985                                 + span.attrStepY[FRAG_ATTRIB_TEX0][1] * adjy) + FIXED_HALF;
986                  dtOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][1]);
987               }
988#endif
989#ifdef INTERP_TEX
990               ATTRIB_LOOP_BEGIN
991                  const GLfloat invW = vLower->win[3];
992                  const GLfloat s0 = vLower->attrib[attr][0] * invW;
993                  const GLfloat t0 = vLower->attrib[attr][1] * invW;
994                  const GLfloat u0 = vLower->attrib[attr][2] * invW;
995                  const GLfloat v0 = vLower->attrib[attr][3] * invW;
996                  sLeft[attr] = s0 + (span.attrStepX[attr][0] * adjx + span.attrStepY[attr][0] * adjy) * (1.0F/FIXED_SCALE);
997                  tLeft[attr] = t0 + (span.attrStepX[attr][1] * adjx + span.attrStepY[attr][1] * adjy) * (1.0F/FIXED_SCALE);
998                  uLeft[attr] = u0 + (span.attrStepX[attr][2] * adjx + span.attrStepY[attr][2] * adjy) * (1.0F/FIXED_SCALE);
999                  vLeft[attr] = v0 + (span.attrStepX[attr][3] * adjx + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE);
1000                  dsOuter[attr] = span.attrStepY[attr][0] + dxOuter * span.attrStepX[attr][0];
1001                  dtOuter[attr] = span.attrStepY[attr][1] + dxOuter * span.attrStepX[attr][1];
1002                  duOuter[attr] = span.attrStepY[attr][2] + dxOuter * span.attrStepX[attr][2];
1003                  dvOuter[attr] = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3];
1004               ATTRIB_LOOP_END
1005#endif
1006            } /*if setupLeft*/
1007
1008
1009            if (setupRight && eRight->lines>0) {
1010#if TRIANGLE_WALK_DOUBLE
1011               fxRightEdge = eRight->fsx;
1012               fdxRightEdge = eRight->dxdy;
1013#else
1014               fxRightEdge = eRight->fsx - FIXED_EPSILON;
1015               fdxRightEdge = eRight->fdxdy;
1016#endif
1017            }
1018
1019            if (lines==0) {
1020               continue;
1021            }
1022
1023
1024            /* Rasterize setup */
1025#ifdef PIXEL_ADDRESS
1026            dPRowInner = dPRowOuter + sizeof(PIXEL_TYPE);
1027#endif
1028#ifdef INTERP_Z
1029#  ifdef DEPTH_TYPE
1030            dZRowInner = dZRowOuter + sizeof(DEPTH_TYPE);
1031#  endif
1032            fdzInner = fdzOuter + span.zStep;
1033#endif
1034#ifdef INTERP_W
1035            dwInner = dwOuter + span.attrStepX[FRAG_ATTRIB_WPOS][3];
1036#endif
1037#ifdef INTERP_FOG
1038            dfogInner = dfogOuter + span.attrStepX[FRAG_ATTRIB_FOGC][0];
1039#endif
1040#ifdef INTERP_RGB
1041            fdrInner = fdrOuter + span.redStep;
1042            fdgInner = fdgOuter + span.greenStep;
1043            fdbInner = fdbOuter + span.blueStep;
1044#endif
1045#ifdef INTERP_ALPHA
1046            fdaInner = fdaOuter + span.alphaStep;
1047#endif
1048#ifdef INTERP_SPEC
1049            dsrInner = dsrOuter + span.specRedStep;
1050            dsgInner = dsgOuter + span.specGreenStep;
1051            dsbInner = dsbOuter + span.specBlueStep;
1052#endif
1053#ifdef INTERP_INDEX
1054            diInner = diOuter + span.indexStep;
1055#endif
1056#ifdef INTERP_INT_TEX
1057            dsInner = dsOuter + span.intTexStep[0];
1058            dtInner = dtOuter + span.intTexStep[1];
1059#endif
1060#ifdef INTERP_TEX
1061            ATTRIB_LOOP_BEGIN
1062               dsInner[attr] = dsOuter[attr] + span.attrStepX[attr][0];
1063               dtInner[attr] = dtOuter[attr] + span.attrStepX[attr][1];
1064               duInner[attr] = duOuter[attr] + span.attrStepX[attr][2];
1065               dvInner[attr] = dvOuter[attr] + span.attrStepX[attr][3];
1066            ATTRIB_LOOP_END
1067#endif
1068
1069            while (lines > 0) {
1070               /* initialize the span interpolants to the leftmost value */
1071               /* ff = fixed-pt fragment */
1072               const GLint right = InterpToInt(fxRightEdge);
1073               span.x = InterpToInt(fxLeftEdge);
1074               if (right <= span.x)
1075                  span.end = 0;
1076               else
1077                  span.end = right - span.x;
1078
1079#ifdef INTERP_Z
1080               span.z = zLeft;
1081#endif
1082#ifdef INTERP_W
1083               span.attrStart[FRAG_ATTRIB_WPOS][3] = wLeft;
1084#endif
1085#ifdef INTERP_FOG
1086               span.attrStart[FRAG_ATTRIB_FOGC][0] = fogLeft;
1087#endif
1088#ifdef INTERP_RGB
1089               span.red = rLeft;
1090               span.green = gLeft;
1091               span.blue = bLeft;
1092#endif
1093#ifdef INTERP_ALPHA
1094               span.alpha = aLeft;
1095#endif
1096#ifdef INTERP_SPEC
1097               span.specRed = srLeft;
1098               span.specGreen = sgLeft;
1099               span.specBlue = sbLeft;
1100#endif
1101#ifdef INTERP_INDEX
1102               span.index = iLeft;
1103#endif
1104#ifdef INTERP_INT_TEX
1105               span.intTex[0] = sLeft;
1106               span.intTex[1] = tLeft;
1107#endif
1108
1109#ifdef INTERP_TEX
1110               ATTRIB_LOOP_BEGIN
1111                  span.attrStart[attr][0] = sLeft[attr];
1112                  span.attrStart[attr][1] = tLeft[attr];
1113                  span.attrStart[attr][2] = uLeft[attr];
1114                  span.attrStart[attr][3] = vLeft[attr];
1115               ATTRIB_LOOP_END
1116#endif
1117
1118               /* This is where we actually generate fragments */
1119               /* XXX the test for span.y > 0 _shouldn't_ be needed but
1120                * it fixes a problem on 64-bit Opterons (bug 4842).
1121                */
1122               if (span.end > 0 && span.y >= 0) {
1123                  const GLint len = span.end - 1;
1124                  (void) len;
1125#ifdef INTERP_RGB
1126                  CLAMP_INTERPOLANT(red, redStep, len);
1127                  CLAMP_INTERPOLANT(green, greenStep, len);
1128                  CLAMP_INTERPOLANT(blue, blueStep, len);
1129#endif
1130#ifdef INTERP_ALPHA
1131                  CLAMP_INTERPOLANT(alpha, alphaStep, len);
1132#endif
1133#ifdef INTERP_SPEC
1134                  CLAMP_INTERPOLANT(specRed, specRedStep, len);
1135                  CLAMP_INTERPOLANT(specGreen, specGreenStep, len);
1136                  CLAMP_INTERPOLANT(specBlue, specBlueStep, len);
1137#endif
1138#ifdef INTERP_INDEX
1139                  CLAMP_INTERPOLANT(index, indexStep, len);
1140#endif
1141                  {
1142                     RENDER_SPAN( span );
1143                  }
1144               }
1145
1146               /*
1147                * Advance to the next scan line.  Compute the
1148                * new edge coordinates, and adjust the
1149                * pixel-center x coordinate so that it stays
1150                * on or inside the major edge.
1151                */
1152               span.y++;
1153               lines--;
1154
1155               fxLeftEdge += fdxLeftEdge;
1156               fxRightEdge += fdxRightEdge;
1157
1158               fError += fdError;
1159               if (fError >= 0) {
1160                  fError -= INTERP_ONE;
1161
1162#ifdef PIXEL_ADDRESS
1163                  pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter);
1164#endif
1165#ifdef INTERP_Z
1166#  ifdef DEPTH_TYPE
1167                  zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowOuter);
1168#  endif
1169                  zLeft += fdzOuter;
1170#endif
1171#ifdef INTERP_W
1172                  wLeft += dwOuter;
1173#endif
1174#ifdef INTERP_FOG
1175                  fogLeft += dfogOuter;
1176#endif
1177#ifdef INTERP_RGB
1178                  rLeft += fdrOuter;
1179                  gLeft += fdgOuter;
1180                  bLeft += fdbOuter;
1181#endif
1182#ifdef INTERP_ALPHA
1183                  aLeft += fdaOuter;
1184#endif
1185#ifdef INTERP_SPEC
1186                  srLeft += dsrOuter;
1187                  sgLeft += dsgOuter;
1188                  sbLeft += dsbOuter;
1189#endif
1190#ifdef INTERP_INDEX
1191                  iLeft += diOuter;
1192#endif
1193#ifdef INTERP_INT_TEX
1194                  sLeft += dsOuter;
1195                  tLeft += dtOuter;
1196#endif
1197#ifdef INTERP_TEX
1198                  ATTRIB_LOOP_BEGIN
1199                     sLeft[attr] += dsOuter[attr];
1200                     tLeft[attr] += dtOuter[attr];
1201                     uLeft[attr] += duOuter[attr];
1202                     vLeft[attr] += dvOuter[attr];
1203                  ATTRIB_LOOP_END
1204#endif
1205               }
1206               else {
1207#ifdef PIXEL_ADDRESS
1208                  pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowInner);
1209#endif
1210#ifdef INTERP_Z
1211#  ifdef DEPTH_TYPE
1212                  zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowInner);
1213#  endif
1214                  zLeft += fdzInner;
1215#endif
1216#ifdef INTERP_W
1217                  wLeft += dwInner;
1218#endif
1219#ifdef INTERP_FOG
1220                  fogLeft += dfogInner;
1221#endif
1222#ifdef INTERP_RGB
1223                  rLeft += fdrInner;
1224                  gLeft += fdgInner;
1225                  bLeft += fdbInner;
1226#endif
1227#ifdef INTERP_ALPHA
1228                  aLeft += fdaInner;
1229#endif
1230#ifdef INTERP_SPEC
1231                  srLeft += dsrInner;
1232                  sgLeft += dsgInner;
1233                  sbLeft += dsbInner;
1234#endif
1235#ifdef INTERP_INDEX
1236                  iLeft += diInner;
1237#endif
1238#ifdef INTERP_INT_TEX
1239                  sLeft += dsInner;
1240                  tLeft += dtInner;
1241#endif
1242#ifdef INTERP_TEX
1243                  ATTRIB_LOOP_BEGIN
1244                     sLeft[attr] += dsInner[attr];
1245                     tLeft[attr] += dtInner[attr];
1246                     uLeft[attr] += duInner[attr];
1247                     vLeft[attr] += dvInner[attr];
1248                  ATTRIB_LOOP_END
1249#endif
1250               }
1251            } /*while lines>0*/
1252
1253         } /* for subTriangle */
1254
1255      }
1256#ifdef CLEANUP_CODE
1257      CLEANUP_CODE
1258#endif
1259   }
1260}
1261
1262#undef SETUP_CODE
1263#undef CLEANUP_CODE
1264#undef RENDER_SPAN
1265
1266#undef PIXEL_TYPE
1267#undef BYTES_PER_ROW
1268#undef PIXEL_ADDRESS
1269#undef DEPTH_TYPE
1270
1271#undef INTERP_Z
1272#undef INTERP_W
1273#undef INTERP_FOG
1274#undef INTERP_RGB
1275#undef INTERP_ALPHA
1276#undef INTERP_SPEC
1277#undef INTERP_INDEX
1278#undef INTERP_INT_TEX
1279#undef INTERP_TEX
1280#undef TEX_UNIT_LOOP
1281#undef VARYING_LOOP
1282
1283#undef S_SCALE
1284#undef T_SCALE
1285
1286#undef FixedToDepth
1287#undef ColorTemp
1288#undef GLinterp
1289#undef InterpToInt
1290#undef INTERP_ONE
1291
1292#undef NAME
1293