s_tritemp.h revision 54e92e8420a028f07b0971ee8aa93be9b4214579
154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul/* $Id: s_tritemp.h,v 1.47 2003/03/16 22:02:40 brianp Exp $ */
2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
3e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
4e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library
5cdf2da368d180205df3573697b51b8764048ad6eBrian Paul * Version:  5.1
622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
72e5c1dce4e6fc27a6968ac91986564200bc5f3bdBrian Paul * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"),
11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation
12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the
14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions:
1522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
16e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included
17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software.
1822144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
26c5a76cbed41b5816d2f5284f90c70364b062aea4Brian Paul/* $XFree86: xc/extras/Mesa/src/swrast/s_tritemp.h,v 1.2 2002/02/27 21:07:54 tsi Exp $ */
27e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
28e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
29e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Triangle Rasterizer Template
30e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *
31e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * This file is #include'd to generate custom triangle rasterizers.
32e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *
33e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The following macros may be defined to indicate what auxillary information
34e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * must be interplated across the triangle:
35e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *    INTERP_Z        - if defined, interpolate Z values
3695e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul *    INTERP_FOG      - if defined, interpolate fog values
37e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *    INTERP_RGB      - if defined, interpolate RGB values
38d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul *    INTERP_ALPHA    - if defined, interpolate Alpha values (req's INTERP_RGB)
3995e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul *    INTERP_SPEC     - if defined, interpolate specular RGB values
40e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *    INTERP_INDEX    - if defined, interpolate color index values
41e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
42e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *                         (fast, simple 2-D texture mapping)
43e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *    INTERP_TEX      - if defined, interpolate set 0 float STRQ texcoords
44e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *                         NOTE:  OpenGL STRQ = Mesa STUV (R was taken for red)
45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *    INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *
47e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * When one can directly address pixels in the color buffer the following
48e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * macros can be defined and used to compute pixel addresses during
49e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * rasterization (see pRow):
50e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
51e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *    BYTES_PER_ROW       - number of bytes per row in the color buffer
52e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
53e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *                          Y==0 at bottom of screen and increases upward.
54e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *
55e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Similarly, for direct depth buffer access, this type is used for depth
56e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * buffer addressing:
57e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *    DEPTH_TYPE          - either GLushort or GLuint
58e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *
59e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Optionally, one may provide one-time setup code per triangle:
60e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *    SETUP_CODE    - code which is to be executed once per triangle
6147cf442c1164b6b406117fccfb8b564602741ee3Brian Paul *    CLEANUP_CODE    - code to execute at end of triangle
6222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
63e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The following macro MUST be defined:
649bf68ad963ba92b5d1e725f965979042495a5313Brian Paul *    RENDER_SPAN(span) - code to write a span of pixels.
65e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *
66e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * This code was designed for the origin to be in the lower-left corner.
67e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *
68e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
69e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
70e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
7196385fa15569e25cd0977e678c0ff3bdab6ef316Brian Paul
7296385fa15569e25cd0977e678c0ff3bdab6ef316Brian Paul/*
73dec3ed69e21baa1113938132e344761f39320f5fBrian Paul * ColorTemp is used for intermediate color values.
7496385fa15569e25cd0977e678c0ff3bdab6ef316Brian Paul */
7596385fa15569e25cd0977e678c0ff3bdab6ef316Brian Paul#if CHAN_TYPE == GL_FLOAT
76dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#define ColorTemp GLfloat
77dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#else
78dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#define ColorTemp GLint  /* same as GLfixed */
7996385fa15569e25cd0977e678c0ff3bdab6ef316Brian Paul#endif
8096385fa15569e25cd0977e678c0ff3bdab6ef316Brian Paul
81a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul/*
82a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul * Either loop over all texture units, or just use unit zero.
83a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul */
84a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul#ifdef INTERP_MULTITEX
85a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul#define TEX_UNIT_LOOP(CODE)					\
86a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul   {								\
87a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul      GLuint u;							\
88a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {	\
89a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul         if (ctx->Texture.Unit[u]._ReallyEnabled) {		\
90a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            CODE						\
91a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul         }							\
92a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul      }								\
93a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul   }
94a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul#define INTERP_TEX
95a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul#elif defined(INTERP_TEX)
96a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul#define TEX_UNIT_LOOP(CODE)					\
97a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul   {								\
98a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul      const GLuint u = 0;					\
99a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul      CODE							\
100a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul   }
101a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul#endif
10296385fa15569e25cd0977e678c0ff3bdab6ef316Brian Paul
10396385fa15569e25cd0977e678c0ff3bdab6ef316Brian Paul
104cdf2da368d180205df3573697b51b8764048ad6eBrian Paulstatic void NAME(GLcontext *ctx, const SWvertex *v0,
105cdf2da368d180205df3573697b51b8764048ad6eBrian Paul                                 const SWvertex *v1,
106cdf2da368d180205df3573697b51b8764048ad6eBrian Paul                                 const SWvertex *v2 )
107e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
108e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   typedef struct {
109a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul        const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
110d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul        GLfloat dx;	/* X(v1) - X(v0) */
111d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul        GLfloat dy;	/* Y(v1) - Y(v0) */
112d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul        GLfixed fdxdy;	/* dx/dy in fixed-point */
113d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul        GLfixed fsx;	/* first sample point x coord */
114d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul        GLfixed fsy;
115d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul        GLfloat adjy;	/* adjust from v[0]->fy to fsy, scaled */
116d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul        GLint lines;	/* number of lines to be sampled on this edge */
117d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul        GLfixed fx0;	/* fixed pt X of lower endpoint */
118e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   } EdgeT;
119e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
120e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_Z
121b6bcae5698df88f7730d40004ce7ce0462e97a20Brian Paul   const GLint depthBits = ctx->Visual.depthBits;
122e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0;
123b6bcae5698df88f7730d40004ce7ce0462e97a20Brian Paul   const GLfloat maxDepth = ctx->DepthMaxF;
124e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define FixedToDepth(F)  ((F) >> fixedToDepthShift)
125e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
126e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   EdgeT eMaj, eTop, eBot;
127e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLfloat oneOverArea;
128a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul   const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
1291e1aac034c986a08248861363c0baa27dc2ae2d5Keith Whitwell   float bf = SWRAST_CONTEXT(ctx)->_backface_sign;
13010d343f407bddf011be3d2b79a6541815759785aBrian Paul   const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */
131a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
132e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
133a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul   struct sw_span span;
1349bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
135b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul   INIT_SPAN(span, GL_POLYGON, 0, 0, 0);
1362a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1379bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#ifdef INTERP_Z
1389bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   (void) fixedToDepthShift;
1399bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#endif
1409bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
1413ade8af7ffce434bb612df67f8e5a780885f991cBrian Paul   /*
1423ade8af7ffce434bb612df67f8e5a780885f991cBrian Paul   printf("%s()\n", __FUNCTION__);
1433ade8af7ffce434bb612df67f8e5a780885f991cBrian Paul   printf("  %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
1443ade8af7ffce434bb612df67f8e5a780885f991cBrian Paul   printf("  %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
1453ade8af7ffce434bb612df67f8e5a780885f991cBrian Paul   printf("  %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
1463ade8af7ffce434bb612df67f8e5a780885f991cBrian Paul   */
1473ade8af7ffce434bb612df67f8e5a780885f991cBrian Paul
148a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
149a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul    * And find the order of the 3 vertices along the Y axis.
150a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul    */
151e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   {
1521178ed817f835e2a9b1fdd33b32d39e2d6070cc8Brian Paul      const GLfixed fy0 = FloatToFixed(v0->win[1] - 0.5F) & snapMask;
1531178ed817f835e2a9b1fdd33b32d39e2d6070cc8Brian Paul      const GLfixed fy1 = FloatToFixed(v1->win[1] - 0.5F) & snapMask;
1541178ed817f835e2a9b1fdd33b32d39e2d6070cc8Brian Paul      const GLfixed fy2 = FloatToFixed(v2->win[1] - 0.5F) & snapMask;
155a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul
156a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul      if (fy0 <= fy1) {
157d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         if (fy1 <= fy2) {
158a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            /* y0 <= y1 <= y2 */
159d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul            vMin = v0;   vMid = v1;   vMax = v2;
160a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            vMin_fy = fy0;  vMid_fy = fy1;  vMax_fy = fy2;
161d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         }
162d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         else if (fy2 <= fy0) {
163a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            /* y2 <= y0 <= y1 */
164d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul            vMin = v2;   vMid = v0;   vMax = v1;
165a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            vMin_fy = fy2;  vMid_fy = fy0;  vMax_fy = fy1;
166d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         }
167d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         else {
168a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            /* y0 <= y2 <= y1 */
169d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul            vMin = v0;   vMid = v2;   vMax = v1;
170a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            vMin_fy = fy0;  vMid_fy = fy2;  vMax_fy = fy1;
171a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            bf = -bf;
172d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         }
173e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
174e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
175d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         if (fy0 <= fy2) {
176a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            /* y1 <= y0 <= y2 */
177d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul            vMin = v1;   vMid = v0;   vMax = v2;
178a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            vMin_fy = fy1;  vMid_fy = fy0;  vMax_fy = fy2;
179a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            bf = -bf;
180d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         }
181d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         else if (fy2 <= fy1) {
182a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            /* y2 <= y1 <= y0 */
183d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul            vMin = v2;   vMid = v1;   vMax = v0;
184a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            vMin_fy = fy2;  vMid_fy = fy1;  vMax_fy = fy0;
185a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            bf = -bf;
186d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         }
187d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         else {
188a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            /* y1 <= y2 <= y0 */
189d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul            vMin = v1;   vMid = v2;   vMax = v0;
190a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            vMin_fy = fy1;  vMid_fy = fy2;  vMax_fy = fy0;
191d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         }
192e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
193a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul
194a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul      /* fixed point X coords */
195a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul      vMin_fx = FloatToFixed(vMin->win[0] + 0.5F) & snapMask;
196a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul      vMid_fx = FloatToFixed(vMid->win[0] + 0.5F) & snapMask;
197a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul      vMax_fx = FloatToFixed(vMax->win[0] + 0.5F) & snapMask;
198e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
199e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
200e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* vertex/edge relationship */
201e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
202e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   eTop.v0 = vMid;   eTop.v1 = vMax;
203e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   eBot.v0 = vMin;   eBot.v1 = vMid;
204e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
205a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
206a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   eMaj.dx = FixedToFloat(vMax_fx - vMin_fx);
207a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   eMaj.dy = FixedToFloat(vMax_fy - vMin_fy);
208a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   eTop.dx = FixedToFloat(vMax_fx - vMid_fx);
209a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   eTop.dy = FixedToFloat(vMax_fy - vMid_fy);
210a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   eBot.dx = FixedToFloat(vMid_fx - vMin_fx);
211a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   eBot.dy = FixedToFloat(vMid_fy - vMin_fy);
212e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
213a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   /* compute area, oneOverArea and perform backface culling */
214e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   {
215e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
216e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
217e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* Do backface culling */
218e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (area * bf < 0.0)
219d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         return;
220e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
22110d343f407bddf011be3d2b79a6541815759785aBrian Paul      if (IS_INF_OR_NAN(area) || area == 0.0F)
222e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         return;
223e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
224ac3958ea1bf8f7b1648f9c1b2ffbe93ffd40b602Brian Paul      oneOverArea = 1.0F / area;
225e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
226e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
227e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifndef DO_OCCLUSION_TEST
228e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   ctx->OcclusionResult = GL_TRUE;
229e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
230be99e845bd7979fe46d38d9b294c1ba0a0aa95b8Brian Paul   span.facing = ctx->_Facing; /* for 2-sided stencil test */
231e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
232e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Edge setup.  For a triangle strip these could be reused... */
233e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   {
234e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      eMaj.fsy = FixedCeil(vMin_fy);
23526d729581fcf1991fbcc8320f64fa40d73170e95Brian Paul      eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy));
236e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (eMaj.lines > 0) {
237e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLfloat dxdy = eMaj.dx / eMaj.dy;
238e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         eMaj.fdxdy = SignedFloatToFixed(dxdy);
239e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
240e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         eMaj.fx0 = vMin_fx;
241e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy);
242e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
243e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
244e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         return;  /*CULLED*/
245e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
246e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
247e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      eTop.fsy = FixedCeil(vMid_fy);
24826d729581fcf1991fbcc8320f64fa40d73170e95Brian Paul      eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy));
249e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (eTop.lines > 0) {
250e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLfloat dxdy = eTop.dx / eTop.dy;
251e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         eTop.fdxdy = SignedFloatToFixed(dxdy);
252e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
253e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         eTop.fx0 = vMid_fx;
254e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy);
255e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
256e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
257e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      eBot.fsy = FixedCeil(vMin_fy);
25826d729581fcf1991fbcc8320f64fa40d73170e95Brian Paul      eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy));
259e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (eBot.lines > 0) {
260e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLfloat dxdy = eBot.dx / eBot.dy;
261e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         eBot.fdxdy = SignedFloatToFixed(dxdy);
262e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
263e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         eBot.fx0 = vMin_fx;
264e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy);
265e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
266e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
267e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
268e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /*
269e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * Conceptually, we view a triangle as two subtriangles
270e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * separated by a perfectly horizontal line.  The edge that is
271e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * intersected by this line is one with maximal absolute dy; we
272e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * call it a ``major'' edge.  The other two edges are the
273e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * ``top'' edge (for the upper subtriangle) and the ``bottom''
274e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * edge (for the lower subtriangle).  If either of these two
275e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * edges is horizontal or very close to horizontal, the
276e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * corresponding subtriangle might cover zero sample points;
277e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * we take care to handle such cases, for performance as well
278e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * as correctness.
279e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    *
280e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * By stepping rasterization parameters along the major edge,
281e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * we can avoid recomputing them at the discontinuity where
282e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * the top and bottom edges meet.  However, this forces us to
28322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes    * be able to scan both left-to-right and right-to-left.
284e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * Also, we must determine whether the major edge is at the
285e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * left or right side of the triangle.  We do this by
286e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * computing the magnitude of the cross-product of the major
287e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * and top edges.  Since this magnitude depends on the sine of
288e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * the angle between the two edges, its sign tells us whether
289e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * we turn to the left or to the right when travelling along
290e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * the major edge to the top edge, and from this we infer
291e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * whether the major edge is on the left or the right.
292e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    *
293e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * Serendipitously, this cross-product magnitude is also a
294e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * value we need to compute the iteration parameter
295e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * derivatives for the triangle, and it can be used to perform
296e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * backface culling because its sign tells us whether the
297e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * triangle is clockwise or counterclockwise.  In this code we
298e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * refer to it as ``area'' because it's also proportional to
299e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * the pixel area of the triangle.
300e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    */
301e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
302e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   {
303d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul      GLint scan_from_left_to_right;  /* true if scanning left-to-right */
304e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INDEX
3059bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      GLfloat didx, didy;
306e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
307e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
308e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /*
309e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * Execute user-supplied setup code
310e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       */
311e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef SETUP_CODE
312e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      SETUP_CODE
313e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
314e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
315d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul      scan_from_left_to_right = (oneOverArea < 0.0F);
316e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
3179bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
318e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* compute d?/dx and d?/dy derivatives */
319e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_Z
320a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul      span.interpMask |= SPAN_Z;
321e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      {
32254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         GLfloat eMaj_dz = vMax->win[2] - vMin->win[2];
32354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         GLfloat eBot_dz = vMid->win[2] - vMin->win[2];
32454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
32554e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         if (span.dzdx > maxDepth || span.dzdx < -maxDepth) {
326e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* probably a sliver triangle */
32754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul            span.dzdx = 0.0;
32854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul            span.dzdy = 0.0;
329e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
330e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else {
33154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul            span.dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
332e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
333e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (depthBits <= 16)
33454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul            span.zStep = SignedFloatToFixed(span.dzdx);
335e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else
33654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul            span.zStep = (GLint) span.dzdx;
33754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul      }
33854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#endif
33954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#ifdef INTERP_W
34054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul      {
34154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         const GLfloat eMaj_dw = vMax->win[3] - vMin->win[3];
34254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         const GLfloat eBot_dw = vMid->win[3] - vMin->win[3];
34354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dwdx = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw);
34454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dwdy = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx);
345e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
34695e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul#endif
34795e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul#ifdef INTERP_FOG
348a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul      span.interpMask |= SPAN_FOG;
349e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      {
3501b3528fe635242f782fbcdde3ba74b5b7359a362Brian Paul         const GLfloat eMaj_dfog = vMax->fog - vMin->fog;
3511b3528fe635242f782fbcdde3ba74b5b7359a362Brian Paul         const GLfloat eBot_dfog = vMid->fog - vMin->fog;
35254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dfogdx = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
35354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
35454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.fogStep = span.dfogdx;
355e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
356e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
357e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_RGB
358a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul      span.interpMask |= SPAN_RGBA;
359d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul      if (ctx->Light.ShadeModel == GL_SMOOTH) {
360dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eMaj_dr = (GLfloat) ((ColorTemp) vMax->color[RCOMP] - vMin->color[RCOMP]);
361dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eBot_dr = (GLfloat) ((ColorTemp) vMid->color[RCOMP] - vMin->color[RCOMP]);
362dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eMaj_dg = (GLfloat) ((ColorTemp) vMax->color[GCOMP] - vMin->color[GCOMP]);
363dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eBot_dg = (GLfloat) ((ColorTemp) vMid->color[GCOMP] - vMin->color[GCOMP]);
364dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eMaj_db = (GLfloat) ((ColorTemp) vMax->color[BCOMP] - vMin->color[BCOMP]);
365dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eBot_db = (GLfloat) ((ColorTemp) vMid->color[BCOMP] - vMin->color[BCOMP]);
366d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul#  ifdef INTERP_ALPHA
367dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eMaj_da = (GLfloat) ((ColorTemp) vMax->color[ACOMP] - vMin->color[ACOMP]);
368dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eBot_da = (GLfloat) ((ColorTemp) vMid->color[ACOMP] - vMin->color[ACOMP]);
369d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul#  endif
37054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
37154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
37254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
37354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
37454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
37554e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
376dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  if CHAN_TYPE == GL_FLOAT
37754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.redStep   = span.drdx;
37854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.greenStep = span.dgdx;
37954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.blueStep  = span.dbdx;
380dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  else
38154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.redStep   = SignedFloatToFixed(span.drdx);
38254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.greenStep = SignedFloatToFixed(span.dgdx);
38354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.blueStep  = SignedFloatToFixed(span.dbdx);
384dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  endif /* GL_FLOAT */
385d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul#  ifdef INTERP_ALPHA
38654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
38754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
388dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#    if CHAN_TYPE == GL_FLOAT
38954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.alphaStep = span.dadx;
390dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#    else
39154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.alphaStep = SignedFloatToFixed(span.dadx);
392dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#    endif /* GL_FLOAT */
393dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  endif /* INTERP_ALPHA */
394d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul      }
395d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul      else {
396d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul         ASSERT (ctx->Light.ShadeModel == GL_FLAT);
397a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul         span.interpMask |= SPAN_FLAT;
39854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.drdx = span.drdy = span.redStep   = 0;
39954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dgdx = span.dgdy = span.greenStep = 0;
40054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dbdx = span.dbdy = span.blueStep  = 0;
401d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul#  ifdef INTERP_ALPHA
40254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dadx = span.dady = span.alphaStep = 0;
403d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul#  endif
4049bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      }
405dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#endif /* INTERP_RGB */
406e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_SPEC
407a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul      span.interpMask |= SPAN_SPEC;
408d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul      if (ctx->Light.ShadeModel == GL_SMOOTH) {
409dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eMaj_dsr = (GLfloat) ((ColorTemp) vMax->specular[RCOMP] - vMin->specular[RCOMP]);
410dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eBot_dsr = (GLfloat) ((ColorTemp) vMid->specular[RCOMP] - vMin->specular[RCOMP]);
411dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eMaj_dsg = (GLfloat) ((ColorTemp) vMax->specular[GCOMP] - vMin->specular[GCOMP]);
412dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eBot_dsg = (GLfloat) ((ColorTemp) vMid->specular[GCOMP] - vMin->specular[GCOMP]);
413dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eMaj_dsb = (GLfloat) ((ColorTemp) vMax->specular[BCOMP] - vMin->specular[BCOMP]);
414dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eBot_dsb = (GLfloat) ((ColorTemp) vMid->specular[BCOMP] - vMin->specular[BCOMP]);
41554e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr);
41654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx);
41754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg);
41854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx);
41954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb);
42054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx);
421dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  if CHAN_TYPE == GL_FLOAT
42254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.specRedStep   = span.dsrdx;
42354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.specGreenStep = span.dsgdx;
42454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.specBlueStep  = span.dsbdx;
425dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  else
42654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.specRedStep   = SignedFloatToFixed(span.dsrdx);
42754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.specGreenStep = SignedFloatToFixed(span.dsgdx);
42854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.specBlueStep  = SignedFloatToFixed(span.dsbdx);
429dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  endif
430e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
431d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul      else {
43254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dsrdx = span.dsrdy = span.specRedStep   = 0;
43354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dsgdx = span.dsgdy = span.specGreenStep = 0;
43454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         span.dsbdx = span.dsbdy = span.specBlueStep  = 0;
435d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul      }
436dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#endif /* INTERP_SPEC */
437e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INDEX
438a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul      span.interpMask |= SPAN_INDEX;
439d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul      if (ctx->Light.ShadeModel == GL_SMOOTH) {
440dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eMaj_di = (GLfloat) ((GLint) vMax->index - (GLint) vMin->index);
441dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eBot_di = (GLfloat) ((GLint) vMid->index - (GLint) vMin->index);
442e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di);
443e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx);
444dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         span.indexStep = SignedFloatToFixed(didx);
445e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
446d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul      else {
447a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul         span.interpMask |= SPAN_FLAT;
448d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul         didx = didy = 0.0F;
449a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul         span.indexStep = 0;
450d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul      }
451e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
452e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INT_TEX
453a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul      span.interpMask |= SPAN_INT_TEXTURE;
454e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      {
455dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eMaj_ds = (vMax->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE;
456dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eBot_ds = (vMid->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE;
457dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eMaj_dt = (vMax->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE;
458dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         GLfloat eBot_dt = (vMid->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE;
459dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         span.texStepX[0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
460dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         span.texStepY[0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
461dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         span.texStepX[0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
462dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         span.texStepY[0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
463dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         span.intTexStep[0] = SignedFloatToFixed(span.texStepX[0][0]);
464dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         span.intTexStep[1] = SignedFloatToFixed(span.texStepX[0][1]);
465e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
466e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
467e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_TEX
468a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul      span.interpMask |= SPAN_TEXTURE;
469e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      {
470a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul         /* win[3] is 1/W */
471dec3ed69e21baa1113938132e344761f39320f5fBrian Paul         const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3];
472a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul         TEX_UNIT_LOOP(
473a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            GLfloat eMaj_ds = vMax->texcoord[u][0] * wMax - vMin->texcoord[u][0] * wMin;
474a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            GLfloat eBot_ds = vMid->texcoord[u][0] * wMid - vMin->texcoord[u][0] * wMin;
475a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            GLfloat eMaj_dt = vMax->texcoord[u][1] * wMax - vMin->texcoord[u][1] * wMin;
476a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            GLfloat eBot_dt = vMid->texcoord[u][1] * wMid - vMin->texcoord[u][1] * wMin;
477a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            GLfloat eMaj_du = vMax->texcoord[u][2] * wMax - vMin->texcoord[u][2] * wMin;
478a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            GLfloat eBot_du = vMid->texcoord[u][2] * wMid - vMin->texcoord[u][2] * wMin;
479a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            GLfloat eMaj_dv = vMax->texcoord[u][3] * wMax - vMin->texcoord[u][3] * wMin;
480a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            GLfloat eBot_dv = vMid->texcoord[u][3] * wMid - vMin->texcoord[u][3] * wMin;
481a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            span.texStepX[u][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
482a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            span.texStepY[u][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
483a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            span.texStepX[u][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
484a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            span.texStepY[u][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
485a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            span.texStepX[u][2] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
486a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            span.texStepY[u][2] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
487a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            span.texStepX[u][3] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
488a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            span.texStepY[u][3] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
489a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul         )
490e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
491e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
492e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
493e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /*
494e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * We always sample at pixel centers.  However, we avoid
495e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * explicit half-pixel offsets in this code by incorporating
496e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * the proper offset in each of x and y during the
497e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * transformation to window coordinates.
498e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       *
499e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * We also apply the usual rasterization rules to prevent
500e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * cracks and overlaps.  A pixel is considered inside a
501e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * subtriangle if it meets all of four conditions: it is on or
502e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * to the right of the left edge, strictly to the left of the
503e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * right edge, on or below the top edge, and strictly above
504e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * the bottom edge.  (Some edges may be degenerate.)
505e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       *
506e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * The following discussion assumes left-to-right scanning
507e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * (that is, the major edge is on the left); the right-to-left
508e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * case is a straightforward variation.
509e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       *
510e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * We start by finding the half-integral y coordinate that is
511e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * at or below the top of the triangle.  This gives us the
512e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * first scan line that could possibly contain pixels that are
513e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * inside the triangle.
514e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       *
515e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * Next we creep down the major edge until we reach that y,
51622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes       * and compute the corresponding x coordinate on the edge.
517e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * Then we find the half-integral x that lies on or just
518e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * inside the edge.  This is the first pixel that might lie in
519e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * the interior of the triangle.  (We won't know for sure
520e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * until we check the other edges.)
521e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       *
522e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * As we rasterize the triangle, we'll step down the major
523e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * edge.  For each step in y, we'll move an integer number
524e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * of steps in x.  There are two possible x step sizes, which
525e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * we'll call the ``inner'' step (guaranteed to land on the
526e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * edge or inside it) and the ``outer'' step (guaranteed to
527e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * land on the edge or outside it).  The inner and outer steps
528e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * differ by one.  During rasterization we maintain an error
529e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * term that indicates our distance from the true edge, and
530e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * select either the inner step or the outer step, whichever
531e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * gets us to the first pixel that falls inside the triangle.
532e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       *
533e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * All parameters (z, red, etc.) as well as the buffer
534e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * addresses for color and z have inner and outer step values,
535e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * so that we can increment them appropriately.  This method
536e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * eliminates the need to adjust parameters by creeping a
537e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * sub-pixel amount into the triangle at each scanline.
538e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       */
539e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
540e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      {
541e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         int subTriangle;
5421b3528fe635242f782fbcdde3ba74b5b7359a362Brian Paul         GLfixed fx;
543c5a76cbed41b5816d2f5284f90c70364b062aea4Brian Paul         GLfixed fxLeftEdge = 0, fxRightEdge = 0;
544c5a76cbed41b5816d2f5284f90c70364b062aea4Brian Paul         GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
545e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLfixed fdxOuter;
546e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         int idxOuter;
547e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         float dxOuter;
548c5a76cbed41b5816d2f5284f90c70364b062aea4Brian Paul         GLfixed fError = 0, fdError = 0;
549e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         float adjx, adjy;
550e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         GLfixed fy;
551e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef PIXEL_ADDRESS
552c5a76cbed41b5816d2f5284f90c70364b062aea4Brian Paul         PIXEL_TYPE *pRow = NULL;
553c5a76cbed41b5816d2f5284f90c70364b062aea4Brian Paul         int dPRowOuter = 0, dPRowInner;  /* offset in bytes */
554e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
555e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_Z
556e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  ifdef DEPTH_TYPE
557c5a76cbed41b5816d2f5284f90c70364b062aea4Brian Paul         DEPTH_TYPE *zRow = NULL;
558c5a76cbed41b5816d2f5284f90c70364b062aea4Brian Paul         int dZRowOuter = 0, dZRowInner;  /* offset in bytes */
559e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  endif
56054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         GLfixed zLeft = 0, fdzOuter = 0, fdzInner;
56154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#endif
56254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#ifdef INTERP_W
56354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         GLfloat wLeft, dwOuter, dwInner;
56495e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul#endif
56595e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul#ifdef INTERP_FOG
566c5a76cbed41b5816d2f5284f90c70364b062aea4Brian Paul         GLfloat fogLeft = 0, dfogOuter = 0, dfogInner;
567e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
568e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_RGB
56954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         ColorTemp rLeft = 0, fdrOuter = 0, fdrInner;
57054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         ColorTemp gLeft = 0, fdgOuter = 0, fdgInner;
57154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         ColorTemp bLeft = 0, fdbOuter = 0, fdbInner;
5729bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#endif
5739bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#ifdef INTERP_ALPHA
57454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         ColorTemp aLeft = 0, fdaOuter = 0, fdaInner;
57596385fa15569e25cd0977e678c0ff3bdab6ef316Brian Paul#endif
576e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_SPEC
57754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         ColorTemp srLeft=0, dsrOuter=0, dsrInner;
57854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         ColorTemp sgLeft=0, dsgOuter=0, dsgInner;
57954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         ColorTemp sbLeft=0, dsbOuter=0, dsbInner;
58096385fa15569e25cd0977e678c0ff3bdab6ef316Brian Paul#endif
581e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INDEX
58254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         GLfixed iLeft=0, diOuter=0, diInner;
583e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
584e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INT_TEX
58554e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         GLfixed sLeft=0, dsOuter=0, dsInner;
58654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         GLfixed tLeft=0, dtOuter=0, dtInner;
587e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
588e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_TEX
589610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul         GLfloat sLeft[MAX_TEXTURE_COORD_UNITS];
590610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul         GLfloat tLeft[MAX_TEXTURE_COORD_UNITS];
591610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul         GLfloat uLeft[MAX_TEXTURE_COORD_UNITS];
592610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul         GLfloat vLeft[MAX_TEXTURE_COORD_UNITS];
593610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul         GLfloat dsOuter[MAX_TEXTURE_COORD_UNITS], dsInner[MAX_TEXTURE_COORD_UNITS];
594610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul         GLfloat dtOuter[MAX_TEXTURE_COORD_UNITS], dtInner[MAX_TEXTURE_COORD_UNITS];
595610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul         GLfloat duOuter[MAX_TEXTURE_COORD_UNITS], duInner[MAX_TEXTURE_COORD_UNITS];
596610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul         GLfloat dvOuter[MAX_TEXTURE_COORD_UNITS], dvInner[MAX_TEXTURE_COORD_UNITS];
597e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
598e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
599e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         for (subTriangle=0; subTriangle<=1; subTriangle++) {
600e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            EdgeT *eLeft, *eRight;
601e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            int setupLeft, setupRight;
602e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            int lines;
603e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
604e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            if (subTriangle==0) {
605e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* bottom half */
606d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               if (scan_from_left_to_right) {
607e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  eLeft = &eMaj;
608e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  eRight = &eBot;
609e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  lines = eRight->lines;
610e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  setupLeft = 1;
611e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  setupRight = 1;
612e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
613e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               else {
614e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  eLeft = &eBot;
615e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  eRight = &eMaj;
616e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  lines = eLeft->lines;
617e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  setupLeft = 1;
618e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  setupRight = 1;
619e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
620e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            }
621e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            else {
622e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* top half */
623d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               if (scan_from_left_to_right) {
624e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  eLeft = &eMaj;
625e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  eRight = &eTop;
626e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  lines = eRight->lines;
627e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  setupLeft = 0;
628e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  setupRight = 1;
629e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
630e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               else {
631e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  eLeft = &eTop;
632e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  eRight = &eMaj;
633e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  lines = eLeft->lines;
634e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  setupLeft = 1;
635e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  setupRight = 0;
636e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
637e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               if (lines == 0)
638e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  return;
639e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            }
640e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
641e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            if (setupLeft && eLeft->lines > 0) {
642a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul               const SWvertex *vLower;
643e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               GLfixed fsx = eLeft->fsx;
644e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fx = FixedCeil(fsx);
645e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fError = fx - fsx - FIXED_ONE;
646e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fxLeftEdge = fsx - FIXED_EPSILON;
647e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fdxLeftEdge = eLeft->fdxdy;
648e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fdxOuter = FixedFloor(fdxLeftEdge - FIXED_EPSILON);
649e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fdError = fdxOuter - fdxLeftEdge + FIXED_ONE;
650e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               idxOuter = FixedToInt(fdxOuter);
651e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               dxOuter = (float) idxOuter;
652e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               (void) dxOuter;
653e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
654e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fy = eLeft->fsy;
655a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul               span.y = FixedToInt(fy);
656e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
657e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               adjx = (float)(fx - eLeft->fx0);  /* SCALED! */
658e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               adjy = eLeft->adjy;		 /* SCALED! */
6592e5c1dce4e6fc27a6968ac91986564200bc5f3bdBrian Paul#ifndef __IBMCPP__
660e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               (void) adjx;  /* silence compiler warnings */
661e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               (void) adjy;  /* silence compiler warnings */
6622e5c1dce4e6fc27a6968ac91986564200bc5f3bdBrian Paul#endif
663e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               vLower = eLeft->v0;
6642e5c1dce4e6fc27a6968ac91986564200bc5f3bdBrian Paul#ifndef __IBMCPP__
665e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               (void) vLower;  /* silence compiler warnings */
6662e5c1dce4e6fc27a6968ac91986564200bc5f3bdBrian Paul#endif
667e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
668e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef PIXEL_ADDRESS
669e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               {
670a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                  pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(FixedToInt(fxLeftEdge), span.y);
671e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE);
672e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  /* negative because Y=0 at bottom and increases upward */
673e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
674e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
675e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /*
676e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * Now we need the set of parameter (z, color, etc.) values at
677e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * the point (fx, fy).  This gives us properly-sampled parameter
678e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * values that we can step from pixel to pixel.  Furthermore,
679e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * although we might have intermediate results that overflow
680e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * the normal parameter range when we step temporarily outside
681e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * the triangle, we shouldn't overflow or underflow for any
682e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * pixel that's actually inside the triangle.
683e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                */
684e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
685e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_Z
686e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               {
687cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell                  GLfloat z0 = vLower->win[2];
688e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  if (depthBits <= 16) {
689e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                     /* interpolate fixed-pt values */
69054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                     GLfloat tmp = (z0 * FIXED_SCALE + span.dzdx * adjx + span.dzdy * adjy) + FIXED_HALF;
691e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                     if (tmp < MAX_GLUINT / 2)
69254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                        zLeft = (GLfixed) tmp;
693e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                     else
69454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                        zLeft = MAX_GLUINT / 2;
69554e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                     fdzOuter = SignedFloatToFixed(span.dzdy + dxOuter * span.dzdx);
696e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  }
697e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  else {
698e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                     /* interpolate depth values exactly */
69954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                     zLeft = (GLint) (z0 + span.dzdx * FixedToFloat(adjx) + span.dzdy * FixedToFloat(adjy));
70054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                     fdzOuter = (GLint) (span.dzdy + dxOuter * span.dzdx);
701e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  }
702e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  ifdef DEPTH_TYPE
7039bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  zRow = (DEPTH_TYPE *)
704a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                    _mesa_zbuffer_address(ctx, FixedToInt(fxLeftEdge), span.y);
705e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE);
706e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  endif
707e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
70895e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul#endif
70954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#ifdef INTERP_W
71054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               wLeft = vLower->win[3] + (span.dwdx * adjx + span.dwdy * adjy) * (1.0F/FIXED_SCALE);
71154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               dwOuter = span.dwdy + dxOuter * span.dwdx;
71254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#endif
71395e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul#ifdef INTERP_FOG
71454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               fogLeft = vLower->fog + (span.dfogdx * adjx + span.dfogdy * adjy) * (1.0F/FIXED_SCALE);
71554e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               dfogOuter = span.dfogdy + dxOuter * span.dfogdx;
716e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
717e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_RGB
718d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               if (ctx->Light.ShadeModel == GL_SMOOTH) {
719dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  if CHAN_TYPE == GL_FLOAT
72054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  rLeft = vLower->color[RCOMP] + (span.drdx * adjx + span.drdy * adjy) * (1.0F / FIXED_SCALE);
72154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  gLeft = vLower->color[GCOMP] + (span.dgdx * adjx + span.dgdy * adjy) * (1.0F / FIXED_SCALE);
72254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  bLeft = vLower->color[BCOMP] + (span.dbdx * adjx + span.dbdy * adjy) * (1.0F / FIXED_SCALE);
72354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  fdrOuter = span.drdy + dxOuter * span.drdx;
72454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  fdgOuter = span.dgdy + dxOuter * span.dgdx;
72554e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  fdbOuter = span.dbdy + dxOuter * span.dbdx;
726dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  else
72754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  rLeft = (ChanToFixed(vLower->color[RCOMP]) + span.drdx * adjx + span.drdy * adjy) + FIXED_HALF;
72854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  gLeft = (ChanToFixed(vLower->color[GCOMP]) + span.dgdx * adjx + span.dgdy * adjy) + FIXED_HALF;
72954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  bLeft = (ChanToFixed(vLower->color[BCOMP]) + span.dbdx * adjx + span.dbdy * adjy) + FIXED_HALF;
73054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  fdrOuter = SignedFloatToFixed(span.drdy + dxOuter * span.drdx);
73154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  fdgOuter = SignedFloatToFixed(span.dgdy + dxOuter * span.dgdx);
73254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  fdbOuter = SignedFloatToFixed(span.dbdy + dxOuter * span.dbdx);
733dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  endif
734d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul#  ifdef INTERP_ALPHA
735dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#    if CHAN_TYPE == GL_FLOAT
73654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  aLeft = vLower->color[ACOMP] + (span.dadx * adjx + span.dady * adjy) * (1.0F / FIXED_SCALE);
73754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  fdaOuter = span.dady + dxOuter * span.dadx;
738dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#    else
73954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  aLeft = (ChanToFixed(vLower->color[ACOMP]) + span.dadx * adjx + span.dady * adjy) + FIXED_HALF;
74054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  fdaOuter = SignedFloatToFixed(span.dady + dxOuter * span.dadx);
741dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#    endif
742d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul#  endif
743d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               }
744d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               else {
745d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul                  ASSERT (ctx->Light.ShadeModel == GL_FLAT);
746dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  if CHAN_TYPE == GL_FLOAT
74754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  rLeft = v2->color[RCOMP];
74854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  gLeft = v2->color[GCOMP];
74954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  bLeft = v2->color[BCOMP];
750dec3ed69e21baa1113938132e344761f39320f5fBrian Paul                  fdrOuter = fdgOuter = fdbOuter = 0.0F;
751dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  else
75254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  rLeft = ChanToFixed(v2->color[RCOMP]);
75354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  gLeft = ChanToFixed(v2->color[GCOMP]);
75454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  bLeft = ChanToFixed(v2->color[BCOMP]);
755d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul                  fdrOuter = fdgOuter = fdbOuter = 0;
756dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  endif
757d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul#  ifdef INTERP_ALPHA
758dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#    if CHAN_TYPE == GL_FLOAT
75954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  aLeft = v2->color[ACOMP];
760dec3ed69e21baa1113938132e344761f39320f5fBrian Paul                  fdaOuter = 0.0F;
761dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#    else
76254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  aLeft = ChanToFixed(v2->color[ACOMP]);
763d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul                  fdaOuter = 0;
764dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#    endif
765d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul#  endif
766d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               }
7679bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#endif
768dec3ed69e21baa1113938132e344761f39320f5fBrian Paul
769e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_SPEC
770d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               if (ctx->Light.ShadeModel == GL_SMOOTH) {
771dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  if CHAN_TYPE == GL_FLOAT
77254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  srLeft = vLower->specular[RCOMP] + (span.dsrdx * adjx + span.dsrdy * adjy) * (1.0F / FIXED_SCALE);
77354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  sgLeft = vLower->specular[GCOMP] + (span.dsgdx * adjx + span.dsgdy * adjy) * (1.0F / FIXED_SCALE);
77454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  sbLeft = vLower->specular[BCOMP] + (span.dsbdx * adjx + span.dsbdy * adjy) * (1.0F / FIXED_SCALE);
77554e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  dsrOuter = span.dsrdy + dxOuter * span.dsrdx;
77654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  dsgOuter = span.dsgdy + dxOuter * span.dsgdx;
77754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  dsbOuter = span.dsbdy + dxOuter * span.dsbdx;
778dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  else
77954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  srLeft = (GLfixed) (ChanToFixed(vLower->specular[RCOMP]) + span.dsrdx * adjx + span.dsrdy * adjy) + FIXED_HALF;
78054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  sgLeft = (GLfixed) (ChanToFixed(vLower->specular[GCOMP]) + span.dsgdx * adjx + span.dsgdy * adjy) + FIXED_HALF;
78154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  sbLeft = (GLfixed) (ChanToFixed(vLower->specular[BCOMP]) + span.dsbdx * adjx + span.dsbdy * adjy) + FIXED_HALF;
78254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  dsrOuter = SignedFloatToFixed(span.dsrdy + dxOuter * span.dsrdx);
78354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  dsgOuter = SignedFloatToFixed(span.dsgdy + dxOuter * span.dsgdx);
78454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  dsbOuter = SignedFloatToFixed(span.dsbdy + dxOuter * span.dsbdx);
785dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  endif
786d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               }
787d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               else {
788dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#if  CHAN_TYPE == GL_FLOAT
78954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  srLeft = v2->specular[RCOMP];
79054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  sgLeft = v2->specular[GCOMP];
79154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  sbLeft = v2->specular[BCOMP];
79254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  dsrOuter = dsgOuter = dsbOuter = 0.0F;
793dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  else
79454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  srLeft = ChanToFixed(v2->specular[RCOMP]);
79554e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  sgLeft = ChanToFixed(v2->specular[GCOMP]);
79654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  sbLeft = ChanToFixed(v2->specular[BCOMP]);
79754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  dsrOuter = dsgOuter = dsbOuter = 0;
798dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  endif
799d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               }
80096385fa15569e25cd0977e678c0ff3bdab6ef316Brian Paul#endif
801dec3ed69e21baa1113938132e344761f39320f5fBrian Paul
802e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INDEX
803d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               if (ctx->Light.ShadeModel == GL_SMOOTH) {
80454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  iLeft = (GLfixed)(vLower->index * FIXED_SCALE
805d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul                                 + didx * adjx + didy * adjy) + FIXED_HALF;
80654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  diOuter = SignedFloatToFixed(didy + dxOuter * didx);
807d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               }
808d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               else {
80954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  iLeft = (GLfixed) (v2->index * FIXED_SCALE);
81054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  diOuter = 0;
811d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               }
812e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
813e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INT_TEX
814e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               {
815e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  GLfloat s0, t0;
816cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell                  s0 = vLower->texcoord[0][0] * S_SCALE;
81754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  sLeft = (GLfixed)(s0 * FIXED_SCALE + span.texStepX[0][0] * adjx
818dec3ed69e21baa1113938132e344761f39320f5fBrian Paul                                 + span.texStepY[0][0] * adjy) + FIXED_HALF;
81954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  dsOuter = SignedFloatToFixed(span.texStepY[0][0] + dxOuter * span.texStepX[0][0]);
820e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
821d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul                  t0 = vLower->texcoord[0][1] * T_SCALE;
82254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  tLeft = (GLfixed)(t0 * FIXED_SCALE + span.texStepX[0][1] * adjx
823dec3ed69e21baa1113938132e344761f39320f5fBrian Paul                                 + span.texStepY[0][1] * adjy) + FIXED_HALF;
82454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  dtOuter = SignedFloatToFixed(span.texStepY[0][1] + dxOuter * span.texStepX[0][1]);
825d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul               }
826e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
827e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_TEX
828a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul               TEX_UNIT_LOOP(
829dec3ed69e21baa1113938132e344761f39320f5fBrian Paul                  const GLfloat invW = vLower->win[3];
830a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  const GLfloat s0 = vLower->texcoord[u][0] * invW;
831a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  const GLfloat t0 = vLower->texcoord[u][1] * invW;
832a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  const GLfloat u0 = vLower->texcoord[u][2] * invW;
833a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  const GLfloat v0 = vLower->texcoord[u][3] * invW;
834a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  sLeft[u] = s0 + (span.texStepX[u][0] * adjx + span.texStepY[u][0] * adjy) * (1.0F/FIXED_SCALE);
835a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  tLeft[u] = t0 + (span.texStepX[u][1] * adjx + span.texStepY[u][1] * adjy) * (1.0F/FIXED_SCALE);
836a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  uLeft[u] = u0 + (span.texStepX[u][2] * adjx + span.texStepY[u][2] * adjy) * (1.0F/FIXED_SCALE);
837a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  vLeft[u] = v0 + (span.texStepX[u][3] * adjx + span.texStepY[u][3] * adjy) * (1.0F/FIXED_SCALE);
838a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  dsOuter[u] = span.texStepY[u][0] + dxOuter * span.texStepX[u][0];
839a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  dtOuter[u] = span.texStepY[u][1] + dxOuter * span.texStepX[u][1];
840a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  duOuter[u] = span.texStepY[u][2] + dxOuter * span.texStepX[u][2];
841a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  dvOuter[u] = span.texStepY[u][3] + dxOuter * span.texStepX[u][3];
842a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul               )
843e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
844e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            } /*if setupLeft*/
845e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
846e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
847e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            if (setupRight && eRight->lines>0) {
848e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fxRightEdge = eRight->fsx - FIXED_EPSILON;
849e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fdxRightEdge = eRight->fdxdy;
850e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            }
851e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
852e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            if (lines==0) {
853e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               continue;
854e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            }
855e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
856e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
857e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* Rasterize setup */
858e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef PIXEL_ADDRESS
859e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            dPRowInner = dPRowOuter + sizeof(PIXEL_TYPE);
860e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
861e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_Z
862e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  ifdef DEPTH_TYPE
863e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            dZRowInner = dZRowOuter + sizeof(DEPTH_TYPE);
864e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  endif
865a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul            fdzInner = fdzOuter + span.zStep;
86695e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul#endif
86754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#ifdef INTERP_W
86854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul            dwInner = dwOuter + span.dwdx;
86954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#endif
87095e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul#ifdef INTERP_FOG
87154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul            dfogInner = dfogOuter + span.dfogdx;
872e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
873dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#if defined(INTERP_RGB)
874a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul            fdrInner = fdrOuter + span.redStep;
875a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul            fdgInner = fdgOuter + span.greenStep;
876a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul            fdbInner = fdbOuter + span.blueStep;
877e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
878dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#if defined(INTERP_ALPHA)
879a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul            fdaInner = fdaOuter + span.alphaStep;
8809bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#endif
881dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#if defined(INTERP_SPEC)
88254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul            dsrInner = dsrOuter + span.specRedStep;
88354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul            dsgInner = dsgOuter + span.specGreenStep;
88454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul            dsbInner = dsbOuter + span.specBlueStep;
885e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
886e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INDEX
88754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul            diInner = diOuter + span.indexStep;
888e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
889e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INT_TEX
89054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul            dsInner = dsOuter + span.intTexStep[0];
89154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul            dtInner = dtOuter + span.intTexStep[1];
892e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
893e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_TEX
894a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            TEX_UNIT_LOOP(
895a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul               dsInner[u] = dsOuter[u] + span.texStepX[u][0];
896a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul               dtInner[u] = dtOuter[u] + span.texStepX[u][1];
897a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul               duInner[u] = duOuter[u] + span.texStepX[u][2];
898a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul               dvInner[u] = dvOuter[u] + span.texStepX[u][3];
899a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul            )
900e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
901e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
9029bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            while (lines > 0) {
903e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* initialize the span interpolants to the leftmost value */
904e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* ff = fixed-pt fragment */
9059bf68ad963ba92b5d1e725f965979042495a5313Brian Paul               const GLint right = FixedToInt(fxRightEdge);
9067956292a765910077f50352d7cd0174e1e66d26cBrian Paul
907a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul               span.x = FixedToInt(fxLeftEdge);
90810f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
909a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul               if (right <= span.x)
910a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                  span.end = 0;
9119bf68ad963ba92b5d1e725f965979042495a5313Brian Paul               else
912a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                  span.end = right - span.x;
9139bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
914e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_Z
91554e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.z = zLeft;
91654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#endif
91754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#ifdef INTERP_W
91854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.w = wLeft;
91995e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul#endif
92095e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul#ifdef INTERP_FOG
921a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul               span.fog = fogLeft;
922e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
923dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#if defined(INTERP_RGB)
92454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.red = rLeft;
92554e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.green = gLeft;
92654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.blue = bLeft;
927e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
928dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#if defined(INTERP_ALPHA)
92954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.alpha = aLeft;
9309bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#endif
931dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#if defined(INTERP_SPEC)
93254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.specRed = srLeft;
93354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.specGreen = sgLeft;
93454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.specBlue = sbLeft;
935e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
936e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INDEX
93754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.index = iLeft;
938e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
939e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INT_TEX
94054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.intTex[0] = sLeft;
94154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.intTex[1] = tLeft;
942e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
9439bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
944e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_TEX
945a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul               TEX_UNIT_LOOP(
946a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  span.tex[u][0] = sLeft[u];
947a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  span.tex[u][1] = tLeft[u];
948a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  span.tex[u][2] = uLeft[u];
949a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  span.tex[u][3] = vLeft[u];
950a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul               )
951e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
952e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
953e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_RGB
954e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               {
955e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  /* need this to accomodate round-off errors */
956a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                  const GLint len = right - span.x - 1;
957a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                  GLfixed ffrend = span.red + len * span.redStep;
958a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                  GLfixed ffgend = span.green + len * span.greenStep;
959a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                  GLfixed ffbend = span.blue + len * span.blueStep;
9609bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  if (ffrend < 0) {
961a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                     span.red -= ffrend;
962a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                     if (span.red < 0)
963a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                        span.red = 0;
9649bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  }
9659bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  if (ffgend < 0) {
966a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                     span.green -= ffgend;
967a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                     if (span.green < 0)
968a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                        span.green = 0;
9699bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  }
9709bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  if (ffbend < 0) {
971a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                     span.blue -= ffbend;
972a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                     if (span.blue < 0)
973a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                        span.blue = 0;
9749bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  }
975e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
976e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
9779bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#ifdef INTERP_ALPHA
978e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               {
979a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                  const GLint len = right - span.x - 1;
980a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                  GLfixed ffaend = span.alpha + len * span.alphaStep;
9819bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  if (ffaend < 0) {
982a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                     span.alpha -= ffaend;
983a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                     if (span.alpha < 0)
984a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                        span.alpha = 0;
9859bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  }
986e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
987e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
9889bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#ifdef INTERP_SPEC
989e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               {
9909bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  /* need this to accomodate round-off errors */
991a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                  const GLint len = right - span.x - 1;
992a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                  GLfixed ffsrend = span.specRed + len * span.specRedStep;
993a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                  GLfixed ffsgend = span.specGreen + len * span.specGreenStep;
994a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                  GLfixed ffsbend = span.specBlue + len * span.specBlueStep;
9959bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  if (ffsrend < 0) {
996a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                     span.specRed -= ffsrend;
997a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                     if (span.specRed < 0)
998a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                        span.specRed = 0;
9999bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  }
10009bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  if (ffsgend < 0) {
1001a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                     span.specGreen -= ffsgend;
1002a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                     if (span.specGreen < 0)
1003a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                        span.specGreen = 0;
10049bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  }
10059bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  if (ffsbend < 0) {
1006a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                     span.specBlue -= ffsbend;
1007a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                     if (span.specBlue < 0)
1008a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                        span.specBlue = 0;
10099bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  }
1010e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
1011e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
1012e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INDEX
1013a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul               if (span.index < 0)  span.index = 0;
101419bbfc62638b60dd1a41e84686f24483adea5b03Brian Paul#endif
101519bbfc62638b60dd1a41e84686f24483adea5b03Brian Paul
10169bf68ad963ba92b5d1e725f965979042495a5313Brian Paul               /* This is where we actually generate fragments */
1017a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul               if (span.end > 0) {
10189bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  RENDER_SPAN( span );
10199bf68ad963ba92b5d1e725f965979042495a5313Brian Paul               }
1020e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1021e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /*
1022e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * Advance to the next scan line.  Compute the
1023e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * new edge coordinates, and adjust the
1024e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * pixel-center x coordinate so that it stays
1025e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * on or inside the major edge.
1026e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                */
1027a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul               (span.y)++;
1028e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               lines--;
1029e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1030e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fxLeftEdge += fdxLeftEdge;
1031e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fxRightEdge += fdxRightEdge;
1032e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1033e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1034e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fError += fdError;
1035e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               if (fError >= 0) {
1036e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  fError -= FIXED_ONE;
1037e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef PIXEL_ADDRESS
10389bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter);
1039e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
1040e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_Z
1041e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  ifdef DEPTH_TYPE
10429bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowOuter);
1043e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  endif
104454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  zLeft += fdzOuter;
104554e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#endif
104654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#ifdef INTERP_W
104754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  wLeft += dwOuter;
104895e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul#endif
104995e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul#ifdef INTERP_FOG
10501b3528fe635242f782fbcdde3ba74b5b7359a362Brian Paul                  fogLeft += dfogOuter;
1051e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
1052dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#if defined(INTERP_RGB)
105354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  rLeft += fdrOuter;
105454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  gLeft += fdgOuter;
105554e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  bLeft += fdbOuter;
1056e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
1057dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#if defined(INTERP_ALPHA)
105854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  aLeft += fdaOuter;
1059e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
1060dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#if defined(INTERP_SPEC)
106154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  srLeft += dsrOuter;
106254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  sgLeft += dsgOuter;
106354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  sbLeft += dsbOuter;
10649bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#endif
1065e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INDEX
106654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  iLeft += diOuter;
1067e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
1068e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INT_TEX
106954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  sLeft += dsOuter;
107054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  tLeft += dtOuter;
1071e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
1072e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_TEX
1073a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  TEX_UNIT_LOOP(
1074a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                     sLeft[u] += dsOuter[u];
1075a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                     tLeft[u] += dtOuter[u];
1076a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                     uLeft[u] += duOuter[u];
1077a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                     vLeft[u] += dvOuter[u];
1078a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  )
1079e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
1080e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
1081e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               else {
1082e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef PIXEL_ADDRESS
10839bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowInner);
1084e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
1085e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_Z
1086e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  ifdef DEPTH_TYPE
10879bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowInner);
1088e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  endif
108954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  zLeft += fdzInner;
109054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#endif
109154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#ifdef INTERP_W
109254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  wLeft += dwInner;
109395e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul#endif
109495e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul#ifdef INTERP_FOG
10951b3528fe635242f782fbcdde3ba74b5b7359a362Brian Paul                  fogLeft += dfogInner;
1096e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
1097dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#if defined(INTERP_RGB)
109854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  rLeft += fdrInner;
109954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  gLeft += fdgInner;
110054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  bLeft += fdbInner;
1101e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
1102dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#if defined(INTERP_ALPHA)
110354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  aLeft += fdaInner;
1104e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
1105dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#if defined(INTERP_SPEC)
110654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  srLeft += dsrInner;
110754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  sgLeft += dsgInner;
110854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  sbLeft += dsbInner;
11099bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#endif
1110e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INDEX
111154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  iLeft += diInner;
1112e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
1113e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INT_TEX
111454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  sLeft += dsInner;
111554e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  tLeft += dtInner;
1116e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
1117e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_TEX
1118a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  TEX_UNIT_LOOP(
1119a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                     sLeft[u] += dsInner[u];
1120a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                     tLeft[u] += dtInner[u];
1121a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                     uLeft[u] += duInner[u];
1122a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                     vLeft[u] += dvInner[u];
1123a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul                  )
1124e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
1125e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
1126e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            } /*while lines>0*/
1127e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1128e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         } /* for subTriangle */
1129e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1130e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
113147cf442c1164b6b406117fccfb8b564602741ee3Brian Paul#ifdef CLEANUP_CODE
113247cf442c1164b6b406117fccfb8b564602741ee3Brian Paul      CLEANUP_CODE
113347cf442c1164b6b406117fccfb8b564602741ee3Brian Paul#endif
1134e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
1135e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
1136e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1137e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef SETUP_CODE
113847cf442c1164b6b406117fccfb8b564602741ee3Brian Paul#undef CLEANUP_CODE
11399bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#undef RENDER_SPAN
1140e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1141e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef PIXEL_TYPE
1142e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef BYTES_PER_ROW
1143e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef PIXEL_ADDRESS
1144e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1145e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef INTERP_Z
114654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#undef INTERP_W
114795e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul#undef INTERP_FOG
1148e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef INTERP_RGB
1149e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef INTERP_ALPHA
11509bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#undef INTERP_SPEC
1151e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef INTERP_INDEX
1152e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef INTERP_INT_TEX
1153e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef INTERP_TEX
1154e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef INTERP_MULTITEX
1155a79b55ae65a4a85a2aeaa2a5b1cb757c6e88849dBrian Paul#undef TEX_UNIT_LOOP
1156e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1157e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef S_SCALE
1158e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef T_SCALE
1159e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1160e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef FixedToDepth
1161e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1162e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef DO_OCCLUSION_TEST
1163cdf2da368d180205df3573697b51b8764048ad6eBrian Paul#undef NAME
1164