s_aatritemp.h revision 7c4268176eaaeb45003db4d5042a518b84c9f6dc
1/* $Id: s_aatritemp.h,v 1.21 2001/09/19 20:30:44 kschultz Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version:  3.5
6 *
7 * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28/*
29 * Antialiased Triangle Rasterizer Template
30 *
31 * This file is #include'd to generate custom AA triangle rasterizers.
32 * NOTE: this code hasn't been optimized yet.  That'll come after it
33 * works correctly.
34 *
35 * The following macros may be defined to indicate what auxillary information
36 * must be copmuted across the triangle:
37 *    DO_Z         - if defined, compute Z values
38 *    DO_RGBA      - if defined, compute RGBA values
39 *    DO_INDEX     - if defined, compute color index values
40 *    DO_SPEC      - if defined, compute specular RGB values
41 *    DO_TEX       - if defined, compute unit 0 STRQ texcoords
42 *    DO_MULTITEX  - if defined, compute all unit's STRQ texcoords
43 */
44
45/*void triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv )*/
46{
47   const GLfloat *p0 = v0->win;
48   const GLfloat *p1 = v1->win;
49   const GLfloat *p2 = v2->win;
50   const SWvertex *vMin, *vMid, *vMax;
51   GLint iyMin, iyMax;
52   GLfloat yMin, yMax;
53   GLboolean ltor;
54   GLfloat majDx, majDy;  /* major (i.e. long) edge dx and dy */
55
56#ifdef DO_Z
57   GLfloat zPlane[4];
58   GLdepth z[MAX_WIDTH];
59#endif
60#ifdef DO_FOG
61   GLfloat fogPlane[4];
62   GLfloat fog[MAX_WIDTH];
63#else
64   GLfloat *fog = NULL;
65#endif
66#ifdef DO_RGBA
67   GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];
68   DEFMARRAY(GLchan, rgba, MAX_WIDTH, 4);  /* mac 32k limitation */
69#endif
70#ifdef DO_INDEX
71   GLfloat iPlane[4];
72   GLuint index[MAX_WIDTH];
73   GLint icoverageSpan[MAX_WIDTH];
74#else
75   GLfloat coverageSpan[MAX_WIDTH];
76#endif
77#ifdef DO_SPEC
78   GLfloat srPlane[4], sgPlane[4], sbPlane[4];
79   DEFMARRAY(GLchan, spec, MAX_WIDTH, 4);
80#endif
81#ifdef DO_TEX
82   GLfloat sPlane[4], tPlane[4], uPlane[4], vPlane[4];
83   GLfloat texWidth, texHeight;
84   DEFARRAY(GLfloat, s, MAX_WIDTH);  /* mac 32k limitation */
85   DEFARRAY(GLfloat, t, MAX_WIDTH);
86   DEFARRAY(GLfloat, u, MAX_WIDTH);
87   DEFARRAY(GLfloat, lambda, MAX_WIDTH);
88#elif defined(DO_MULTITEX)
89   GLfloat sPlane[MAX_TEXTURE_UNITS][4];
90   GLfloat tPlane[MAX_TEXTURE_UNITS][4];
91   GLfloat uPlane[MAX_TEXTURE_UNITS][4];
92   GLfloat vPlane[MAX_TEXTURE_UNITS][4];
93   GLfloat texWidth[MAX_TEXTURE_UNITS], texHeight[MAX_TEXTURE_UNITS];
94   DEFMARRAY(GLfloat, s, MAX_TEXTURE_UNITS, MAX_WIDTH);  /* mac 32k limit */
95   DEFMARRAY(GLfloat, t, MAX_TEXTURE_UNITS, MAX_WIDTH);
96   DEFMARRAY(GLfloat, u, MAX_TEXTURE_UNITS, MAX_WIDTH);
97   DEFMARRAY(GLfloat, lambda, MAX_TEXTURE_UNITS, MAX_WIDTH);
98#endif
99   GLfloat bf = SWRAST_CONTEXT(ctx)->_backface_sign;
100
101#ifdef DO_RGBA
102   CHECKARRAY(rgba, return);  /* mac 32k limitation */
103#endif
104#ifdef DO_SPEC
105   CHECKARRAY(spec, return);
106#endif
107#if defined(DO_TEX) || defined(DO_MULTITEX)
108   CHECKARRAY(s, return);
109   CHECKARRAY(t, return);
110   CHECKARRAY(u, return);
111   CHECKARRAY(lambda, return);
112#endif
113
114   /* determine bottom to top order of vertices */
115   {
116      GLfloat y0 = v0->win[1];
117      GLfloat y1 = v1->win[1];
118      GLfloat y2 = v2->win[1];
119      if (y0 <= y1) {
120	 if (y1 <= y2) {
121	    vMin = v0;   vMid = v1;   vMax = v2;   /* y0<=y1<=y2 */
122	 }
123	 else if (y2 <= y0) {
124	    vMin = v2;   vMid = v0;   vMax = v1;   /* y2<=y0<=y1 */
125	 }
126	 else {
127	    vMin = v0;   vMid = v2;   vMax = v1;  bf = -bf; /* y0<=y2<=y1 */
128	 }
129      }
130      else {
131	 if (y0 <= y2) {
132	    vMin = v1;   vMid = v0;   vMax = v2;  bf = -bf; /* y1<=y0<=y2 */
133	 }
134	 else if (y2 <= y1) {
135	    vMin = v2;   vMid = v1;   vMax = v0;  bf = -bf; /* y2<=y1<=y0 */
136	 }
137	 else {
138	    vMin = v1;   vMid = v2;   vMax = v0;   /* y1<=y2<=y0 */
139	 }
140      }
141   }
142
143   majDx = vMax->win[0] - vMin->win[0];
144   majDy = vMax->win[1] - vMin->win[1];
145
146   {
147      const GLfloat botDx = vMid->win[0] - vMin->win[0];
148      const GLfloat botDy = vMid->win[1] - vMin->win[1];
149      const GLfloat area = majDx * botDy - botDx * majDy;
150      ltor = (GLboolean) (area < 0.0F);
151      /* Do backface culling */
152      if (area * bf < 0 || area * area < .0025)
153	 return;
154   }
155
156#ifndef DO_OCCLUSION_TEST
157   ctx->OcclusionResult = GL_TRUE;
158#endif
159
160   /* Plane equation setup:
161    * We evaluate plane equations at window (x,y) coordinates in order
162    * to compute color, Z, fog, texcoords, etc.  This isn't terribly
163    * efficient but it's easy and reliable.
164    */
165#ifdef DO_Z
166   compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
167#endif
168#ifdef DO_FOG
169   compute_plane(p0, p1, p2, v0->fog, v1->fog, v2->fog, fogPlane);
170#endif
171#ifdef DO_RGBA
172   if (ctx->Light.ShadeModel == GL_SMOOTH) {
173      compute_plane(p0, p1, p2, v0->color[0], v1->color[0], v2->color[0], rPlane);
174      compute_plane(p0, p1, p2, v0->color[1], v1->color[1], v2->color[1], gPlane);
175      compute_plane(p0, p1, p2, v0->color[2], v1->color[2], v2->color[2], bPlane);
176      compute_plane(p0, p1, p2, v0->color[3], v1->color[3], v2->color[3], aPlane);
177   }
178   else {
179      constant_plane(v2->color[RCOMP], rPlane);
180      constant_plane(v2->color[GCOMP], gPlane);
181      constant_plane(v2->color[BCOMP], bPlane);
182      constant_plane(v2->color[ACOMP], aPlane);
183   }
184#endif
185#ifdef DO_INDEX
186   if (ctx->Light.ShadeModel == GL_SMOOTH) {
187      compute_plane(p0, p1, p2, (GLfloat) v0->index,
188                    (GLfloat) v1->index, (GLfloat) v2->index, iPlane);
189   }
190   else {
191      constant_plane((GLfloat) v2->index, iPlane);
192   }
193#endif
194#ifdef DO_SPEC
195   if (ctx->Light.ShadeModel == GL_SMOOTH) {
196      compute_plane(p0, p1, p2, v0->specular[0], v1->specular[0], v2->specular[0],srPlane);
197      compute_plane(p0, p1, p2, v0->specular[1], v1->specular[1], v2->specular[1],sgPlane);
198      compute_plane(p0, p1, p2, v0->specular[2], v1->specular[2], v2->specular[2],sbPlane);
199   }
200   else {
201      constant_plane(v2->specular[RCOMP], srPlane);
202      constant_plane(v2->specular[GCOMP], sgPlane);
203      constant_plane(v2->specular[BCOMP], sbPlane);
204   }
205#endif
206#ifdef DO_TEX
207   {
208      const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
209      const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];
210      const GLfloat invW0 = v0->win[3];
211      const GLfloat invW1 = v1->win[3];
212      const GLfloat invW2 = v2->win[3];
213      const GLfloat s0 = v0->texcoord[0][0] * invW0;
214      const GLfloat s1 = v1->texcoord[0][0] * invW1;
215      const GLfloat s2 = v2->texcoord[0][0] * invW2;
216      const GLfloat t0 = v0->texcoord[0][1] * invW0;
217      const GLfloat t1 = v1->texcoord[0][1] * invW1;
218      const GLfloat t2 = v2->texcoord[0][1] * invW2;
219      const GLfloat r0 = v0->texcoord[0][2] * invW0;
220      const GLfloat r1 = v1->texcoord[0][2] * invW1;
221      const GLfloat r2 = v2->texcoord[0][2] * invW2;
222      const GLfloat q0 = v0->texcoord[0][3] * invW0;
223      const GLfloat q1 = v1->texcoord[0][3] * invW1;
224      const GLfloat q2 = v2->texcoord[0][3] * invW2;
225      compute_plane(p0, p1, p2, s0, s1, s2, sPlane);
226      compute_plane(p0, p1, p2, t0, t1, t2, tPlane);
227      compute_plane(p0, p1, p2, r0, r1, r2, uPlane);
228      compute_plane(p0, p1, p2, q0, q1, q2, vPlane);
229      texWidth = (GLfloat) texImage->Width;
230      texHeight = (GLfloat) texImage->Height;
231   }
232#elif defined(DO_MULTITEX)
233   {
234      GLuint u;
235      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
236         if (ctx->Texture.Unit[u]._ReallyEnabled) {
237            const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;
238            const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];
239            const GLfloat invW0 = v0->win[3];
240            const GLfloat invW1 = v1->win[3];
241            const GLfloat invW2 = v2->win[3];
242            const GLfloat s0 = v0->texcoord[u][0] * invW0;
243            const GLfloat s1 = v1->texcoord[u][0] * invW1;
244            const GLfloat s2 = v2->texcoord[u][0] * invW2;
245            const GLfloat t0 = v0->texcoord[u][1] * invW0;
246            const GLfloat t1 = v1->texcoord[u][1] * invW1;
247            const GLfloat t2 = v2->texcoord[u][1] * invW2;
248            const GLfloat r0 = v0->texcoord[u][2] * invW0;
249            const GLfloat r1 = v1->texcoord[u][2] * invW1;
250            const GLfloat r2 = v2->texcoord[u][2] * invW2;
251            const GLfloat q0 = v0->texcoord[u][3] * invW0;
252            const GLfloat q1 = v1->texcoord[u][3] * invW1;
253            const GLfloat q2 = v2->texcoord[u][3] * invW2;
254            compute_plane(p0, p1, p2, s0, s1, s2, sPlane[u]);
255            compute_plane(p0, p1, p2, t0, t1, t2, tPlane[u]);
256            compute_plane(p0, p1, p2, r0, r1, r2, uPlane[u]);
257            compute_plane(p0, p1, p2, q0, q1, q2, vPlane[u]);
258            texWidth[u]  = (GLfloat) texImage->Width;
259            texHeight[u] = (GLfloat) texImage->Height;
260         }
261      }
262   }
263#endif
264
265   /* Begin bottom-to-top scan over the triangle.
266    * The long edge will either be on the left or right side of the
267    * triangle.  We always scan from the long edge toward the shorter
268    * edges, stopping when we find that coverage = 0.  If the long edge
269    * is on the left we scan left-to-right.  Else, we scan right-to-left.
270    */
271   yMin = vMin->win[1];
272   yMax = vMax->win[1];
273   iyMin = (GLint) yMin;
274   iyMax = (GLint) yMax + 1;
275
276   if (ltor) {
277      /* scan left to right */
278      const GLfloat *pMin = vMin->win;
279      const GLfloat *pMid = vMid->win;
280      const GLfloat *pMax = vMax->win;
281      const GLfloat dxdy = majDx / majDy;
282      const GLfloat xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
283      GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
284      GLint iy;
285      for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
286         GLint ix, startX = (GLint) (x - xAdj);
287         GLuint count, n;
288         GLfloat coverage = 0.0F;
289         /* skip over fragments with zero coverage */
290         while (startX < MAX_WIDTH) {
291            coverage = compute_coveragef(pMin, pMid, pMax, startX, iy);
292            if (coverage > 0.0F)
293               break;
294            startX++;
295         }
296
297         /* enter interior of triangle */
298         ix = startX;
299         count = 0;
300         while (coverage > 0.0F) {
301            /* (cx,cy) = center of fragment */
302            const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
303#ifdef DO_INDEX
304            icoverageSpan[count] = compute_coveragei(pMin, pMid, pMax, ix, iy);
305#else
306            coverageSpan[count] = coverage;
307#endif
308#ifdef DO_Z
309            z[count] = (GLdepth) solve_plane(cx, cy, zPlane);
310#endif
311#ifdef DO_FOG
312	    fog[count] = solve_plane(cx, cy, fogPlane);
313#endif
314#ifdef DO_RGBA
315            rgba[count][RCOMP] = solve_plane_chan(cx, cy, rPlane);
316            rgba[count][GCOMP] = solve_plane_chan(cx, cy, gPlane);
317            rgba[count][BCOMP] = solve_plane_chan(cx, cy, bPlane);
318            rgba[count][ACOMP] = solve_plane_chan(cx, cy, aPlane);
319#endif
320#ifdef DO_INDEX
321            index[count] = (GLint) solve_plane(cx, cy, iPlane);
322#endif
323#ifdef DO_SPEC
324            spec[count][RCOMP] = solve_plane_chan(cx, cy, srPlane);
325            spec[count][GCOMP] = solve_plane_chan(cx, cy, sgPlane);
326            spec[count][BCOMP] = solve_plane_chan(cx, cy, sbPlane);
327#endif
328#ifdef DO_TEX
329            {
330               const GLfloat invQ = solve_plane_recip(cx, cy, vPlane);
331               s[count] = solve_plane(cx, cy, sPlane) * invQ;
332               t[count] = solve_plane(cx, cy, tPlane) * invQ;
333               u[count] = solve_plane(cx, cy, uPlane) * invQ;
334               lambda[count] = compute_lambda(sPlane, tPlane, invQ,
335                                                 texWidth, texHeight);
336            }
337#elif defined(DO_MULTITEX)
338            {
339               GLuint unit;
340               for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
341                  if (ctx->Texture.Unit[unit]._ReallyEnabled) {
342                     GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]);
343                     s[unit][count] = solve_plane(cx, cy, sPlane[unit]) * invQ;
344                     t[unit][count] = solve_plane(cx, cy, tPlane[unit]) * invQ;
345                     u[unit][count] = solve_plane(cx, cy, uPlane[unit]) * invQ;
346                     lambda[unit][count] = compute_lambda(sPlane[unit],
347                          tPlane[unit], invQ, texWidth[unit], texHeight[unit]);
348                  }
349               }
350            }
351#endif
352            ix++;
353            count++;
354            coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
355         }
356
357         if (ix <= startX)
358            continue;
359
360         n = (GLuint) ix - (GLuint) startX;
361
362#ifdef DO_MULTITEX
363#  ifdef DO_SPEC
364         _mesa_write_multitexture_span(ctx, n, startX, iy, z, fog,
365                                       (const GLfloat (*)[MAX_WIDTH]) s,
366                                       (const GLfloat (*)[MAX_WIDTH]) t,
367                                       (const GLfloat (*)[MAX_WIDTH]) u,
368                                       (GLfloat (*)[MAX_WIDTH]) lambda,
369                                       rgba, (const GLchan (*)[4]) spec,
370                                       coverageSpan,  GL_POLYGON);
371#  else
372         _mesa_write_multitexture_span(ctx, n, startX, iy, z, fog,
373                                       (const GLfloat (*)[MAX_WIDTH]) s,
374                                       (const GLfloat (*)[MAX_WIDTH]) t,
375                                       (const GLfloat (*)[MAX_WIDTH]) u,
376                                       lambda, rgba, NULL, coverageSpan,
377                                       GL_POLYGON);
378#  endif
379#elif defined(DO_TEX)
380#  ifdef DO_SPEC
381         _mesa_write_texture_span(ctx, n, startX, iy, z, fog,
382                                  s, t, u, lambda, rgba,
383                                  (const GLchan (*)[4]) spec,
384                                  coverageSpan, GL_POLYGON);
385#  else
386         _mesa_write_texture_span(ctx, n, startX, iy, z, fog,
387                                  s, t, u, lambda,
388                                  rgba, NULL, coverageSpan, GL_POLYGON);
389#  endif
390#elif defined(DO_RGBA)
391         _mesa_write_rgba_span(ctx, n, startX, iy, z, fog, rgba,
392                               coverageSpan, GL_POLYGON);
393#elif defined(DO_INDEX)
394         _mesa_write_index_span(ctx, n, startX, iy, z, fog, index,
395                                icoverageSpan, GL_POLYGON);
396#endif
397      }
398   }
399   else {
400      /* scan right to left */
401      const GLfloat *pMin = vMin->win;
402      const GLfloat *pMid = vMid->win;
403      const GLfloat *pMax = vMax->win;
404      const GLfloat dxdy = majDx / majDy;
405      const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
406      GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
407      GLint iy;
408      for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
409         GLint ix, left, startX = (GLint) (x + xAdj);
410         GLuint count, n;
411         GLfloat coverage = 0.0F;
412
413         /* make sure we're not past the window edge */
414         if (startX >= ctx->DrawBuffer->_Xmax) {
415            startX = ctx->DrawBuffer->_Xmax - 1;
416         }
417
418         /* skip fragments with zero coverage */
419         while (startX >= 0) {
420            coverage = compute_coveragef(pMin, pMax, pMid, startX, iy);
421            if (coverage > 0.0F)
422               break;
423            startX--;
424         }
425
426         /* enter interior of triangle */
427         ix = startX;
428         count = 0;
429         while (coverage > 0.0F) {
430            /* (cx,cy) = center of fragment */
431            const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
432#ifdef DO_INDEX
433            icoverageSpan[ix] = compute_coveragei(pMin, pMid, pMax, ix, iy);
434#else
435            coverageSpan[ix] = coverage;
436#endif
437#ifdef DO_Z
438            z[ix] = (GLdepth) solve_plane(cx, cy, zPlane);
439#endif
440#ifdef DO_FOG
441            fog[ix] = solve_plane(cx, cy, fogPlane);
442#endif
443#ifdef DO_RGBA
444            rgba[ix][RCOMP] = solve_plane_chan(cx, cy, rPlane);
445            rgba[ix][GCOMP] = solve_plane_chan(cx, cy, gPlane);
446            rgba[ix][BCOMP] = solve_plane_chan(cx, cy, bPlane);
447            rgba[ix][ACOMP] = solve_plane_chan(cx, cy, aPlane);
448#endif
449#ifdef DO_INDEX
450            index[ix] = (GLint) solve_plane(cx, cy, iPlane);
451#endif
452#ifdef DO_SPEC
453            spec[ix][RCOMP] = solve_plane_chan(cx, cy, srPlane);
454            spec[ix][GCOMP] = solve_plane_chan(cx, cy, sgPlane);
455            spec[ix][BCOMP] = solve_plane_chan(cx, cy, sbPlane);
456#endif
457#ifdef DO_TEX
458            {
459               const GLfloat invQ = solve_plane_recip(cx, cy, vPlane);
460               s[ix] = solve_plane(cx, cy, sPlane) * invQ;
461               t[ix] = solve_plane(cx, cy, tPlane) * invQ;
462               u[ix] = solve_plane(cx, cy, uPlane) * invQ;
463               lambda[ix] = compute_lambda(sPlane, tPlane, invQ,
464                                              texWidth, texHeight);
465            }
466#elif defined(DO_MULTITEX)
467            {
468               GLuint unit;
469               for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
470                  if (ctx->Texture.Unit[unit]._ReallyEnabled) {
471                     GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]);
472                     s[unit][ix] = solve_plane(cx, cy, sPlane[unit]) * invQ;
473                     t[unit][ix] = solve_plane(cx, cy, tPlane[unit]) * invQ;
474                     u[unit][ix] = solve_plane(cx, cy, uPlane[unit]) * invQ;
475                     lambda[unit][ix] = compute_lambda(sPlane[unit],
476                         tPlane[unit], invQ, texWidth[unit], texHeight[unit]);
477                  }
478               }
479            }
480#endif
481            ix--;
482            count++;
483            coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
484         }
485
486         if (startX <= ix)
487            continue;
488
489         n = (GLuint) startX - (GLuint) ix;
490
491         left = ix + 1;
492#ifdef DO_MULTITEX
493         {
494            GLuint unit;
495            for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
496               if (ctx->Texture.Unit[unit]._ReallyEnabled) {
497                  GLint j;
498                  for (j = 0; j < (GLint) n; j++) {
499                     s[unit][j] = s[unit][j + left];
500                     t[unit][j] = t[unit][j + left];
501                     u[unit][j] = u[unit][j + left];
502                     lambda[unit][j] = lambda[unit][j + left];
503                  }
504               }
505            }
506         }
507#  ifdef DO_SPEC
508         _mesa_write_multitexture_span(ctx, n, left, iy, z + left, fog + left,
509                                       (const GLfloat (*)[MAX_WIDTH]) s,
510                                       (const GLfloat (*)[MAX_WIDTH]) t,
511                                       (const GLfloat (*)[MAX_WIDTH]) u,
512                                       lambda, rgba + left,
513                                       (const GLchan (*)[4]) (spec + left),
514                                       coverageSpan + left,
515                                       GL_POLYGON);
516#  else
517         _mesa_write_multitexture_span(ctx, n, left, iy, z + left, fog + left,
518                                       (const GLfloat (*)[MAX_WIDTH]) s,
519                                       (const GLfloat (*)[MAX_WIDTH]) t,
520                                       (const GLfloat (*)[MAX_WIDTH]) u,
521                                       lambda,
522                                       rgba + left, NULL, coverageSpan + left,
523                                       GL_POLYGON);
524#  endif
525#elif defined(DO_TEX)
526#  ifdef DO_SPEC
527         _mesa_write_texture_span(ctx, n, left, iy, z + left, fog + left,
528                                  s + left, t + left, u + left,
529                                  lambda + left, rgba + left,
530                                  (const GLchan (*)[4]) (spec + left),
531                                  coverageSpan + left,
532                                  GL_POLYGON);
533#  else
534         _mesa_write_texture_span(ctx, n, left, iy, z + left, fog + left,
535                                  s + left, t + left,
536                                  u + left, lambda + left,
537                                  rgba + left, NULL,
538                                  coverageSpan + left, GL_POLYGON);
539#  endif
540#elif defined(DO_RGBA)
541         _mesa_write_rgba_span(ctx, n, left, iy, z + left, fog + left,
542                               rgba + left, coverageSpan + left, GL_POLYGON);
543#elif defined(DO_INDEX)
544         _mesa_write_index_span(ctx, n, left, iy, z + left, fog + left,
545                               index + left, icoverageSpan + left, GL_POLYGON);
546#endif
547      }
548   }
549
550#ifdef DO_RGBA
551   UNDEFARRAY(rgba);  /* mac 32k limitation */
552#endif
553#ifdef DO_SPEC
554   UNDEFARRAY(spec);
555#endif
556#if defined(DO_TEX) || defined(DO_MULTITEX)
557   UNDEFARRAY(s);
558   UNDEFARRAY(t);
559   UNDEFARRAY(u);
560   UNDEFARRAY(lambda);
561#endif
562}
563
564
565#ifdef DO_Z
566#undef DO_Z
567#endif
568
569#ifdef DO_FOG
570#undef DO_FOG
571#endif
572
573#ifdef DO_RGBA
574#undef DO_RGBA
575#endif
576
577#ifdef DO_INDEX
578#undef DO_INDEX
579#endif
580
581#ifdef DO_SPEC
582#undef DO_SPEC
583#endif
584
585#ifdef DO_TEX
586#undef DO_TEX
587#endif
588
589#ifdef DO_MULTITEX
590#undef DO_MULTITEX
591#endif
592
593#ifdef DO_OCCLUSION_TEST
594#undef DO_OCCLUSION_TEST
595#endif
596