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