s_tritemp.h revision c1b97d91c7e38290be85eb1ff56e6c108e1e47ca
1/* $Id: s_tritemp.h,v 1.6 2000/12/08 00:09:24 brianp Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version:  3.5
6 *
7 * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28/*
29 * Triangle Rasterizer Template
30 *
31 * This file is #include'd to generate custom triangle rasterizers.
32 *
33 * The following macros may be defined to indicate what auxillary information
34 * must be interplated across the triangle:
35 *    INTERP_Z        - if defined, interpolate Z values
36 *    INTERP_RGB      - if defined, interpolate RGB values
37 *    INTERP_SPEC     - if defined, interpolate specular RGB values
38 *    INTERP_ALPHA    - if defined, interpolate Alpha values
39 *    INTERP_INDEX    - if defined, interpolate color index values
40 *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
41 *                         (fast, simple 2-D texture mapping)
42 *    INTERP_TEX      - if defined, interpolate set 0 float STRQ texcoords
43 *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
44 *    INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
45 *
46 * When one can directly address pixels in the color buffer the following
47 * macros can be defined and used to compute pixel addresses during
48 * rasterization (see pRow):
49 *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
50 *    BYTES_PER_ROW       - number of bytes per row in the color buffer
51 *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
52 *                          Y==0 at bottom of screen and increases upward.
53 *
54 * Similarly, for direct depth buffer access, this type is used for depth
55 * buffer addressing:
56 *    DEPTH_TYPE          - either GLushort or GLuint
57 *
58 * Optionally, one may provide one-time setup code per triangle:
59 *    SETUP_CODE    - code which is to be executed once per triangle
60 *
61 * The following macro MUST be defined:
62 *    INNER_LOOP(LEFT,RIGHT,Y) - code to write a span of pixels.
63 *        Something like:
64 *
65 *                    for (x=LEFT; x<RIGHT;x++) {
66 *                       put_pixel(x,Y);
67 *                       // increment fixed point interpolants
68 *                    }
69 *
70 * This code was designed for the origin to be in the lower-left corner.
71 *
72 * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
73 */
74
75
76/*void triangle( GLcontext *ctx, SWvertex *v0, SWvertex *v1, SWvertex *v2 )*/
77{
78   typedef struct {
79        const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
80	GLfloat dx;	/* X(v1) - X(v0) */
81	GLfloat dy;	/* Y(v1) - Y(v0) */
82	GLfixed fdxdy;	/* dx/dy in fixed-point */
83	GLfixed fsx;	/* first sample point x coord */
84	GLfixed fsy;
85	GLfloat adjy;	/* adjust from v[0]->fy to fsy, scaled */
86	GLint lines;	/* number of lines to be sampled on this edge */
87	GLfixed fx0;	/* fixed pt X of lower endpoint */
88   } EdgeT;
89
90#ifdef INTERP_Z
91   const GLint depthBits = ctx->Visual.DepthBits;
92   const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0;
93   const GLfloat maxDepth = ctx->Visual.DepthMaxF;
94#define FixedToDepth(F)  ((F) >> fixedToDepthShift)
95#endif
96   EdgeT eMaj, eTop, eBot;
97   GLfloat oneOverArea;
98   const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
99   float bf = SWRAST_CONTEXT(ctx)->_backface_sign;
100
101   /* find the order of the 3 vertices along the Y axis */
102   {
103      GLfloat y0 = v0->win[1];
104      GLfloat y1 = v1->win[1];
105      GLfloat y2 = v2->win[1];
106
107      if (y0<=y1) {
108	 if (y1<=y2) {
109	    vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
110	 }
111	 else if (y2<=y0) {
112	    vMin = v2;   vMid = v0;   vMax = v1;   /* y2<=y0<=y1 */
113	 }
114	 else {
115	    vMin = v0;   vMid = v2;   vMax = v1;  bf = -bf; /* y0<=y2<=y1 */
116	 }
117      }
118      else {
119	 if (y0<=y2) {
120	    vMin = v1;   vMid = v0;   vMax = v2;  bf = -bf; /* y1<=y0<=y2 */
121	 }
122	 else if (y2<=y1) {
123	    vMin = v2;   vMid = v1;   vMax = v0;  bf = -bf; /* y2<=y1<=y0 */
124	 }
125	 else {
126	    vMin = v1;   vMid = v2;   vMax = v0;   /* y1<=y2<=y0 */
127	 }
128      }
129   }
130
131   /* vertex/edge relationship */
132   eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
133   eTop.v0 = vMid;   eTop.v1 = vMax;
134   eBot.v0 = vMin;   eBot.v1 = vMid;
135
136   /* compute deltas for each edge:  vertex[v1] - vertex[v0] */
137   eMaj.dx = vMax->win[0] - vMin->win[0];
138   eMaj.dy = vMax->win[1] - vMin->win[1];
139   eTop.dx = vMax->win[0] - vMid->win[0];
140   eTop.dy = vMax->win[1] - vMid->win[1];
141   eBot.dx = vMid->win[0] - vMin->win[0];
142   eBot.dy = vMid->win[1] - vMin->win[1];
143
144   /* compute oneOverArea */
145   {
146      const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
147
148      /* Do backface culling */
149      if (area * bf < 0.0)
150	 return;
151
152      if (area == 0.0F)
153         return;
154
155      /* check for very tiny triangle */
156      if (area * area < (0.05F * 0.05F))  /* square to ensure positive value */
157         oneOverArea = 1.0F / 0.05F;  /* a close-enough value */
158      else
159         oneOverArea = 1.0F / area;
160   }
161
162#ifndef DO_OCCLUSION_TEST
163   ctx->OcclusionResult = GL_TRUE;
164#endif
165
166   /* Edge setup.  For a triangle strip these could be reused... */
167   {
168      /* fixed point Y coordinates */
169      GLfixed vMin_fx = FloatToFixed(vMin->win[0] + 0.5F);
170      GLfixed vMin_fy = FloatToFixed(vMin->win[1] - 0.5F);
171      GLfixed vMid_fx = FloatToFixed(vMid->win[0] + 0.5F);
172      GLfixed vMid_fy = FloatToFixed(vMid->win[1] - 0.5F);
173      GLfixed vMax_fy = FloatToFixed(vMax->win[1] - 0.5F);
174
175      eMaj.fsy = FixedCeil(vMin_fy);
176      eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy));
177      if (eMaj.lines > 0) {
178         GLfloat dxdy = eMaj.dx / eMaj.dy;
179         eMaj.fdxdy = SignedFloatToFixed(dxdy);
180         eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
181         eMaj.fx0 = vMin_fx;
182         eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy);
183      }
184      else {
185         return;  /*CULLED*/
186      }
187
188      eTop.fsy = FixedCeil(vMid_fy);
189      eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy));
190      if (eTop.lines > 0) {
191         GLfloat dxdy = eTop.dx / eTop.dy;
192         eTop.fdxdy = SignedFloatToFixed(dxdy);
193         eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
194         eTop.fx0 = vMid_fx;
195         eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy);
196      }
197
198      eBot.fsy = FixedCeil(vMin_fy);
199      eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy));
200      if (eBot.lines > 0) {
201         GLfloat dxdy = eBot.dx / eBot.dy;
202         eBot.fdxdy = SignedFloatToFixed(dxdy);
203         eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
204         eBot.fx0 = vMin_fx;
205         eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy);
206      }
207   }
208
209   /*
210    * Conceptually, we view a triangle as two subtriangles
211    * separated by a perfectly horizontal line.  The edge that is
212    * intersected by this line is one with maximal absolute dy; we
213    * call it a ``major'' edge.  The other two edges are the
214    * ``top'' edge (for the upper subtriangle) and the ``bottom''
215    * edge (for the lower subtriangle).  If either of these two
216    * edges is horizontal or very close to horizontal, the
217    * corresponding subtriangle might cover zero sample points;
218    * we take care to handle such cases, for performance as well
219    * as correctness.
220    *
221    * By stepping rasterization parameters along the major edge,
222    * we can avoid recomputing them at the discontinuity where
223    * the top and bottom edges meet.  However, this forces us to
224    * be able to scan both left-to-right and right-to-left.
225    * Also, we must determine whether the major edge is at the
226    * left or right side of the triangle.  We do this by
227    * computing the magnitude of the cross-product of the major
228    * and top edges.  Since this magnitude depends on the sine of
229    * the angle between the two edges, its sign tells us whether
230    * we turn to the left or to the right when travelling along
231    * the major edge to the top edge, and from this we infer
232    * whether the major edge is on the left or the right.
233    *
234    * Serendipitously, this cross-product magnitude is also a
235    * value we need to compute the iteration parameter
236    * derivatives for the triangle, and it can be used to perform
237    * backface culling because its sign tells us whether the
238    * triangle is clockwise or counterclockwise.  In this code we
239    * refer to it as ``area'' because it's also proportional to
240    * the pixel area of the triangle.
241    */
242
243   {
244      GLint ltor;		/* true if scanning left-to-right */
245#ifdef INTERP_Z
246      GLfloat dzdx, dzdy;      GLfixed fdzdx;
247      GLfloat dfogdx, dfogdy;      GLfixed fdfogdx;
248#endif
249#ifdef INTERP_RGB
250      GLfloat drdx, drdy;      GLfixed fdrdx;
251      GLfloat dgdx, dgdy;      GLfixed fdgdx;
252      GLfloat dbdx, dbdy;      GLfixed fdbdx;
253#endif
254#ifdef INTERP_SPEC
255      GLfloat dsrdx, dsrdy;    GLfixed fdsrdx;
256      GLfloat dsgdx, dsgdy;    GLfixed fdsgdx;
257      GLfloat dsbdx, dsbdy;    GLfixed fdsbdx;
258#endif
259#ifdef INTERP_ALPHA
260      GLfloat dadx, dady;      GLfixed fdadx;
261#endif
262#ifdef INTERP_INDEX
263      GLfloat didx, didy;      GLfixed fdidx;
264#endif
265#ifdef INTERP_INT_TEX
266      GLfloat dsdx, dsdy;      GLfixed fdsdx;
267      GLfloat dtdx, dtdy;      GLfixed fdtdx;
268#endif
269#ifdef INTERP_TEX
270      GLfloat dsdx, dsdy;
271      GLfloat dtdx, dtdy;
272      GLfloat dudx, dudy;
273      GLfloat dvdx, dvdy;
274#endif
275#ifdef INTERP_MULTITEX
276      GLfloat dsdx[MAX_TEXTURE_UNITS], dsdy[MAX_TEXTURE_UNITS];
277      GLfloat dtdx[MAX_TEXTURE_UNITS], dtdy[MAX_TEXTURE_UNITS];
278      GLfloat dudx[MAX_TEXTURE_UNITS], dudy[MAX_TEXTURE_UNITS];
279      GLfloat dvdx[MAX_TEXTURE_UNITS], dvdy[MAX_TEXTURE_UNITS];
280#endif
281
282      /*
283       * Execute user-supplied setup code
284       */
285#ifdef SETUP_CODE
286      SETUP_CODE
287#endif
288
289      ltor = (oneOverArea < 0.0F);
290
291      /* compute d?/dx and d?/dy derivatives */
292#ifdef INTERP_Z
293      {
294         GLfloat eMaj_dz, eBot_dz;
295         eMaj_dz = vMax->win[2] - vMin->win[2];
296         eBot_dz = vMid->win[2] - vMin->win[2];
297         dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
298         if (dzdx > maxDepth || dzdx < -maxDepth) {
299            /* probably a sliver triangle */
300            dzdx = 0.0;
301            dzdy = 0.0;
302         }
303         else {
304            dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
305         }
306         if (depthBits <= 16)
307            fdzdx = SignedFloatToFixed(dzdx);
308         else
309            fdzdx = (GLint) dzdx;
310      }
311      {
312         GLfloat eMaj_dfog, eBot_dfog;
313         eMaj_dfog = (vMax->fog - vMin->fog) * 256;
314         eBot_dfog = (vMid->fog - vMin->fog) * 256;
315         dfogdx = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
316         fdfogdx = SignedFloatToFixed(dfogdx);
317         dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
318      }
319#endif
320#ifdef INTERP_RGB
321      {
322         GLfloat eMaj_dr, eBot_dr;
323         eMaj_dr = (GLint) vMax->color[0]
324                 - (GLint) vMin->color[0];
325         eBot_dr = (GLint) vMid->color[0]
326                 - (GLint) vMin->color[0];
327         drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
328         fdrdx = SignedFloatToFixed(drdx);
329         drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
330      }
331      {
332         GLfloat eMaj_dg, eBot_dg;
333         eMaj_dg = (GLint) vMax->color[1]
334                 - (GLint) vMin->color[1];
335	 eBot_dg = (GLint) vMid->color[1]
336                 - (GLint) vMin->color[1];
337         dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
338         fdgdx = SignedFloatToFixed(dgdx);
339         dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
340      }
341      {
342         GLfloat eMaj_db, eBot_db;
343         eMaj_db = (GLint) vMax->color[2]
344                 - (GLint) vMin->color[2];
345         eBot_db = (GLint) vMid->color[2]
346                 - (GLint) vMin->color[2];
347         dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
348         fdbdx = SignedFloatToFixed(dbdx);
349	 dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
350      }
351#endif
352#ifdef INTERP_SPEC
353      {
354         GLfloat eMaj_dsr, eBot_dsr;
355         eMaj_dsr = (GLint) vMax->specular[0]
356                  - (GLint) vMin->specular[0];
357         eBot_dsr = (GLint) vMid->specular[0]
358                  - (GLint) vMin->specular[0];
359         dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr);
360         fdsrdx = SignedFloatToFixed(dsrdx);
361         dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx);
362      }
363      {
364         GLfloat eMaj_dsg, eBot_dsg;
365         eMaj_dsg = (GLint) vMax->specular[1]
366                  - (GLint) vMin->specular[1];
367	 eBot_dsg = (GLint) vMid->specular[1]
368                  - (GLint) vMin->specular[1];
369         dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg);
370         fdsgdx = SignedFloatToFixed(dsgdx);
371         dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx);
372      }
373      {
374         GLfloat eMaj_dsb, eBot_dsb;
375         eMaj_dsb = (GLint) vMax->specular[2]
376                  - (GLint) vMin->specular[2];
377         eBot_dsb = (GLint) vMid->specular[2]
378                  - (GLint) vMin->specular[2];
379         dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb);
380         fdsbdx = SignedFloatToFixed(dsbdx);
381	 dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx);
382      }
383#endif
384#ifdef INTERP_ALPHA
385      {
386         GLfloat eMaj_da, eBot_da;
387         eMaj_da = (GLint) vMax->color[3]
388                 - (GLint) vMin->color[3];
389         eBot_da = (GLint) vMid->color[3]
390                 - (GLint) vMin->color[3];
391         dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
392         fdadx = SignedFloatToFixed(dadx);
393         dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
394      }
395#endif
396#ifdef INTERP_INDEX
397      {
398         GLfloat eMaj_di, eBot_di;
399         eMaj_di = (GLint) vMax->index
400                 - (GLint) vMin->index;
401         eBot_di = (GLint) vMid->index
402                 - (GLint) vMin->index;
403         didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di);
404         fdidx = SignedFloatToFixed(didx);
405         didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx);
406      }
407#endif
408#ifdef INTERP_INT_TEX
409      {
410         GLfloat eMaj_ds, eBot_ds;
411         eMaj_ds = (vMax->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE;
412         eBot_ds = (vMid->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE;
413         dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
414         fdsdx = SignedFloatToFixed(dsdx);
415         dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
416      }
417      {
418         GLfloat eMaj_dt, eBot_dt;
419         eMaj_dt = (vMax->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE;
420         eBot_dt = (vMid->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE;
421         dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
422         fdtdx = SignedFloatToFixed(dtdx);
423         dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
424      }
425
426#endif
427#ifdef INTERP_TEX
428      {
429         GLfloat wMax = vMax->win[3];
430         GLfloat wMin = vMin->win[3];
431         GLfloat wMid = vMid->win[3];
432         GLfloat eMaj_ds, eBot_ds;
433         GLfloat eMaj_dt, eBot_dt;
434         GLfloat eMaj_du, eBot_du;
435         GLfloat eMaj_dv, eBot_dv;
436
437         eMaj_ds = vMax->texcoord[0][0] * wMax - vMin->texcoord[0][0] * wMin;
438         eBot_ds = vMid->texcoord[0][0] * wMid - vMin->texcoord[0][0] * wMin;
439         dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
440         dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
441
442	 eMaj_dt = vMax->texcoord[0][1] * wMax - vMin->texcoord[0][1] * wMin;
443	 eBot_dt = vMid->texcoord[0][1] * wMid - vMin->texcoord[0][1] * wMin;
444	 dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
445	 dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
446
447	 eMaj_du = vMax->texcoord[0][2] * wMax - vMin->texcoord[0][2] * wMin;
448	 eBot_du = vMid->texcoord[0][2] * wMid - vMin->texcoord[0][2] * wMin;
449	 dudx = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
450	 dudy = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
451
452
453	 eMaj_dv = vMax->texcoord[0][3] * wMax - vMin->texcoord[0][3] * wMin;
454	 eBot_dv = vMid->texcoord[0][3] * wMid - vMin->texcoord[0][3] * wMin;
455	 dvdx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
456	 dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
457      }
458#endif
459#ifdef INTERP_MULTITEX
460      {
461         GLfloat wMax = vMax->win[3];
462         GLfloat wMin = vMin->win[3];
463         GLfloat wMid = vMid->win[3];
464         GLuint u;
465         for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
466            if (ctx->Texture.Unit[u]._ReallyEnabled) {
467               GLfloat eMaj_ds, eBot_ds;
468               GLfloat eMaj_dt, eBot_dt;
469               GLfloat eMaj_du, eBot_du;
470               GLfloat eMaj_dv, eBot_dv;
471               eMaj_ds = vMax->texcoord[u][0] * wMax
472                       - vMin->texcoord[u][0] * wMin;
473               eBot_ds = vMid->texcoord[u][0] * wMid
474                       - vMin->texcoord[u][0] * wMin;
475               dsdx[u] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
476               dsdy[u] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
477
478	       eMaj_dt = vMax->texcoord[u][1] * wMax
479		       - vMin->texcoord[u][1] * wMin;
480	       eBot_dt = vMid->texcoord[u][1] * wMid
481		       - vMin->texcoord[u][1] * wMin;
482	       dtdx[u] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
483	       dtdy[u] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
484
485	       eMaj_du = vMax->texcoord[u][2] * wMax
486                       - vMin->texcoord[u][2] * wMin;
487	       eBot_du = vMid->texcoord[u][2] * wMid
488                       - vMin->texcoord[u][2] * wMin;
489	       dudx[u] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
490	       dudy[u] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
491
492	       eMaj_dv = vMax->texcoord[u][3] * wMax
493                       - vMin->texcoord[u][3] * wMin;
494	       eBot_dv = vMid->texcoord[u][3] * wMid
495                       - vMin->texcoord[u][3] * wMin;
496	       dvdx[u] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
497	       dvdy[u] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
498            }
499         }
500      }
501#endif
502
503      /*
504       * We always sample at pixel centers.  However, we avoid
505       * explicit half-pixel offsets in this code by incorporating
506       * the proper offset in each of x and y during the
507       * transformation to window coordinates.
508       *
509       * We also apply the usual rasterization rules to prevent
510       * cracks and overlaps.  A pixel is considered inside a
511       * subtriangle if it meets all of four conditions: it is on or
512       * to the right of the left edge, strictly to the left of the
513       * right edge, on or below the top edge, and strictly above
514       * the bottom edge.  (Some edges may be degenerate.)
515       *
516       * The following discussion assumes left-to-right scanning
517       * (that is, the major edge is on the left); the right-to-left
518       * case is a straightforward variation.
519       *
520       * We start by finding the half-integral y coordinate that is
521       * at or below the top of the triangle.  This gives us the
522       * first scan line that could possibly contain pixels that are
523       * inside the triangle.
524       *
525       * Next we creep down the major edge until we reach that y,
526       * and compute the corresponding x coordinate on the edge.
527       * Then we find the half-integral x that lies on or just
528       * inside the edge.  This is the first pixel that might lie in
529       * the interior of the triangle.  (We won't know for sure
530       * until we check the other edges.)
531       *
532       * As we rasterize the triangle, we'll step down the major
533       * edge.  For each step in y, we'll move an integer number
534       * of steps in x.  There are two possible x step sizes, which
535       * we'll call the ``inner'' step (guaranteed to land on the
536       * edge or inside it) and the ``outer'' step (guaranteed to
537       * land on the edge or outside it).  The inner and outer steps
538       * differ by one.  During rasterization we maintain an error
539       * term that indicates our distance from the true edge, and
540       * select either the inner step or the outer step, whichever
541       * gets us to the first pixel that falls inside the triangle.
542       *
543       * All parameters (z, red, etc.) as well as the buffer
544       * addresses for color and z have inner and outer step values,
545       * so that we can increment them appropriately.  This method
546       * eliminates the need to adjust parameters by creeping a
547       * sub-pixel amount into the triangle at each scanline.
548       */
549
550      {
551         int subTriangle;
552         GLfixed fx, fxLeftEdge, fxRightEdge, fdxLeftEdge, fdxRightEdge;
553         GLfixed fdxOuter;
554         int idxOuter;
555         float dxOuter;
556         GLfixed fError, fdError;
557         float adjx, adjy;
558         GLfixed fy;
559         int iy;
560#ifdef PIXEL_ADDRESS
561         PIXEL_TYPE *pRow;
562         int dPRowOuter, dPRowInner;  /* offset in bytes */
563#endif
564#ifdef INTERP_Z
565#  ifdef DEPTH_TYPE
566         DEPTH_TYPE *zRow;
567         int dZRowOuter, dZRowInner;  /* offset in bytes */
568#  endif
569         GLfixed fz, fdzOuter, fdzInner;
570         GLfixed ffog, fdfogOuter, fdfogInner;
571#endif
572#ifdef INTERP_RGB
573         GLfixed fr, fdrOuter, fdrInner;
574         GLfixed fg, fdgOuter, fdgInner;
575         GLfixed fb, fdbOuter, fdbInner;
576#endif
577#ifdef INTERP_SPEC
578         GLfixed fsr, fdsrOuter, fdsrInner;
579         GLfixed fsg, fdsgOuter, fdsgInner;
580         GLfixed fsb, fdsbOuter, fdsbInner;
581#endif
582#ifdef INTERP_ALPHA
583         GLfixed fa, fdaOuter, fdaInner;
584#endif
585#ifdef INTERP_INDEX
586         GLfixed fi, fdiOuter, fdiInner;
587#endif
588#ifdef INTERP_INT_TEX
589         GLfixed fs, fdsOuter, fdsInner;
590         GLfixed ft, fdtOuter, fdtInner;
591#endif
592#ifdef INTERP_TEX
593         GLfloat sLeft, dsOuter, dsInner;
594         GLfloat tLeft, dtOuter, dtInner;
595         GLfloat uLeft, duOuter, duInner;
596         GLfloat vLeft, dvOuter, dvInner;
597#endif
598#ifdef INTERP_MULTITEX
599         GLfloat sLeft[MAX_TEXTURE_UNITS];
600         GLfloat tLeft[MAX_TEXTURE_UNITS];
601         GLfloat uLeft[MAX_TEXTURE_UNITS];
602         GLfloat vLeft[MAX_TEXTURE_UNITS];
603         GLfloat dsOuter[MAX_TEXTURE_UNITS], dsInner[MAX_TEXTURE_UNITS];
604         GLfloat dtOuter[MAX_TEXTURE_UNITS], dtInner[MAX_TEXTURE_UNITS];
605         GLfloat duOuter[MAX_TEXTURE_UNITS], duInner[MAX_TEXTURE_UNITS];
606         GLfloat dvOuter[MAX_TEXTURE_UNITS], dvInner[MAX_TEXTURE_UNITS];
607#endif
608
609         for (subTriangle=0; subTriangle<=1; subTriangle++) {
610            EdgeT *eLeft, *eRight;
611            int setupLeft, setupRight;
612            int lines;
613
614            if (subTriangle==0) {
615               /* bottom half */
616               if (ltor) {
617                  eLeft = &eMaj;
618                  eRight = &eBot;
619                  lines = eRight->lines;
620                  setupLeft = 1;
621                  setupRight = 1;
622               }
623               else {
624                  eLeft = &eBot;
625                  eRight = &eMaj;
626                  lines = eLeft->lines;
627                  setupLeft = 1;
628                  setupRight = 1;
629               }
630            }
631            else {
632               /* top half */
633               if (ltor) {
634                  eLeft = &eMaj;
635                  eRight = &eTop;
636                  lines = eRight->lines;
637                  setupLeft = 0;
638                  setupRight = 1;
639               }
640               else {
641                  eLeft = &eTop;
642                  eRight = &eMaj;
643                  lines = eLeft->lines;
644                  setupLeft = 1;
645                  setupRight = 0;
646               }
647               if (lines == 0)
648                  return;
649            }
650
651            if (setupLeft && eLeft->lines > 0) {
652               const SWvertex *vLower;
653               GLfixed fsx = eLeft->fsx;
654               fx = FixedCeil(fsx);
655               fError = fx - fsx - FIXED_ONE;
656               fxLeftEdge = fsx - FIXED_EPSILON;
657               fdxLeftEdge = eLeft->fdxdy;
658               fdxOuter = FixedFloor(fdxLeftEdge - FIXED_EPSILON);
659               fdError = fdxOuter - fdxLeftEdge + FIXED_ONE;
660               idxOuter = FixedToInt(fdxOuter);
661               dxOuter = (float) idxOuter;
662               (void) dxOuter;
663
664               fy = eLeft->fsy;
665               iy = FixedToInt(fy);
666
667               adjx = (float)(fx - eLeft->fx0);  /* SCALED! */
668               adjy = eLeft->adjy;		 /* SCALED! */
669               (void) adjx;  /* silence compiler warnings */
670               (void) adjy;  /* silence compiler warnings */
671
672               vLower = eLeft->v0;
673               (void) vLower;  /* silence compiler warnings */
674
675#ifdef PIXEL_ADDRESS
676               {
677                  pRow = PIXEL_ADDRESS( FixedToInt(fxLeftEdge), iy );
678                  dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE);
679                  /* negative because Y=0 at bottom and increases upward */
680               }
681#endif
682               /*
683                * Now we need the set of parameter (z, color, etc.) values at
684                * the point (fx, fy).  This gives us properly-sampled parameter
685                * values that we can step from pixel to pixel.  Furthermore,
686                * although we might have intermediate results that overflow
687                * the normal parameter range when we step temporarily outside
688                * the triangle, we shouldn't overflow or underflow for any
689                * pixel that's actually inside the triangle.
690                */
691
692#ifdef INTERP_Z
693               {
694                  GLfloat z0 = vLower->win[2];
695                  if (depthBits <= 16) {
696                     /* interpolate fixed-pt values */
697                     GLfloat tmp = (z0 * FIXED_SCALE +
698                                    dzdx * adjx + dzdy * adjy) + FIXED_HALF;
699                     if (tmp < MAX_GLUINT / 2)
700                        fz = (GLfixed) tmp;
701                     else
702                        fz = MAX_GLUINT / 2;
703                     fdzOuter = SignedFloatToFixed(dzdy + dxOuter * dzdx);
704                  }
705                  else {
706                     /* interpolate depth values exactly */
707                     fz = (GLint) (z0 + dzdx*FixedToFloat(adjx) + dzdy*FixedToFloat(adjy));
708                     fdzOuter = (GLint) (dzdy + dxOuter * dzdx);
709                  }
710#  ifdef DEPTH_TYPE
711                  zRow = (DEPTH_TYPE *) _mesa_zbuffer_address(ctx, FixedToInt(fxLeftEdge), iy);
712                  dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE);
713#  endif
714               }
715	       {
716		  ffog = FloatToFixed(vLower->fog) * 256 + dfogdx * adjx + dfogdy * adjy + FIXED_HALF;
717		  fdfogOuter = SignedFloatToFixed(dfogdy + dxOuter * dfogdx);
718	       }
719#endif
720#ifdef INTERP_RGB
721               fr = (GLfixed)(IntToFixed(vLower->color[0])
722                              + drdx * adjx + drdy * adjy) + FIXED_HALF;
723               fdrOuter = SignedFloatToFixed(drdy + dxOuter * drdx);
724
725               fg = (GLfixed)(IntToFixed(vLower->color[1])
726                              + dgdx * adjx + dgdy * adjy) + FIXED_HALF;
727               fdgOuter = SignedFloatToFixed(dgdy + dxOuter * dgdx);
728
729               fb = (GLfixed)(IntToFixed(vLower->color[2])
730                              + dbdx * adjx + dbdy * adjy) + FIXED_HALF;
731               fdbOuter = SignedFloatToFixed(dbdy + dxOuter * dbdx);
732#endif
733#ifdef INTERP_SPEC
734               fsr = (GLfixed)(IntToFixed(vLower->specular[0])
735                               + dsrdx * adjx + dsrdy * adjy) + FIXED_HALF;
736               fdsrOuter = SignedFloatToFixed(dsrdy + dxOuter * dsrdx);
737
738               fsg = (GLfixed)(IntToFixed(vLower->specular[1])
739                               + dsgdx * adjx + dsgdy * adjy) + FIXED_HALF;
740               fdsgOuter = SignedFloatToFixed(dsgdy + dxOuter * dsgdx);
741
742               fsb = (GLfixed)(IntToFixed(vLower->specular[2])
743                               + dsbdx * adjx + dsbdy * adjy) + FIXED_HALF;
744               fdsbOuter = SignedFloatToFixed(dsbdy + dxOuter * dsbdx);
745#endif
746#ifdef INTERP_ALPHA
747               fa = (GLfixed)(IntToFixed(vLower->color[3])
748                              + dadx * adjx + dady * adjy) + FIXED_HALF;
749               fdaOuter = SignedFloatToFixed(dady + dxOuter * dadx);
750#endif
751#ifdef INTERP_INDEX
752               fi = (GLfixed)(vLower->index * FIXED_SCALE
753                              + didx * adjx + didy * adjy) + FIXED_HALF;
754               fdiOuter = SignedFloatToFixed(didy + dxOuter * didx);
755#endif
756#ifdef INTERP_INT_TEX
757               {
758                  GLfloat s0, t0;
759                  s0 = vLower->texcoord[0][0] * S_SCALE;
760                  fs = (GLfixed)(s0 * FIXED_SCALE + dsdx * adjx + dsdy * adjy) + FIXED_HALF;
761                  fdsOuter = SignedFloatToFixed(dsdy + dxOuter * dsdx);
762
763		  t0 = vLower->texcoord[0][1] * T_SCALE;
764		  ft = (GLfixed)(t0 * FIXED_SCALE + dtdx * adjx + dtdy * adjy) + FIXED_HALF;
765		  fdtOuter = SignedFloatToFixed(dtdy + dxOuter * dtdx);
766	       }
767#endif
768#ifdef INTERP_TEX
769               {
770                  GLfloat invW = vLower->win[3];
771                  GLfloat s0, t0, u0, v0;
772                  s0 = vLower->texcoord[0][0] * invW;
773                  sLeft = s0 + (dsdx * adjx + dsdy * adjy) * (1.0F/FIXED_SCALE);
774                  dsOuter = dsdy + dxOuter * dsdx;
775		  t0 = vLower->texcoord[0][1] * invW;
776		  tLeft = t0 + (dtdx * adjx + dtdy * adjy) * (1.0F/FIXED_SCALE);
777		  dtOuter = dtdy + dxOuter * dtdx;
778		  u0 = vLower->texcoord[0][2] * invW;
779		  uLeft = u0 + (dudx * adjx + dudy * adjy) * (1.0F/FIXED_SCALE);
780		  duOuter = dudy + dxOuter * dudx;
781		  v0 = vLower->texcoord[0][3] * invW;
782		  vLeft = v0 + (dvdx * adjx + dvdy * adjy) * (1.0F/FIXED_SCALE);
783		  dvOuter = dvdy + dxOuter * dvdx;
784               }
785#endif
786#ifdef INTERP_MULTITEX
787               {
788                  GLuint u;
789                  for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
790                     if (ctx->Texture.Unit[u]._ReallyEnabled) {
791                        GLfloat invW = vLower->win[3];
792                        GLfloat s0, t0, u0, v0;
793                        s0 = vLower->texcoord[u][0] * invW;
794                        sLeft[u] = s0 + (dsdx[u] * adjx + dsdy[u] * adjy) * (1.0F/FIXED_SCALE);
795                        dsOuter[u] = dsdy[u] + dxOuter * dsdx[u];
796			t0 = vLower->texcoord[u][1] * invW;
797			tLeft[u] = t0 + (dtdx[u] * adjx + dtdy[u] * adjy) * (1.0F/FIXED_SCALE);
798			dtOuter[u] = dtdy[u] + dxOuter * dtdx[u];
799			u0 = vLower->texcoord[u][2] * invW;
800			uLeft[u] = u0 + (dudx[u] * adjx + dudy[u] * adjy) * (1.0F/FIXED_SCALE);
801			duOuter[u] = dudy[u] + dxOuter * dudx[u];
802			v0 = vLower->texcoord[u][3] * invW;
803                        vLeft[u] = v0 + (dvdx[u] * adjx + dvdy[u] * adjy) * (1.0F/FIXED_SCALE);
804                        dvOuter[u] = dvdy[u] + dxOuter * dvdx[u];
805                     }
806                  }
807               }
808#endif
809
810            } /*if setupLeft*/
811
812
813            if (setupRight && eRight->lines>0) {
814               fxRightEdge = eRight->fsx - FIXED_EPSILON;
815               fdxRightEdge = eRight->fdxdy;
816            }
817
818            if (lines==0) {
819               continue;
820            }
821
822
823            /* Rasterize setup */
824#ifdef PIXEL_ADDRESS
825            dPRowInner = dPRowOuter + sizeof(PIXEL_TYPE);
826#endif
827#ifdef INTERP_Z
828#  ifdef DEPTH_TYPE
829            dZRowInner = dZRowOuter + sizeof(DEPTH_TYPE);
830#  endif
831            fdzInner = fdzOuter + fdzdx;
832            fdfogInner = fdfogOuter + fdfogdx;
833#endif
834#ifdef INTERP_RGB
835            fdrInner = fdrOuter + fdrdx;
836            fdgInner = fdgOuter + fdgdx;
837            fdbInner = fdbOuter + fdbdx;
838#endif
839#ifdef INTERP_SPEC
840            fdsrInner = fdsrOuter + fdsrdx;
841            fdsgInner = fdsgOuter + fdsgdx;
842            fdsbInner = fdsbOuter + fdsbdx;
843#endif
844#ifdef INTERP_ALPHA
845            fdaInner = fdaOuter + fdadx;
846#endif
847#ifdef INTERP_INDEX
848            fdiInner = fdiOuter + fdidx;
849#endif
850#ifdef INTERP_INT_TEX
851            fdsInner = fdsOuter + fdsdx;
852            fdtInner = fdtOuter + fdtdx;
853#endif
854#ifdef INTERP_TEX
855	    dsInner = dsOuter + dsdx;
856	    dtInner = dtOuter + dtdx;
857	    duInner = duOuter + dudx;
858	    dvInner = dvOuter + dvdx;
859#endif
860#ifdef INTERP_MULTITEX
861            {
862               GLuint u;
863               for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
864                  if (ctx->Texture.Unit[u]._ReallyEnabled) {
865                     dsInner[u] = dsOuter[u] + dsdx[u];
866                     dtInner[u] = dtOuter[u] + dtdx[u];
867                     duInner[u] = duOuter[u] + dudx[u];
868                     dvInner[u] = dvOuter[u] + dvdx[u];
869                  }
870               }
871            }
872#endif
873
874            while (lines>0) {
875               /* initialize the span interpolants to the leftmost value */
876               /* ff = fixed-pt fragment */
877               GLint left = FixedToInt(fxLeftEdge);
878               GLint right = FixedToInt(fxRightEdge);
879#ifdef INTERP_Z
880               GLfixed ffz = fz;
881               GLfixed fffog = ffog;
882#endif
883#ifdef INTERP_RGB
884               GLfixed ffr = fr,  ffg = fg,  ffb = fb;
885#endif
886#ifdef INTERP_SPEC
887               GLfixed ffsr = fsr,  ffsg = fsg,  ffsb = fsb;
888#endif
889#ifdef INTERP_ALPHA
890               GLfixed ffa = fa;
891#endif
892#ifdef INTERP_INDEX
893               GLfixed ffi = fi;
894#endif
895#ifdef INTERP_INT_TEX
896               GLfixed ffs = fs,  fft = ft;
897#endif
898#ifdef INTERP_TEX
899               GLfloat ss = sLeft, tt = tLeft, uu = uLeft, vv = vLeft;
900#endif
901#ifdef INTERP_MULTITEX
902               GLfloat ss[MAX_TEXTURE_UNITS];
903               GLfloat tt[MAX_TEXTURE_UNITS];
904               GLfloat uu[MAX_TEXTURE_UNITS];
905               GLfloat vv[MAX_TEXTURE_UNITS];
906               {
907                  GLuint u;
908                  for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
909                     if (ctx->Texture.Unit[u]._ReallyEnabled) {
910                        ss[u] = sLeft[u];
911                        tt[u] = tLeft[u];
912                        uu[u] = uLeft[u];
913                        vv[u] = vLeft[u];
914                     }
915                  }
916               }
917#endif
918
919#ifdef INTERP_RGB
920               {
921                  /* need this to accomodate round-off errors */
922                  GLfixed ffrend = ffr+(right-left-1)*fdrdx;
923                  GLfixed ffgend = ffg+(right-left-1)*fdgdx;
924                  GLfixed ffbend = ffb+(right-left-1)*fdbdx;
925                  if (ffrend<0) ffr -= ffrend;
926                  if (ffgend<0) ffg -= ffgend;
927                  if (ffbend<0) ffb -= ffbend;
928                  if (ffr<0) ffr = 0;
929                  if (ffg<0) ffg = 0;
930                  if (ffb<0) ffb = 0;
931               }
932#endif
933#ifdef INTERP_SPEC
934               {
935                  /* need this to accomodate round-off errors */
936                  GLfixed ffsrend = ffsr+(right-left-1)*fdsrdx;
937                  GLfixed ffsgend = ffsg+(right-left-1)*fdsgdx;
938                  GLfixed ffsbend = ffsb+(right-left-1)*fdsbdx;
939                  if (ffsrend<0) ffsr -= ffsrend;
940                  if (ffsgend<0) ffsg -= ffsgend;
941                  if (ffsbend<0) ffsb -= ffsbend;
942                  if (ffsr<0) ffsr = 0;
943                  if (ffsg<0) ffsg = 0;
944                  if (ffsb<0) ffsb = 0;
945               }
946#endif
947#ifdef INTERP_ALPHA
948               {
949                  GLfixed ffaend = ffa+(right-left-1)*fdadx;
950                  if (ffaend<0) ffa -= ffaend;
951                  if (ffa<0) ffa = 0;
952               }
953#endif
954#ifdef INTERP_INDEX
955               if (ffi<0) ffi = 0;
956#endif
957
958               INNER_LOOP( left, right, iy );
959
960               /*
961                * Advance to the next scan line.  Compute the
962                * new edge coordinates, and adjust the
963                * pixel-center x coordinate so that it stays
964                * on or inside the major edge.
965                */
966               iy++;
967               lines--;
968
969               fxLeftEdge += fdxLeftEdge;
970               fxRightEdge += fdxRightEdge;
971
972
973               fError += fdError;
974               if (fError >= 0) {
975                  fError -= FIXED_ONE;
976#ifdef PIXEL_ADDRESS
977                  pRow = (PIXEL_TYPE *) ((GLubyte*)pRow + dPRowOuter);
978#endif
979#ifdef INTERP_Z
980#  ifdef DEPTH_TYPE
981                  zRow = (DEPTH_TYPE *) ((GLubyte*)zRow + dZRowOuter);
982#  endif
983                  fz += fdzOuter;
984                  ffog += fdfogOuter;
985#endif
986#ifdef INTERP_RGB
987                  fr += fdrOuter;   fg += fdgOuter;   fb += fdbOuter;
988#endif
989#ifdef INTERP_SPEC
990                  fsr += fdsrOuter;   fsg += fdsgOuter;   fsb += fdsbOuter;
991#endif
992#ifdef INTERP_ALPHA
993                  fa += fdaOuter;
994#endif
995#ifdef INTERP_INDEX
996                  fi += fdiOuter;
997#endif
998#ifdef INTERP_INT_TEX
999                  fs += fdsOuter;   ft += fdtOuter;
1000#endif
1001#ifdef INTERP_TEX
1002		  sLeft += dsOuter;
1003		  tLeft += dtOuter;
1004		  uLeft += duOuter;
1005		  vLeft += dvOuter;
1006#endif
1007#ifdef INTERP_MULTITEX
1008                  {
1009                     GLuint u;
1010                     for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
1011                        if (ctx->Texture.Unit[u]._ReallyEnabled) {
1012                           sLeft[u] += dsOuter[u];
1013                           tLeft[u] += dtOuter[u];
1014                           uLeft[u] += duOuter[u];
1015                           vLeft[u] += dvOuter[u];
1016                        }
1017                     }
1018                  }
1019#endif
1020               }
1021               else {
1022#ifdef PIXEL_ADDRESS
1023                  pRow = (PIXEL_TYPE *) ((GLubyte*)pRow + dPRowInner);
1024#endif
1025#ifdef INTERP_Z
1026#  ifdef DEPTH_TYPE
1027                  zRow = (DEPTH_TYPE *) ((GLubyte*)zRow + dZRowInner);
1028#  endif
1029                  fz += fdzInner;
1030                  ffog += fdfogInner;
1031#endif
1032#ifdef INTERP_RGB
1033                  fr += fdrInner;   fg += fdgInner;   fb += fdbInner;
1034#endif
1035#ifdef INTERP_SPEC
1036                  fsr += fdsrInner;   fsg += fdsgInner;   fsb += fdsbInner;
1037#endif
1038#ifdef INTERP_ALPHA
1039                  fa += fdaInner;
1040#endif
1041#ifdef INTERP_INDEX
1042                  fi += fdiInner;
1043#endif
1044#ifdef INTERP_INT_TEX
1045                  fs += fdsInner;   ft += fdtInner;
1046#endif
1047#ifdef INTERP_TEX
1048		  sLeft += dsInner;
1049		  tLeft += dtInner;
1050		  uLeft += duInner;
1051		  vLeft += dvInner;
1052#endif
1053#ifdef INTERP_MULTITEX
1054                  {
1055                     GLuint u;
1056                     for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
1057                        if (ctx->Texture.Unit[u]._ReallyEnabled) {
1058                           sLeft[u] += dsInner[u];
1059                           tLeft[u] += dtInner[u];
1060                           uLeft[u] += duInner[u];
1061                           vLeft[u] += dvInner[u];
1062                        }
1063                     }
1064                  }
1065#endif
1066               }
1067            } /*while lines>0*/
1068
1069         } /* for subTriangle */
1070
1071      }
1072   }
1073}
1074
1075#undef SETUP_CODE
1076#undef INNER_LOOP
1077
1078#undef PIXEL_TYPE
1079#undef BYTES_PER_ROW
1080#undef PIXEL_ADDRESS
1081
1082#undef INTERP_Z
1083#undef INTERP_RGB
1084#undef INTERP_SPEC
1085#undef INTERP_ALPHA
1086#undef INTERP_INDEX
1087#undef INTERP_INT_TEX
1088#undef INTERP_TEX
1089#undef INTERP_MULTITEX
1090
1091#undef S_SCALE
1092#undef T_SCALE
1093
1094#undef FixedToDepth
1095
1096#undef DO_OCCLUSION_TEST
1097