1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library
399f24c8d17f3a39ff0ebbeb1f7fa80142d8be648Brian * Version:  7.0
422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
5dd34fe8679fa200e55cfaf8e80bbecdecea084e3Brian * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
7e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
8e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"),
9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation
10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the
12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions:
1322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included
15e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software.
1622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
25e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
26e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Triangle Rasterizer Template
27e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *
28e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * This file is #include'd to generate custom triangle rasterizers.
29e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *
30e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The following macros may be defined to indicate what auxillary information
31bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol * must be interpolated across the triangle:
329e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian *    INTERP_Z        - if defined, interpolate integer Z values
339e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian *    INTERP_RGB      - if defined, interpolate integer RGB values
349e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian *    INTERP_ALPHA    - if defined, interpolate integer Alpha values
35e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *    INTERP_INT_TEX  - if defined, interpolate integer ST texcoords
369e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian *                         (fast, simple 2-D texture mapping, without
379e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian *                         perspective correction)
388a8a5bd104e8cd9362415db77d5f6a3945939589Brian *    INTERP_ATTRIBS  - if defined, interpolate arbitrary attribs (texcoords,
399e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian *                         varying vars, etc)  This also causes W to be
409e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian *                         computed for perspective correction).
41e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *
42e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * When one can directly address pixels in the color buffer the following
43e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * macros can be defined and used to compute pixel addresses during
44e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * rasterization (see pRow):
45e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
46e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *    BYTES_PER_ROW       - number of bytes per row in the color buffer
47e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
48e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *                          Y==0 at bottom of screen and increases upward.
49e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *
50e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Similarly, for direct depth buffer access, this type is used for depth
519e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian * buffer addressing (see zRow):
52e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *    DEPTH_TYPE          - either GLushort or GLuint
53e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *
54e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Optionally, one may provide one-time setup code per triangle:
55e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *    SETUP_CODE    - code which is to be executed once per triangle
5622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
57e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The following macro MUST be defined:
589bf68ad963ba92b5d1e725f965979042495a5313Brian Paul *    RENDER_SPAN(span) - code to write a span of pixels.
59e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *
60e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * This code was designed for the origin to be in the lower-left corner.
61e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell *
62e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Inspired by triangle rasterizer code written by Allen Akin.  Thanks Allen!
637c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul *
647c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul *
657c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * Some notes on rasterization accuracy:
667c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul *
677c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * This code uses fixed point arithmetic (the GLfixed type) to iterate
687c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * over the triangle edges and interpolate ancillary data (such as Z,
697c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * color, secondary color, etc).  The number of fractional bits in
707c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * GLfixed and the value of SUB_PIXEL_BITS has a direct bearing on the
717c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * accuracy of rasterization.
727c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul *
737c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * If SUB_PIXEL_BITS=4 then we'll snap the vertices to the nearest
747c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * 1/16 of a pixel.  If we're walking up a long, nearly vertical edge
757c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * (dx=1/16, dy=1024) we'll need 4 + 10 = 14 fractional bits in
767c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * GLfixed to walk the edge without error.  If the maximum viewport
777c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * height is 4K pixels, then we'll need 4 + 12 = 16 fractional bits.
787c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul *
797c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * Historically, Mesa has used 11 fractional bits in GLfixed, snaps
807c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * vertices to 1/16 pixel and allowed a maximum viewport height of 2K
817c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * pixels.  11 fractional bits is actually insufficient for accurately
827c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * rasterizing some triangles.  More recently, the maximum viewport
837c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * height was increased to 4K pixels.  Thus, Mesa should be using 16
847c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * fractional bits in GLfixed.  Unfortunately, there may be some issues
857c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * with setting FIXED_FRAC_BITS=16, such as multiplication overflow.
867c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * This will have to be examined in some detail...
877c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul *
887c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * For now, if you find rasterization errors, particularly with tall,
897c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * sliver triangles, try increasing FIXED_FRAC_BITS and/or decreasing
907c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul * SUB_PIXEL_BITS.
91e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
92e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
9384b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul
94daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul/*
95daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul * Some code we unfortunately need to prevent negative interpolated colors.
96daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul */
97daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul#ifndef CLAMP_INTERPOLANT
98daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul#define CLAMP_INTERPOLANT(CHANNEL, CHANNELSTEP, LEN)		\
99daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Pauldo {								\
100daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul   GLfixed endVal = span.CHANNEL + (LEN) * span.CHANNELSTEP;	\
101daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul   if (endVal < 0) {						\
102daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul      span.CHANNEL -= endVal;					\
103daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul   }								\
104daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul   if (span.CHANNEL < 0) {					\
105daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul      span.CHANNEL = 0;						\
106daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul   }								\
107daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul} while (0)
108daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul#endif
109daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul
110daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul
111f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void NAME(struct gl_context *ctx, const SWvertex *v0,
112cdf2da368d180205df3573697b51b8764048ad6eBrian Paul                                 const SWvertex *v1,
113cdf2da368d180205df3573697b51b8764048ad6eBrian Paul                                 const SWvertex *v2 )
114e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
115e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   typedef struct {
11684b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul      const SWvertex *v0, *v1;   /* Y(v0) < Y(v1) */
11784b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul      GLfloat dx;	/* X(v1) - X(v0) */
11884b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul      GLfloat dy;	/* Y(v1) - Y(v0) */
11984b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul      GLfloat dxdy;	/* dx/dy */
12084b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul      GLfixed fdxdy;	/* dx/dy in fixed-point */
12184b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul      GLfloat adjy;	/* adjust from v[0]->fy to fsy, scaled */
12284b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul      GLfixed fsx;	/* first sample point x coord */
12384b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul      GLfixed fsy;
12484b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul      GLfixed fx0;	/* fixed pt X of lower endpoint */
1257d05e484783cc81d2f9d4ceb2b1e1252555ffef0Brian Paul      GLint lines;	/* number of lines to be sampled on this edge */
126e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   } EdgeT;
127e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
128dd34fe8679fa200e55cfaf8e80bbecdecea084e3Brian   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
129e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_Z
130e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   const GLint depthBits = ctx->DrawBuffer->Visual.depthBits;
131e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0;
132e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   const GLfloat maxDepth = ctx->DrawBuffer->_DepthMaxF;
133e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#define FixedToDepth(F)  ((F) >> fixedToDepthShift)
134e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
135e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   EdgeT eMaj, eTop, eBot;
136e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLfloat oneOverArea;
137a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul   const SWvertex *vMin, *vMid, *vMax;  /* Y(vMin)<=Y(vMid)<=Y(vMax) */
13802afd45d3b2eccff5d566cdeb32b3211803bd500Brian   GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign;
13910d343f407bddf011be3d2b79a6541815759785aBrian Paul   const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */
1409e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
141e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
142cdb27e8242215271364602995d85607cfc06d441Brian Paul   SWspan span;
1439bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
144dd34fe8679fa200e55cfaf8e80bbecdecea084e3Brian   (void) swrast;
145dd34fe8679fa200e55cfaf8e80bbecdecea084e3Brian
146f4b103dc993491355ec3e3640d9cb060138175c2Brian   INIT_SPAN(span, GL_POLYGON);
147f9c01c33d3d168ae7c2eadc6c0fb10faada6f6f5Brian   span.y = 0; /* silence warnings */
1482a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
1499bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#ifdef INTERP_Z
1509bf68ad963ba92b5d1e725f965979042495a5313Brian Paul   (void) fixedToDepthShift;
1519bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#endif
1529bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
1533ade8af7ffce434bb612df67f8e5a780885f991cBrian Paul   /*
1543ade8af7ffce434bb612df67f8e5a780885f991cBrian Paul   printf("%s()\n", __FUNCTION__);
1559e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   printf("  %g, %g, %g\n",
1569e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian          v0->attrib[FRAG_ATTRIB_WPOS][0],
1579e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian          v0->attrib[FRAG_ATTRIB_WPOS][1],
1589e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian          v0->attrib[FRAG_ATTRIB_WPOS][2]);
1599e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   printf("  %g, %g, %g\n",
1609e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian          v1->attrib[FRAG_ATTRIB_WPOS][0],
1619e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian          v1->attrib[FRAG_ATTRIB_WPOS][1],
1629e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian          v1->attrib[FRAG_ATTRIB_WPOS][2]);
1639e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   printf("  %g, %g, %g\n",
1649e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian          v2->attrib[FRAG_ATTRIB_WPOS][0],
1659e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian          v2->attrib[FRAG_ATTRIB_WPOS][1],
1669e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian          v2->attrib[FRAG_ATTRIB_WPOS][2]);
1677d05e484783cc81d2f9d4ceb2b1e1252555ffef0Brian Paul   */
1689e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian
169a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   /* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
170a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul    * And find the order of the 3 vertices along the Y axis.
171a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul    */
172e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   {
1739e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      const GLfixed fy0 = FloatToFixed(v0->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask;
1749e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      const GLfixed fy1 = FloatToFixed(v1->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask;
1759e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      const GLfixed fy2 = FloatToFixed(v2->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask;
176a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul      if (fy0 <= fy1) {
177d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         if (fy1 <= fy2) {
178a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            /* y0 <= y1 <= y2 */
179d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul            vMin = v0;   vMid = v1;   vMax = v2;
180a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            vMin_fy = fy0;  vMid_fy = fy1;  vMax_fy = fy2;
181d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         }
182d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         else if (fy2 <= fy0) {
183a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            /* y2 <= y0 <= y1 */
184d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul            vMin = v2;   vMid = v0;   vMax = v1;
185a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            vMin_fy = fy2;  vMid_fy = fy0;  vMax_fy = fy1;
186d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         }
187d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         else {
188a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            /* y0 <= y2 <= y1 */
189d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul            vMin = v0;   vMid = v2;   vMax = v1;
190a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            vMin_fy = fy0;  vMid_fy = fy2;  vMax_fy = fy1;
191a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            bf = -bf;
192d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         }
193e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
194e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
195d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         if (fy0 <= fy2) {
196a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            /* y1 <= y0 <= y2 */
197d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul            vMin = v1;   vMid = v0;   vMax = v2;
198a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            vMin_fy = fy1;  vMid_fy = fy0;  vMax_fy = fy2;
199a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            bf = -bf;
200d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         }
201d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         else if (fy2 <= fy1) {
202a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            /* y2 <= y1 <= y0 */
203d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul            vMin = v2;   vMid = v1;   vMax = v0;
204a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            vMin_fy = fy2;  vMid_fy = fy1;  vMax_fy = fy0;
205a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            bf = -bf;
206d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         }
207d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         else {
208a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            /* y1 <= y2 <= y0 */
209d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul            vMin = v1;   vMid = v2;   vMax = v0;
210a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul            vMin_fy = fy1;  vMid_fy = fy2;  vMax_fy = fy0;
211d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         }
212e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
213a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul
214a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul      /* fixed point X coords */
2159e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      vMin_fx = FloatToFixed(vMin->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask;
2169e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      vMid_fx = FloatToFixed(vMid->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask;
2179e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian      vMax_fx = FloatToFixed(vMax->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask;
218e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
219e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
220e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* vertex/edge relationship */
221e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   eMaj.v0 = vMin;   eMaj.v1 = vMax;   /*TODO: .v1's not needed */
222e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   eTop.v0 = vMid;   eTop.v1 = vMax;
223e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   eBot.v0 = vMin;   eBot.v1 = vMid;
224e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
225a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   /* compute deltas for each edge:  vertex[upper] - vertex[lower] */
226a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   eMaj.dx = FixedToFloat(vMax_fx - vMin_fx);
227a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   eMaj.dy = FixedToFloat(vMax_fy - vMin_fy);
228a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   eTop.dx = FixedToFloat(vMax_fx - vMid_fx);
229a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   eTop.dy = FixedToFloat(vMax_fy - vMid_fy);
230a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   eBot.dx = FixedToFloat(vMid_fx - vMin_fx);
231a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   eBot.dy = FixedToFloat(vMid_fy - vMin_fy);
232e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
233a2162e42280f2aa17a5dfd36b18ff4f6026dade5Brian Paul   /* compute area, oneOverArea and perform backface culling */
234e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   {
235e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
236fcd7c37fd3d0f61cf6ac81170bc0b3fca64ad9bbBrian
23702afd45d3b2eccff5d566cdeb32b3211803bd500Brian      if (IS_INF_OR_NAN(area) || area == 0.0F)
238d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul         return;
239e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
24002afd45d3b2eccff5d566cdeb32b3211803bd500Brian      if (area * bf * swrast->_BackfaceCullSign < 0.0)
241e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         return;
242e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
243ac3958ea1bf8f7b1648f9c1b2ffbe93ffd40b602Brian Paul      oneOverArea = 1.0F / area;
244e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
245fcd7c37fd3d0f61cf6ac81170bc0b3fca64ad9bbBrian      /* 0 = front, 1 = back */
24602afd45d3b2eccff5d566cdeb32b3211803bd500Brian      span.facing = oneOverArea * bf > 0.0F;
247fcd7c37fd3d0f61cf6ac81170bc0b3fca64ad9bbBrian   }
248e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
249e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Edge setup.  For a triangle strip these could be reused... */
250e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   {
251e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      eMaj.fsy = FixedCeil(vMin_fy);
25226d729581fcf1991fbcc8320f64fa40d73170e95Brian Paul      eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy));
253e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (eMaj.lines > 0) {
25484b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul         eMaj.dxdy = eMaj.dx / eMaj.dy;
25584b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul         eMaj.fdxdy = SignedFloatToFixed(eMaj.dxdy);
256e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy);  /* SCALED! */
257e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         eMaj.fx0 = vMin_fx;
25884b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul         eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * eMaj.dxdy);
259e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
260e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
261e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         return;  /*CULLED*/
262e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
263e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
264e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      eTop.fsy = FixedCeil(vMid_fy);
26526d729581fcf1991fbcc8320f64fa40d73170e95Brian Paul      eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy));
266e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (eTop.lines > 0) {
26784b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul         eTop.dxdy = eTop.dx / eTop.dy;
26884b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul         eTop.fdxdy = SignedFloatToFixed(eTop.dxdy);
269e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
270e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         eTop.fx0 = vMid_fx;
27184b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul         eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * eTop.dxdy);
272e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
273e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
274e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      eBot.fsy = FixedCeil(vMin_fy);
27526d729581fcf1991fbcc8320f64fa40d73170e95Brian Paul      eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy));
276e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (eBot.lines > 0) {
27784b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul         eBot.dxdy = eBot.dx / eBot.dy;
27884b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul         eBot.fdxdy = SignedFloatToFixed(eBot.dxdy);
279e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy);  /* SCALED! */
280e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         eBot.fx0 = vMin_fx;
28184b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul         eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * eBot.dxdy);
282e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
283e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
284e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
285e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /*
286e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * Conceptually, we view a triangle as two subtriangles
287e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * separated by a perfectly horizontal line.  The edge that is
288e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * intersected by this line is one with maximal absolute dy; we
289e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * call it a ``major'' edge.  The other two edges are the
290e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * ``top'' edge (for the upper subtriangle) and the ``bottom''
291e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * edge (for the lower subtriangle).  If either of these two
292e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * edges is horizontal or very close to horizontal, the
293e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * corresponding subtriangle might cover zero sample points;
294e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * we take care to handle such cases, for performance as well
295e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * as correctness.
296e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    *
297e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * By stepping rasterization parameters along the major edge,
298e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * we can avoid recomputing them at the discontinuity where
299e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * the top and bottom edges meet.  However, this forces us to
30022144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes    * be able to scan both left-to-right and right-to-left.
301e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * Also, we must determine whether the major edge is at the
302e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * left or right side of the triangle.  We do this by
303e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * computing the magnitude of the cross-product of the major
304e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * and top edges.  Since this magnitude depends on the sine of
305e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * the angle between the two edges, its sign tells us whether
306e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * we turn to the left or to the right when travelling along
307e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * the major edge to the top edge, and from this we infer
308e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * whether the major edge is on the left or the right.
309e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    *
310e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * Serendipitously, this cross-product magnitude is also a
311e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * value we need to compute the iteration parameter
312e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * derivatives for the triangle, and it can be used to perform
313e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * backface culling because its sign tells us whether the
314e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * triangle is clockwise or counterclockwise.  In this code we
315e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * refer to it as ``area'' because it's also proportional to
316e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    * the pixel area of the triangle.
317e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell    */
318e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
319e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   {
320d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul      GLint scan_from_left_to_right;  /* true if scanning left-to-right */
321e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
322e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /*
323e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * Execute user-supplied setup code
324e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       */
325e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef SETUP_CODE
326e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      SETUP_CODE
327e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
328e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
329d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul      scan_from_left_to_right = (oneOverArea < 0.0F);
330e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
3319bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
332e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* compute d?/dx and d?/dy derivatives */
333e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_Z
334a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul      span.interpMask |= SPAN_Z;
335e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      {
3369e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLfloat eMaj_dz = vMax->attrib[FRAG_ATTRIB_WPOS][2] - vMin->attrib[FRAG_ATTRIB_WPOS][2];
3379e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLfloat eBot_dz = vMid->attrib[FRAG_ATTRIB_WPOS][2] - vMin->attrib[FRAG_ATTRIB_WPOS][2];
3389ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.attrStepX[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
3399e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         if (span.attrStepX[FRAG_ATTRIB_WPOS][2] > maxDepth ||
3409e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian             span.attrStepX[FRAG_ATTRIB_WPOS][2] < -maxDepth) {
341e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* probably a sliver triangle */
3429ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian            span.attrStepX[FRAG_ATTRIB_WPOS][2] = 0.0;
3439ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian            span.attrStepY[FRAG_ATTRIB_WPOS][2] = 0.0;
344e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
345e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else {
3469ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian            span.attrStepY[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
347e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
348e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         if (depthBits <= 16)
3499ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian            span.zStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_WPOS][2]);
350e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         else
3519ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian            span.zStep = (GLint) span.attrStepX[FRAG_ATTRIB_WPOS][2];
35254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul      }
35354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#endif
354e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_RGB
355a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul      span.interpMask |= SPAN_RGBA;
356d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul      if (ctx->Light.ShadeModel == GL_SMOOTH) {
3579e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLfloat eMaj_dr = (GLfloat) (vMax->color[RCOMP] - vMin->color[RCOMP]);
3589e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLfloat eBot_dr = (GLfloat) (vMid->color[RCOMP] - vMin->color[RCOMP]);
3599e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLfloat eMaj_dg = (GLfloat) (vMax->color[GCOMP] - vMin->color[GCOMP]);
3609e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLfloat eBot_dg = (GLfloat) (vMid->color[GCOMP] - vMin->color[GCOMP]);
3619e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLfloat eMaj_db = (GLfloat) (vMax->color[BCOMP] - vMin->color[BCOMP]);
3629e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLfloat eBot_db = (GLfloat) (vMid->color[BCOMP] - vMin->color[BCOMP]);
363d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul#  ifdef INTERP_ALPHA
3649e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLfloat eMaj_da = (GLfloat) (vMax->color[ACOMP] - vMin->color[ACOMP]);
3659e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLfloat eBot_da = (GLfloat) (vMid->color[ACOMP] - vMin->color[ACOMP]);
366d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul#  endif
3679ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.attrStepX[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
3689ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.attrStepY[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
3699ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.attrStepX[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
3709ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.attrStepY[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
3719ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.attrStepX[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
3729ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.attrStepY[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
3739ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.redStep   = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][0]);
3749ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.greenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][1]);
3759ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.blueStep  = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][2]);
376d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul#  ifdef INTERP_ALPHA
3779ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.attrStepX[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
37899f24c8d17f3a39ff0ebbeb1f7fa80142d8be648Brian         span.attrStepY[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
3799ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.alphaStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3]);
380dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#  endif /* INTERP_ALPHA */
381d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul      }
382d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul      else {
383daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul         ASSERT(ctx->Light.ShadeModel == GL_FLAT);
384a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul         span.interpMask |= SPAN_FLAT;
3859ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.attrStepX[FRAG_ATTRIB_COL0][0] = span.attrStepY[FRAG_ATTRIB_COL0][0] = 0.0F;
3869ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.attrStepX[FRAG_ATTRIB_COL0][1] = span.attrStepY[FRAG_ATTRIB_COL0][1] = 0.0F;
3879ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.attrStepX[FRAG_ATTRIB_COL0][2] = span.attrStepY[FRAG_ATTRIB_COL0][2] = 0.0F;
388dc24230de7f913969b52dee3579bb8fa3d50a8c0Karl Schultz	 span.redStep   = 0;
389dc24230de7f913969b52dee3579bb8fa3d50a8c0Karl Schultz	 span.greenStep = 0;
390dc24230de7f913969b52dee3579bb8fa3d50a8c0Karl Schultz	 span.blueStep  = 0;
391d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul#  ifdef INTERP_ALPHA
3923d04682b7a729ff4471528a57a6bdf64d235a43eBrian         span.attrStepX[FRAG_ATTRIB_COL0][3] = span.attrStepY[FRAG_ATTRIB_COL0][3] = 0.0F;
393dc24230de7f913969b52dee3579bb8fa3d50a8c0Karl Schultz	 span.alphaStep = 0;
394d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul#  endif
3959bf68ad963ba92b5d1e725f965979042495a5313Brian Paul      }
396dec3ed69e21baa1113938132e344761f39320f5fBrian Paul#endif /* INTERP_RGB */
397e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INT_TEX
398e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      {
399dd34fe8679fa200e55cfaf8e80bbecdecea084e3Brian         GLfloat eMaj_ds = (vMax->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE;
400dd34fe8679fa200e55cfaf8e80bbecdecea084e3Brian         GLfloat eBot_ds = (vMid->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE;
401dd34fe8679fa200e55cfaf8e80bbecdecea084e3Brian         GLfloat eMaj_dt = (vMax->attrib[FRAG_ATTRIB_TEX0][1] - vMin->attrib[FRAG_ATTRIB_TEX0][1]) * T_SCALE;
402dd34fe8679fa200e55cfaf8e80bbecdecea084e3Brian         GLfloat eBot_dt = (vMid->attrib[FRAG_ATTRIB_TEX0][1] - vMin->attrib[FRAG_ATTRIB_TEX0][1]) * T_SCALE;
4039ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.attrStepX[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
4049ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.attrStepY[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
4059ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.attrStepX[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
4069ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.attrStepY[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
4079ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.intTexStep[0] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][0]);
4089ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian         span.intTexStep[1] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][1]);
409e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
410e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
4118a8a5bd104e8cd9362415db77d5f6a3945939589Brian#ifdef INTERP_ATTRIBS
412e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      {
4139e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         /* attrib[FRAG_ATTRIB_WPOS][3] is 1/W */
4149e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         const GLfloat wMax = vMax->attrib[FRAG_ATTRIB_WPOS][3];
4159e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         const GLfloat wMin = vMin->attrib[FRAG_ATTRIB_WPOS][3];
4169e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         const GLfloat wMid = vMid->attrib[FRAG_ATTRIB_WPOS][3];
4179e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         {
4189e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            const GLfloat eMaj_dw = wMax - wMin;
4199e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            const GLfloat eBot_dw = wMid - wMin;
4209e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            span.attrStepX[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw);
4219e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            span.attrStepY[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx);
4229e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         }
4230bdf216dd06d5136b8529297297aa962bab548c2Brian         ATTRIB_LOOP_BEGIN
4249e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            if (swrast->_InterpMode[attr] == GL_FLAT) {
4259e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               ASSIGN_4V(span.attrStepX[attr], 0.0, 0.0, 0.0, 0.0);
4269e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               ASSIGN_4V(span.attrStepY[attr], 0.0, 0.0, 0.0, 0.0);
4279e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            }
4289e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            else {
4299e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               GLuint c;
4309e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               for (c = 0; c < 4; c++) {
4319e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  GLfloat eMaj_da = vMax->attrib[attr][c] * wMax - vMin->attrib[attr][c] * wMin;
4329e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  GLfloat eBot_da = vMid->attrib[attr][c] * wMid - vMin->attrib[attr][c] * wMin;
4339e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  span.attrStepX[attr][c] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
4349e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  span.attrStepY[attr][c] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
4359e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               }
4369e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            }
4370bdf216dd06d5136b8529297297aa962bab548c2Brian         ATTRIB_LOOP_END
438e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
439e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
440e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
441e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /*
442e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * We always sample at pixel centers.  However, we avoid
443e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * explicit half-pixel offsets in this code by incorporating
444e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * the proper offset in each of x and y during the
445e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * transformation to window coordinates.
446e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       *
447e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * We also apply the usual rasterization rules to prevent
448e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * cracks and overlaps.  A pixel is considered inside a
449e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * subtriangle if it meets all of four conditions: it is on or
450e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * to the right of the left edge, strictly to the left of the
451e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * right edge, on or below the top edge, and strictly above
452e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * the bottom edge.  (Some edges may be degenerate.)
453e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       *
454e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * The following discussion assumes left-to-right scanning
455e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * (that is, the major edge is on the left); the right-to-left
456e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * case is a straightforward variation.
457e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       *
458e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * We start by finding the half-integral y coordinate that is
459e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * at or below the top of the triangle.  This gives us the
460e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * first scan line that could possibly contain pixels that are
461e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * inside the triangle.
462e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       *
463e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * Next we creep down the major edge until we reach that y,
46422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes       * and compute the corresponding x coordinate on the edge.
465e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * Then we find the half-integral x that lies on or just
466e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * inside the edge.  This is the first pixel that might lie in
467e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * the interior of the triangle.  (We won't know for sure
468e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * until we check the other edges.)
469e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       *
470e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * As we rasterize the triangle, we'll step down the major
471e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * edge.  For each step in y, we'll move an integer number
472e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * of steps in x.  There are two possible x step sizes, which
473e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * we'll call the ``inner'' step (guaranteed to land on the
474e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * edge or inside it) and the ``outer'' step (guaranteed to
475e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * land on the edge or outside it).  The inner and outer steps
476e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * differ by one.  During rasterization we maintain an error
477e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * term that indicates our distance from the true edge, and
478e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * select either the inner step or the outer step, whichever
479e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * gets us to the first pixel that falls inside the triangle.
480e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       *
481e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * All parameters (z, red, etc.) as well as the buffer
482e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * addresses for color and z have inner and outer step values,
483e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * so that we can increment them appropriately.  This method
484e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * eliminates the need to adjust parameters by creeping a
485e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       * sub-pixel amount into the triangle at each scanline.
486e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell       */
487e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
488e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      {
4897c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul         GLint subTriangle;
4909e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLfixed fxLeftEdge = 0, fxRightEdge = 0;
4919e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
4929e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLfixed fError = 0, fdError = 0;
493e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef PIXEL_ADDRESS
494c5a76cbed41b5816d2f5284f90c70364b062aea4Brian Paul         PIXEL_TYPE *pRow = NULL;
4957c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul         GLint dPRowOuter = 0, dPRowInner;  /* offset in bytes */
496e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
497e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_Z
498e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  ifdef DEPTH_TYPE
499e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         struct gl_renderbuffer *zrb
500e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul            = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
501c5a76cbed41b5816d2f5284f90c70364b062aea4Brian Paul         DEPTH_TYPE *zRow = NULL;
5027c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul         GLint dZRowOuter = 0, dZRowInner;  /* offset in bytes */
503e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  endif
5047265556b9aa0367e9b5031e7cb15ed2a5d73866dBrian Paul         GLuint zLeft = 0;
5057265556b9aa0367e9b5031e7cb15ed2a5d73866dBrian Paul         GLfixed fdzOuter = 0, fdzInner;
50654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#endif
507e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_RGB
5089e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLint rLeft = 0, fdrOuter = 0, fdrInner;
5099e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLint gLeft = 0, fdgOuter = 0, fdgInner;
5109e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLint bLeft = 0, fdbOuter = 0, fdbInner;
5119bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#endif
5129bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#ifdef INTERP_ALPHA
5139e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLint aLeft = 0, fdaOuter = 0, fdaInner;
51496385fa15569e25cd0977e678c0ff3bdab6ef316Brian Paul#endif
515e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INT_TEX
51654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         GLfixed sLeft=0, dsOuter=0, dsInner;
51754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul         GLfixed tLeft=0, dtOuter=0, dtInner;
518e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
5198a8a5bd104e8cd9362415db77d5f6a3945939589Brian#ifdef INTERP_ATTRIBS
5209e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLfloat wLeft = 0, dwOuter = 0, dwInner;
5219e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLfloat attrLeft[FRAG_ATTRIB_MAX][4];
5229e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian         GLfloat daOuter[FRAG_ATTRIB_MAX][4], daInner[FRAG_ATTRIB_MAX][4];
523bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol#endif
524e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
525e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         for (subTriangle=0; subTriangle<=1; subTriangle++) {
526e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            EdgeT *eLeft, *eRight;
527e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            int setupLeft, setupRight;
528e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            int lines;
529e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
530e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            if (subTriangle==0) {
531e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* bottom half */
532d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               if (scan_from_left_to_right) {
533e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  eLeft = &eMaj;
534e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  eRight = &eBot;
535e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  lines = eRight->lines;
536e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  setupLeft = 1;
537e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  setupRight = 1;
538e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
539e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               else {
540e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  eLeft = &eBot;
541e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  eRight = &eMaj;
542e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  lines = eLeft->lines;
543e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  setupLeft = 1;
544e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  setupRight = 1;
545e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
546e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            }
547e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            else {
548e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* top half */
549d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               if (scan_from_left_to_right) {
550e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  eLeft = &eMaj;
551e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  eRight = &eTop;
552e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  lines = eRight->lines;
553e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  setupLeft = 0;
554e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  setupRight = 1;
555e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
556e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               else {
557e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  eLeft = &eTop;
558e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  eRight = &eMaj;
559e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  lines = eLeft->lines;
560e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  setupLeft = 1;
561e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  setupRight = 0;
562e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
563e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               if (lines == 0)
564e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  return;
565e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            }
566e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
567e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            if (setupLeft && eLeft->lines > 0) {
5687c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul               const SWvertex *vLower = eLeft->v0;
5697c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul               const GLfixed fsy = eLeft->fsy;
5707d05e484783cc81d2f9d4ceb2b1e1252555ffef0Brian Paul               const GLfixed fsx = eLeft->fsx;  /* no fractional part */
5717c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul               const GLfixed fx = FixedCeil(fsx);  /* no fractional part */
5729e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               const GLfixed adjx = (GLfixed) (fx - eLeft->fx0); /* SCALED! */
5739e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               const GLfixed adjy = (GLfixed) eLeft->adjy;      /* SCALED! */
5747c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul               GLint idxOuter;
5757c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul               GLfloat dxOuter;
57684b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul               GLfixed fdxOuter;
5777c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul
578e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fError = fx - fsx - FIXED_ONE;
579e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fxLeftEdge = fsx - FIXED_EPSILON;
580e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fdxLeftEdge = eLeft->fdxdy;
581e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fdxOuter = FixedFloor(fdxLeftEdge - FIXED_EPSILON);
582e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fdError = fdxOuter - fdxLeftEdge + FIXED_ONE;
583e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               idxOuter = FixedToInt(fdxOuter);
5847c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul               dxOuter = (GLfloat) idxOuter;
5857c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul               span.y = FixedToInt(fsy);
586e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
5877c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul               /* silence warnings on some compilers */
5887c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul               (void) dxOuter;
5897c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul               (void) adjx;
5907c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul               (void) adjy;
5917c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul               (void) vLower;
592e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
593e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef PIXEL_ADDRESS
594e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               {
5959e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(FixedToInt(fxLeftEdge), span.y);
596e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE);
597e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  /* negative because Y=0 at bottom and increases upward */
598e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
599e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
600e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /*
601e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * Now we need the set of parameter (z, color, etc.) values at
6027c4a61c57fea4c8f112fc22278f643bee2fbaa45Brian Paul                * the point (fx, fsy).  This gives us properly-sampled parameter
603e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * values that we can step from pixel to pixel.  Furthermore,
604e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * although we might have intermediate results that overflow
605e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * the normal parameter range when we step temporarily outside
606e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * the triangle, we shouldn't overflow or underflow for any
607e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * pixel that's actually inside the triangle.
608e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                */
609e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
610e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_Z
611e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               {
6129e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  GLfloat z0 = vLower->attrib[FRAG_ATTRIB_WPOS][2];
613e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  if (depthBits <= 16) {
614e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                     /* interpolate fixed-pt values */
6159ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian                     GLfloat tmp = (z0 * FIXED_SCALE
6169ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian                                    + span.attrStepX[FRAG_ATTRIB_WPOS][2] * adjx
6179ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian                                    + span.attrStepY[FRAG_ATTRIB_WPOS][2] * adjy) + FIXED_HALF;
618e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                     if (tmp < MAX_GLUINT / 2)
61954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                        zLeft = (GLfixed) tmp;
620e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                     else
62154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                        zLeft = MAX_GLUINT / 2;
6229e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                     fdzOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_WPOS][2] +
6239e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                                                   dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
624e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  }
625e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  else {
6267265556b9aa0367e9b5031e7cb15ed2a5d73866dBrian Paul                     /* interpolate depth values w/out scaling */
6279ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian                     zLeft = (GLuint) (z0 + span.attrStepX[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjx)
6289ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian                                          + span.attrStepY[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjy));
6299e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                     fdzOuter = (GLint) (span.attrStepY[FRAG_ATTRIB_WPOS][2] +
6309e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                                         dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]);
631e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  }
632e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  ifdef DEPTH_TYPE
6339bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  zRow = (DEPTH_TYPE *)
6347cf2d75d4f5397629a058b9ea9b20df688b79e5cBrian Paul                    _swrast_pixel_address(zrb, FixedToInt(fxLeftEdge), span.y);
635e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE);
636e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  endif
637e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
63895e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul#endif
639e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_RGB
640d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               if (ctx->Light.ShadeModel == GL_SMOOTH) {
6419e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP])
6429e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                                  + span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx
6439e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                                  + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) + FIXED_HALF;
6449e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP])
6459e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                                  + span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx
6469e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                                  + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) + FIXED_HALF;
6479e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP])
6489e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                                  + span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx
6499e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                                  + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) + FIXED_HALF;
6509e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  fdrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][0]
6519e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                                                + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0]);
6529e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  fdgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][1]
6539e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                                                + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1]);
6549e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  fdbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][2]
6559e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                                                + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2]);
656d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul#  ifdef INTERP_ALPHA
6579e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP])
6589e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                                  + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx
6599e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                                  + span.attrStepY[FRAG_ATTRIB_COL0][3] * adjy) + FIXED_HALF;
6609e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  fdaOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][3]
6619e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                                                + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]);
662d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul#  endif
663d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               }
664d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               else {
665daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul                  ASSERT(ctx->Light.ShadeModel == GL_FLAT);
66654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  rLeft = ChanToFixed(v2->color[RCOMP]);
66754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  gLeft = ChanToFixed(v2->color[GCOMP]);
66854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  bLeft = ChanToFixed(v2->color[BCOMP]);
669d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul                  fdrOuter = fdgOuter = fdbOuter = 0;
670d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul#  ifdef INTERP_ALPHA
67154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  aLeft = ChanToFixed(v2->color[ACOMP]);
672d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul                  fdaOuter = 0;
673d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul#  endif
674d4cff4f2fa43b22effdd5c339bd48508669a0a42Brian Paul               }
675daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul#endif /* INTERP_RGB */
676daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul
677dec3ed69e21baa1113938132e344761f39320f5fBrian Paul
678e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INT_TEX
679e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               {
680e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                  GLfloat s0, t0;
681dd34fe8679fa200e55cfaf8e80bbecdecea084e3Brian                  s0 = vLower->attrib[FRAG_ATTRIB_TEX0][0] * S_SCALE;
6829ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian                  sLeft = (GLfixed)(s0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][0] * adjx
6839ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian                                 + span.attrStepY[FRAG_ATTRIB_TEX0][0] * adjy) + FIXED_HALF;
6849e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  dsOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][0]
6859e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                                               + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][0]);
686e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
687dd34fe8679fa200e55cfaf8e80bbecdecea084e3Brian                  t0 = vLower->attrib[FRAG_ATTRIB_TEX0][1] * T_SCALE;
6889ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian                  tLeft = (GLfixed)(t0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][1] * adjx
6899ab512ad8cf3a12f4f7f8494fa99bc9389f217dbBrian                                 + span.attrStepY[FRAG_ATTRIB_TEX0][1] * adjy) + FIXED_HALF;
6909e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  dtOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][1]
6919e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                                               + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][1]);
692d22554d2cec07d6a8c11d5aef07835aef8d9a030Brian Paul               }
693e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
6948a8a5bd104e8cd9362415db77d5f6a3945939589Brian#ifdef INTERP_ATTRIBS
6959e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               {
6969e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  const GLuint attr = FRAG_ATTRIB_WPOS;
6979e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  wLeft = vLower->attrib[FRAG_ATTRIB_WPOS][3]
6989e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                        + (span.attrStepX[attr][3] * adjx
6999e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                           + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE);
7009e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  dwOuter = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3];
7019e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               }
7020bdf216dd06d5136b8529297297aa962bab548c2Brian               ATTRIB_LOOP_BEGIN
7039e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  const GLfloat invW = vLower->attrib[FRAG_ATTRIB_WPOS][3];
7049e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  if (swrast->_InterpMode[attr] == GL_FLAT) {
7059e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                     GLuint c;
7069e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                     for (c = 0; c < 4; c++) {
7079e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                        attrLeft[attr][c] = v2->attrib[attr][c] * invW;
7089e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                        daOuter[attr][c] = 0.0;
7099e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                     }
7109e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  }
7119e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  else {
7129e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                     GLuint c;
7139e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                     for (c = 0; c < 4; c++) {
7149e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                        const GLfloat a = vLower->attrib[attr][c] * invW;
7159e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                        attrLeft[attr][c] = a + (  span.attrStepX[attr][c] * adjx
7169e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                                                 + span.attrStepY[attr][c] * adjy) * (1.0F/FIXED_SCALE);
7179e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                        daOuter[attr][c] = span.attrStepY[attr][c] + dxOuter * span.attrStepX[attr][c];
7189e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                     }
7199e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  }
7200bdf216dd06d5136b8529297297aa962bab548c2Brian               ATTRIB_LOOP_END
721bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol#endif
722e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            } /*if setupLeft*/
723e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
724e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
725e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            if (setupRight && eRight->lines>0) {
726e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fxRightEdge = eRight->fsx - FIXED_EPSILON;
727e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fdxRightEdge = eRight->fdxdy;
728e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            }
729e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
730e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            if (lines==0) {
731e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               continue;
732e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            }
733e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
734e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
735e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            /* Rasterize setup */
736e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef PIXEL_ADDRESS
737e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            dPRowInner = dPRowOuter + sizeof(PIXEL_TYPE);
738e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
739e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_Z
740e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  ifdef DEPTH_TYPE
741e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            dZRowInner = dZRowOuter + sizeof(DEPTH_TYPE);
742e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  endif
743a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul            fdzInner = fdzOuter + span.zStep;
74495e02a210ed339ad20b0c16284dcdcf9af2dc755Brian Paul#endif
74505ad3078a908f33ab043de784e2961638f819fa0Brian Paul#ifdef INTERP_RGB
746a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul            fdrInner = fdrOuter + span.redStep;
747a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul            fdgInner = fdgOuter + span.greenStep;
748a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul            fdbInner = fdbOuter + span.blueStep;
749e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
75005ad3078a908f33ab043de784e2961638f819fa0Brian Paul#ifdef INTERP_ALPHA
751a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul            fdaInner = fdaOuter + span.alphaStep;
7529bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#endif
753e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INT_TEX
75454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul            dsInner = dsOuter + span.intTexStep[0];
75554e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul            dtInner = dtOuter + span.intTexStep[1];
756e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
7578a8a5bd104e8cd9362415db77d5f6a3945939589Brian#ifdef INTERP_ATTRIBS
7589e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian            dwInner = dwOuter + span.attrStepX[FRAG_ATTRIB_WPOS][3];
7590bdf216dd06d5136b8529297297aa962bab548c2Brian            ATTRIB_LOOP_BEGIN
7609e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               GLuint c;
7619e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               for (c = 0; c < 4; c++) {
7629e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  daInner[attr][c] = daOuter[attr][c] + span.attrStepX[attr][c];
7639e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               }
7640bdf216dd06d5136b8529297297aa962bab548c2Brian            ATTRIB_LOOP_END
765bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol#endif
766e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
7679bf68ad963ba92b5d1e725f965979042495a5313Brian Paul            while (lines > 0) {
768e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* initialize the span interpolants to the leftmost value */
769e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /* ff = fixed-pt fragment */
7709e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               const GLint right = FixedToInt(fxRightEdge);
7719e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               span.x = FixedToInt(fxLeftEdge);
772a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul               if (right <= span.x)
773a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                  span.end = 0;
7749bf68ad963ba92b5d1e725f965979042495a5313Brian Paul               else
775a4ac844979a17e0d6b6967e082974a11884f2655Brian Paul                  span.end = right - span.x;
7769bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
777e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_Z
77854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.z = zLeft;
77954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#endif
78005ad3078a908f33ab043de784e2961638f819fa0Brian Paul#ifdef INTERP_RGB
78154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.red = rLeft;
78254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.green = gLeft;
78354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.blue = bLeft;
784e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
78505ad3078a908f33ab043de784e2961638f819fa0Brian Paul#ifdef INTERP_ALPHA
78654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.alpha = aLeft;
7879bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#endif
788e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INT_TEX
78954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.intTex[0] = sLeft;
79054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul               span.intTex[1] = tLeft;
791e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
7929bf68ad963ba92b5d1e725f965979042495a5313Brian Paul
7938a8a5bd104e8cd9362415db77d5f6a3945939589Brian#ifdef INTERP_ATTRIBS
7949e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian               span.attrStart[FRAG_ATTRIB_WPOS][3] = wLeft;
7950bdf216dd06d5136b8529297297aa962bab548c2Brian               ATTRIB_LOOP_BEGIN
7969e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  GLuint c;
7979e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  for (c = 0; c < 4; c++) {
7989e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                     span.attrStart[attr][c] = attrLeft[attr][c];
7999e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  }
8000bdf216dd06d5136b8529297297aa962bab548c2Brian               ATTRIB_LOOP_END
801bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol#endif
802e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
803daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul               /* This is where we actually generate fragments */
804daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul               /* XXX the test for span.y > 0 _shouldn't_ be needed but
805daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul                * it fixes a problem on 64-bit Opterons (bug 4842).
806daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul                */
807daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul               if (span.end > 0 && span.y >= 0) {
80805ad3078a908f33ab043de784e2961638f819fa0Brian Paul                  const GLint len = span.end - 1;
80905ad3078a908f33ab043de784e2961638f819fa0Brian Paul                  (void) len;
810e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_RGB
811daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul                  CLAMP_INTERPOLANT(red, redStep, len);
812daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul                  CLAMP_INTERPOLANT(green, greenStep, len);
813daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul                  CLAMP_INTERPOLANT(blue, blueStep, len);
814e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
8159bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#ifdef INTERP_ALPHA
816daeb0056df58afaa1a96a1eaea699571205c8d4bBrian Paul                  CLAMP_INTERPOLANT(alpha, alphaStep, len);
817e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
818920023240c2fc42675f318732b43bdc6f339113cBrian Paul                  {
819920023240c2fc42675f318732b43bdc6f339113cBrian Paul                     RENDER_SPAN( span );
820920023240c2fc42675f318732b43bdc6f339113cBrian Paul                  }
8219bf68ad963ba92b5d1e725f965979042495a5313Brian Paul               }
822e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
823e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               /*
824e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * Advance to the next scan line.  Compute the
825e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * new edge coordinates, and adjust the
826e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * pixel-center x coordinate so that it stays
827e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                * on or inside the major edge.
828e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                */
82905ad3078a908f33ab043de784e2961638f819fa0Brian Paul               span.y++;
830e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               lines--;
831e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
832e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fxLeftEdge += fdxLeftEdge;
833e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fxRightEdge += fdxRightEdge;
834e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
835e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               fError += fdError;
836e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               if (fError >= 0) {
8379e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  fError -= FIXED_ONE;
83884b4a3a087a1475d4e9bd713e4bae91ba6363a50Brian Paul
839e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef PIXEL_ADDRESS
8409bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter);
841e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
842e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_Z
843e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  ifdef DEPTH_TYPE
8449bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowOuter);
845e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  endif
84654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  zLeft += fdzOuter;
84754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#endif
84805ad3078a908f33ab043de784e2961638f819fa0Brian Paul#ifdef INTERP_RGB
84954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  rLeft += fdrOuter;
85054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  gLeft += fdgOuter;
85154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  bLeft += fdbOuter;
852e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
85305ad3078a908f33ab043de784e2961638f819fa0Brian Paul#ifdef INTERP_ALPHA
85454e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  aLeft += fdaOuter;
855e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
856e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INT_TEX
85754e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  sLeft += dsOuter;
85854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  tLeft += dtOuter;
859e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
8608a8a5bd104e8cd9362415db77d5f6a3945939589Brian#ifdef INTERP_ATTRIBS
8619e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  wLeft += dwOuter;
8620bdf216dd06d5136b8529297297aa962bab548c2Brian                  ATTRIB_LOOP_BEGIN
8639e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                     GLuint c;
8649e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                     for (c = 0; c < 4; c++) {
8659e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                        attrLeft[attr][c] += daOuter[attr][c];
8669e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                     }
8670bdf216dd06d5136b8529297297aa962bab548c2Brian                  ATTRIB_LOOP_END
868bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol#endif
869e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
870e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               else {
871e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef PIXEL_ADDRESS
8729bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowInner);
873e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
874e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_Z
875e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  ifdef DEPTH_TYPE
8769bf68ad963ba92b5d1e725f965979042495a5313Brian Paul                  zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowInner);
877e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#  endif
87854e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  zLeft += fdzInner;
87954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul#endif
88005ad3078a908f33ab043de784e2961638f819fa0Brian Paul#ifdef INTERP_RGB
88154e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  rLeft += fdrInner;
88254e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  gLeft += fdgInner;
88354e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  bLeft += fdbInner;
884e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
88505ad3078a908f33ab043de784e2961638f819fa0Brian Paul#ifdef INTERP_ALPHA
88654e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  aLeft += fdaInner;
887e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
888e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#ifdef INTERP_INT_TEX
88954e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  sLeft += dsInner;
89054e92e8420a028f07b0971ee8aa93be9b4214579Brian Paul                  tLeft += dtInner;
891e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#endif
8928a8a5bd104e8cd9362415db77d5f6a3945939589Brian#ifdef INTERP_ATTRIBS
8939e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                  wLeft += dwInner;
8940bdf216dd06d5136b8529297297aa962bab548c2Brian                  ATTRIB_LOOP_BEGIN
8959e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                     GLuint c;
8969e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                     for (c = 0; c < 4; c++) {
8979e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                        attrLeft[attr][c] += daInner[attr][c];
8989e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian                     }
8990bdf216dd06d5136b8529297297aa962bab548c2Brian                  ATTRIB_LOOP_END
900bb38cadb1c5f2dc13096a091bdaf61dc3e3cfa4dMichal Krol#endif
901e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell               }
902e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            } /*while lines>0*/
903e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
904e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         } /* for subTriangle */
905e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
906e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
907e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
908e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
909e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
910e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef SETUP_CODE
9119bf68ad963ba92b5d1e725f965979042495a5313Brian Paul#undef RENDER_SPAN
912e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
913e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef PIXEL_TYPE
914e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef BYTES_PER_ROW
915e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef PIXEL_ADDRESS
9162cbbd3dc50eb3656cfabbd948a594e03c8134943Brian Paul#undef DEPTH_TYPE
917e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
918e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef INTERP_Z
919e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef INTERP_RGB
920e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef INTERP_ALPHA
921e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef INTERP_INT_TEX
9228a8a5bd104e8cd9362415db77d5f6a3945939589Brian#undef INTERP_ATTRIBS
923e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
924e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef S_SCALE
925e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef T_SCALE
926e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
927e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#undef FixedToDepth
928e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
929cdf2da368d180205df3573697b51b8764048ad6eBrian Paul#undef NAME
930