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