Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / tnl_dd / t_dd_tritmp.h
1 /*
2  * Mesa 3-D graphics library
3  * Version:  6.3
4  *
5  * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *    Keith Whitwell <keith@tungstengraphics.com>
26  */
27
28
29 /* Template for building functions to plug into the driver interface
30  * of t_vb_render.c:
31  *     ctx->Driver.QuadFunc
32  *     ctx->Driver.TriangleFunc
33  *     ctx->Driver.LineFunc
34  *     ctx->Driver.PointsFunc
35  *
36  * DO_TWOSIDE:   Plug back-color values from the VB into backfacing triangles,
37  *               and restore vertices afterwards.
38  * DO_OFFSET:    Calculate offset for triangles and adjust vertices.  Restore
39  *               vertices after rendering.
40  * DO_FLAT:      For hardware without native flatshading, copy provoking colors
41  *               into the other vertices.  Restore after rendering.
42  * DO_UNFILLED:  Decompose triangles to lines and points where appropriate.
43  * DO_TWOSTENCIL:Gross hack for two-sided stencil.
44  *
45  * HAVE_SPEC: Vertices have secondary rgba values.
46  *
47  * VERT_X(v): Alias for vertex x value.
48  * VERT_Y(v): Alias for vertex y value.
49  * VERT_Z(v): Alias for vertex z value.
50  * DEPTH_SCALE: Scale for constant offset.
51  * REVERSE_DEPTH: Viewport depth range reversed.
52  *
53  * VERTEX: Hardware vertex type.
54  * GET_VERTEX(n): Retreive vertex with index n.
55  * AREA_IS_CCW(a): Return true if triangle with signed area a is ccw.
56  *
57  * VERT_SET_RGBA: Assign vertex rgba from VB color.
58  * VERT_COPY_RGBA: Copy vertex rgba another vertex.
59  * VERT_SAVE_RGBA: Save vertex rgba to a local variable.
60  * VERT_RESTORE_RGBA: Restore vertex rgba from a local variable.
61  *   --> Similar for SPEC.
62  *
63  * LOCAL_VARS(n): (At least) define local vars for save/restore rgba.
64  *
65  */
66
67 #if HAVE_BACK_COLORS
68 #define VERT_SET_RGBA( v, c )
69 #endif
70
71 #if !HAVE_SPEC
72 #define VERT_SET_SPEC( v, c ) (void) c
73 #define VERT_COPY_SPEC( v0, v1 )
74 #define VERT_SAVE_SPEC( idx )
75 #define VERT_RESTORE_SPEC( idx )
76 #if HAVE_BACK_COLORS
77 #define VERT_COPY_SPEC1( v )
78 #endif
79 #else
80 #if HAVE_BACK_COLORS
81 #define VERT_SET_SPEC( v, c )
82 #endif
83 #endif
84
85 #if !HAVE_BACK_COLORS
86 #define VERT_COPY_SPEC1( v )
87 #define VERT_COPY_RGBA1( v )
88 #endif
89
90 #ifndef INSANE_VERTICES
91 #define VERT_SET_Z(v,val) VERT_Z(v) = val
92 #define VERT_Z_ADD(v,val) VERT_Z(v) += val
93 #endif
94
95 #ifndef REVERSE_DEPTH
96 #define REVERSE_DEPTH 0
97 #endif
98
99 /* disable twostencil for un-aware drivers */
100 #ifndef HAVE_STENCIL_TWOSIDE
101 #define HAVE_STENCIL_TWOSIDE 0
102 #endif
103 #ifndef DO_TWOSTENCIL
104 #define DO_TWOSTENCIL 0
105 #endif
106 #ifndef SETUP_STENCIL
107 #define SETUP_STENCIL(f)
108 #endif
109 #ifndef UNSET_STENCIL
110 #define UNSET_STENCIL(f)
111 #endif
112
113 #if DO_TRI
114 static void TAG(triangle)( struct gl_context *ctx, GLuint e0, GLuint e1, GLuint e2 )
115 {
116    struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
117    VERTEX *v[3];
118    GLfloat offset = 0;
119    GLfloat z[3] = { 0 };
120    GLenum mode = GL_FILL;
121    GLuint facing = 0;
122    LOCAL_VARS(3);
123
124 /*     fprintf(stderr, "%s\n", __FUNCTION__); */
125
126    v[0] = (VERTEX *)GET_VERTEX(e0);
127    v[1] = (VERTEX *)GET_VERTEX(e1);
128    v[2] = (VERTEX *)GET_VERTEX(e2);
129
130    if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED || DO_TWOSTENCIL)
131    {
132       GLfloat ex = VERT_X(v[0]) - VERT_X(v[2]);
133       GLfloat ey = VERT_Y(v[0]) - VERT_Y(v[2]);
134       GLfloat fx = VERT_X(v[1]) - VERT_X(v[2]);
135       GLfloat fy = VERT_Y(v[1]) - VERT_Y(v[2]);
136       GLfloat cc = ex*fy - ey*fx;
137
138       if (DO_TWOSIDE || DO_UNFILLED || DO_TWOSTENCIL)
139       {
140          facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit;
141
142          if (DO_UNFILLED) {
143             if (facing) {
144                mode = ctx->Polygon.BackMode;
145                if (ctx->Polygon.CullFlag &&
146                    ctx->Polygon.CullFaceMode != GL_FRONT) {
147                   return;
148                }
149             } else {
150                mode = ctx->Polygon.FrontMode;
151                if (ctx->Polygon.CullFlag &&
152                    ctx->Polygon.CullFaceMode != GL_BACK) {
153                   return;
154                }
155             }
156          }
157
158          if (DO_TWOSIDE && facing == 1) {
159             if (HAVE_BACK_COLORS) {
160                if (!DO_FLAT) {
161                   VERT_SAVE_RGBA( 0 );
162                   VERT_SAVE_RGBA( 1 );
163                   VERT_COPY_RGBA1( v[0] );
164                   VERT_COPY_RGBA1( v[1] );
165                }
166                VERT_SAVE_RGBA( 2 );
167                VERT_COPY_RGBA1( v[2] );
168                if (HAVE_SPEC) {
169                   if (!DO_FLAT) {
170                      VERT_SAVE_SPEC( 0 );
171                      VERT_SAVE_SPEC( 1 );
172                      VERT_COPY_SPEC1( v[0] );
173                      VERT_COPY_SPEC1( v[1] );
174                   }
175                   VERT_SAVE_SPEC( 2 );
176                   VERT_COPY_SPEC1( v[2] );
177                }
178             }
179             else {
180                GLfloat (*vbcolor)[4] = VB->BackfaceColorPtr->data;
181                (void) vbcolor;
182
183                if (!DO_FLAT) {
184                   VERT_SAVE_RGBA( 0 );
185                   VERT_SAVE_RGBA( 1 );
186                }
187                VERT_SAVE_RGBA( 2 );
188
189                if (VB->BackfaceColorPtr->stride) {
190                   ASSERT(VB->BackfaceColorPtr->stride == 4*sizeof(GLfloat));
191
192                   if (!DO_FLAT) {
193                      VERT_SET_RGBA( v[0], vbcolor[e0] );
194                      VERT_SET_RGBA( v[1], vbcolor[e1] );
195                   }
196                   VERT_SET_RGBA( v[2], vbcolor[e2] );
197                }
198                else {
199                   if (!DO_FLAT) {
200                      VERT_SET_RGBA( v[0], vbcolor[0] );
201                      VERT_SET_RGBA( v[1], vbcolor[0] );
202                   }
203                   VERT_SET_RGBA( v[2], vbcolor[0] );
204                }
205
206                if (HAVE_SPEC && VB->BackfaceSecondaryColorPtr) {
207                   GLfloat (*vbspec)[4] = VB->BackfaceSecondaryColorPtr->data;
208                   ASSERT(VB->BackfaceSecondaryColorPtr->stride == 4*sizeof(GLfloat));
209
210                   if (!DO_FLAT) {
211                      VERT_SAVE_SPEC( 0 );
212                      VERT_SAVE_SPEC( 1 );
213                      VERT_SET_SPEC( v[0], vbspec[e0] );
214                      VERT_SET_SPEC( v[1], vbspec[e1] );
215                   }
216                   VERT_SAVE_SPEC( 2 );
217                   VERT_SET_SPEC( v[2], vbspec[e2] );
218                }
219             }
220          }
221       }
222
223
224       if (DO_OFFSET)
225       {
226          offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
227          z[0] = VERT_Z(v[0]);
228          z[1] = VERT_Z(v[1]);
229          z[2] = VERT_Z(v[2]);
230          if (cc * cc > 1e-16) {
231             GLfloat ic  = 1.0 / cc;
232             GLfloat ez  = z[0] - z[2];
233             GLfloat fz  = z[1] - z[2];
234             GLfloat a   = ey*fz - ez*fy;
235             GLfloat b   = ez*fx - ex*fz;
236             GLfloat ac  = a * ic;
237             GLfloat bc  = b * ic;
238             if ( ac < 0.0f ) ac = -ac;
239             if ( bc < 0.0f ) bc = -bc;
240             offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor / ctx->DrawBuffer->_MRD;
241          }
242          offset *= ctx->DrawBuffer->_MRD * (REVERSE_DEPTH ? -1.0 : 1.0);
243       }
244    }
245
246    if (DO_FLAT) {
247       VERT_SAVE_RGBA( 0 );
248       VERT_SAVE_RGBA( 1 );
249       VERT_COPY_RGBA( v[0], v[2] );
250       VERT_COPY_RGBA( v[1], v[2] );
251       if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
252          VERT_SAVE_SPEC( 0 );
253          VERT_SAVE_SPEC( 1 );
254          VERT_COPY_SPEC( v[0], v[2] );
255          VERT_COPY_SPEC( v[1], v[2] );
256       }
257    }
258
259    if (mode == GL_POINT) {
260       if (DO_OFFSET && ctx->Polygon.OffsetPoint) {
261          VERT_Z_ADD(v[0], offset);
262          VERT_Z_ADD(v[1], offset);
263          VERT_Z_ADD(v[2], offset);
264       }
265       if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
266          SETUP_STENCIL(facing);
267          UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 );
268          UNSET_STENCIL(facing);
269       } else {
270          UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 );
271       }
272    } else if (mode == GL_LINE) {
273       if (DO_OFFSET && ctx->Polygon.OffsetLine) {
274          VERT_Z_ADD(v[0], offset);
275          VERT_Z_ADD(v[1], offset);
276          VERT_Z_ADD(v[2], offset);
277       }
278       if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
279          SETUP_STENCIL(facing);
280          UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 );
281          UNSET_STENCIL(facing);
282       } else {
283          UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 );
284       }
285    } else {
286       if (DO_OFFSET && ctx->Polygon.OffsetFill) {
287          VERT_Z_ADD(v[0], offset);
288          VERT_Z_ADD(v[1], offset);
289          VERT_Z_ADD(v[2], offset);
290       }
291       if (DO_UNFILLED)
292          RASTERIZE( GL_TRIANGLES );
293       if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
294          SETUP_STENCIL(facing);
295          TRI( v[0], v[1], v[2] );
296          UNSET_STENCIL(facing);
297       } else {
298          TRI( v[0], v[1], v[2] );
299       }
300    }
301
302    if (DO_OFFSET)
303    {
304       VERT_SET_Z(v[0], z[0]);
305       VERT_SET_Z(v[1], z[1]);
306       VERT_SET_Z(v[2], z[2]);
307    }
308
309    if (DO_TWOSIDE && facing == 1) {
310       if (!DO_FLAT) {
311          VERT_RESTORE_RGBA( 0 );
312          VERT_RESTORE_RGBA( 1 );
313       }
314       VERT_RESTORE_RGBA( 2 );
315       if (HAVE_SPEC) {
316          if (!DO_FLAT) {
317             VERT_RESTORE_SPEC( 0 );
318             VERT_RESTORE_SPEC( 1 );
319          }
320          VERT_RESTORE_SPEC( 2 );
321       }
322    }
323
324
325    if (DO_FLAT) {
326          VERT_RESTORE_RGBA( 0 );
327          VERT_RESTORE_RGBA( 1 );
328          if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
329             VERT_RESTORE_SPEC( 0 );
330             VERT_RESTORE_SPEC( 1 );
331          }
332    }
333 }
334 #endif
335
336 #if DO_QUAD
337 #if DO_FULL_QUAD
338 static void TAG(quadr)( struct gl_context *ctx,
339                        GLuint e0, GLuint e1, GLuint e2, GLuint e3 )
340 {
341    struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
342    VERTEX *v[4];
343    GLfloat offset = 0;
344    GLfloat z[4] = { 0 };
345    GLenum mode = GL_FILL;
346    GLuint facing = 0;
347    LOCAL_VARS(4);
348
349    v[0] = (VERTEX *)GET_VERTEX(e0);
350    v[1] = (VERTEX *)GET_VERTEX(e1);
351    v[2] = (VERTEX *)GET_VERTEX(e2);
352    v[3] = (VERTEX *)GET_VERTEX(e3);
353
354    if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED || DO_TWOSTENCIL)
355    {
356       GLfloat ex = VERT_X(v[2]) - VERT_X(v[0]);
357       GLfloat ey = VERT_Y(v[2]) - VERT_Y(v[0]);
358       GLfloat fx = VERT_X(v[3]) - VERT_X(v[1]);
359       GLfloat fy = VERT_Y(v[3]) - VERT_Y(v[1]);
360       GLfloat cc = ex*fy - ey*fx;
361
362       if (DO_TWOSIDE || DO_UNFILLED || DO_TWOSTENCIL)
363       {
364          facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit;
365
366          if (DO_UNFILLED) {
367             if (facing) {
368                mode = ctx->Polygon.BackMode;
369                if (ctx->Polygon.CullFlag &&
370                    ctx->Polygon.CullFaceMode != GL_FRONT) {
371                   return;
372                }
373             } else {
374                mode = ctx->Polygon.FrontMode;
375                if (ctx->Polygon.CullFlag &&
376                    ctx->Polygon.CullFaceMode != GL_BACK) {
377                   return;
378                }
379             }
380          }
381
382          if (DO_TWOSIDE && facing == 1) {
383             GLfloat (*vbcolor)[4] = VB->BackfaceColorPtr->data;
384             (void)vbcolor;
385
386             if (HAVE_BACK_COLORS) {
387                if (!DO_FLAT) {
388                   VERT_SAVE_RGBA( 0 );
389                   VERT_SAVE_RGBA( 1 );
390                   VERT_SAVE_RGBA( 2 );
391                   VERT_COPY_RGBA1( v[0] );
392                   VERT_COPY_RGBA1( v[1] );
393                   VERT_COPY_RGBA1( v[2] );
394                }
395                VERT_SAVE_RGBA( 3 );
396                VERT_COPY_RGBA1( v[3] );
397                if (HAVE_SPEC) {
398                   if (!DO_FLAT) {
399                      VERT_SAVE_SPEC( 0 );
400                      VERT_SAVE_SPEC( 1 );
401                      VERT_SAVE_SPEC( 2 );
402                      VERT_COPY_SPEC1( v[0] );
403                      VERT_COPY_SPEC1( v[1] );
404                      VERT_COPY_SPEC1( v[2] );
405                   }
406                   VERT_SAVE_SPEC( 3 );
407                   VERT_COPY_SPEC1( v[3] );
408                }
409             }
410             else {
411                if (!DO_FLAT) {
412                   VERT_SAVE_RGBA( 0 );
413                   VERT_SAVE_RGBA( 1 );
414                   VERT_SAVE_RGBA( 2 );
415                }
416                VERT_SAVE_RGBA( 3 );
417
418                if (VB->BackfaceColorPtr->stride) {
419                   if (!DO_FLAT) {
420                      VERT_SET_RGBA( v[0], vbcolor[e0] );
421                      VERT_SET_RGBA( v[1], vbcolor[e1] );
422                      VERT_SET_RGBA( v[2], vbcolor[e2] );
423                   }
424                   VERT_SET_RGBA( v[3], vbcolor[e3] );
425                }
426                else {
427                   if (!DO_FLAT) {
428                      VERT_SET_RGBA( v[0], vbcolor[0] );
429                      VERT_SET_RGBA( v[1], vbcolor[0] );
430                      VERT_SET_RGBA( v[2], vbcolor[0] );
431                   }
432                   VERT_SET_RGBA( v[3], vbcolor[0] );
433                }
434
435                if (HAVE_SPEC && VB->BackfaceSecondaryColorPtr) {
436                   GLfloat (*vbspec)[4] = VB->BackfaceSecondaryColorPtr->data;
437                   ASSERT(VB->BackfaceSecondaryColorPtr->stride==4*sizeof(GLfloat));
438
439                   if (!DO_FLAT) {
440                      VERT_SAVE_SPEC( 0 );
441                      VERT_SAVE_SPEC( 1 );
442                      VERT_SAVE_SPEC( 2 );
443                      VERT_SET_SPEC( v[0], vbspec[e0] );
444                      VERT_SET_SPEC( v[1], vbspec[e1] );
445                      VERT_SET_SPEC( v[2], vbspec[e2] );
446                   }
447                   VERT_SAVE_SPEC( 3 );
448                   VERT_SET_SPEC( v[3], vbspec[e3] );
449                }
450             }
451          }
452       }
453
454
455       if (DO_OFFSET)
456       {
457          offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
458          z[0] = VERT_Z(v[0]);
459          z[1] = VERT_Z(v[1]);
460          z[2] = VERT_Z(v[2]);
461          z[3] = VERT_Z(v[3]);
462          if (cc * cc > 1e-16) {
463             GLfloat ez = z[2] - z[0];
464             GLfloat fz = z[3] - z[1];
465             GLfloat a   = ey*fz - ez*fy;
466             GLfloat b   = ez*fx - ex*fz;
467             GLfloat ic  = 1.0 / cc;
468             GLfloat ac  = a * ic;
469             GLfloat bc  = b * ic;
470             if ( ac < 0.0f ) ac = -ac;
471             if ( bc < 0.0f ) bc = -bc;
472             offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor / ctx->DrawBuffer->_MRD;
473          }
474          offset *= ctx->DrawBuffer->_MRD * (REVERSE_DEPTH ? -1.0 : 1.0);
475       }
476    }
477
478    if (DO_FLAT) {
479          VERT_SAVE_RGBA( 0 );
480          VERT_SAVE_RGBA( 1 );
481          VERT_SAVE_RGBA( 2 );
482          VERT_COPY_RGBA( v[0], v[3] );
483          VERT_COPY_RGBA( v[1], v[3] );
484          VERT_COPY_RGBA( v[2], v[3] );
485          if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
486             VERT_SAVE_SPEC( 0 );
487             VERT_SAVE_SPEC( 1 );
488             VERT_SAVE_SPEC( 2 );
489             VERT_COPY_SPEC( v[0], v[3] );
490             VERT_COPY_SPEC( v[1], v[3] );
491             VERT_COPY_SPEC( v[2], v[3] );
492          }
493    }
494
495    if (mode == GL_POINT) {
496       if (( DO_OFFSET) && ctx->Polygon.OffsetPoint) {
497          VERT_Z_ADD(v[0], offset);
498          VERT_Z_ADD(v[1], offset);
499          VERT_Z_ADD(v[2], offset);
500          VERT_Z_ADD(v[3], offset);
501       }
502       if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
503          SETUP_STENCIL(facing);
504          UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 );
505          UNSET_STENCIL(facing);
506       } else {
507          UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 );
508       }
509    } else if (mode == GL_LINE) {
510       if (DO_OFFSET && ctx->Polygon.OffsetLine) {
511          VERT_Z_ADD(v[0], offset);
512          VERT_Z_ADD(v[1], offset);
513          VERT_Z_ADD(v[2], offset);
514          VERT_Z_ADD(v[3], offset);
515       }
516       if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
517          SETUP_STENCIL(facing);
518          UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 );
519          UNSET_STENCIL(facing);
520       } else {
521          UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 );
522       }
523    } else {
524       if (DO_OFFSET && ctx->Polygon.OffsetFill) {
525          VERT_Z_ADD(v[0], offset);
526          VERT_Z_ADD(v[1], offset);
527          VERT_Z_ADD(v[2], offset);
528          VERT_Z_ADD(v[3], offset);
529       }
530       RASTERIZE( GL_QUADS );
531       if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
532          SETUP_STENCIL(facing);
533          QUAD( (v[0]), (v[1]), (v[2]), (v[3]) );
534          UNSET_STENCIL(facing);
535       } else {
536          QUAD( (v[0]), (v[1]), (v[2]), (v[3]) );
537       }
538    }
539
540    if (DO_OFFSET)
541    {
542       VERT_SET_Z(v[0], z[0]);
543       VERT_SET_Z(v[1], z[1]);
544       VERT_SET_Z(v[2], z[2]);
545       VERT_SET_Z(v[3], z[3]);
546    }
547
548    if (DO_TWOSIDE && facing == 1) {
549       if (!DO_FLAT) {
550          VERT_RESTORE_RGBA( 0 );
551          VERT_RESTORE_RGBA( 1 );
552          VERT_RESTORE_RGBA( 2 );
553       }
554       VERT_RESTORE_RGBA( 3 );
555       if (HAVE_SPEC) {
556          if (!DO_FLAT) {
557             VERT_RESTORE_SPEC( 0 );
558             VERT_RESTORE_SPEC( 1 );
559             VERT_RESTORE_SPEC( 2 );
560          }
561          VERT_RESTORE_SPEC( 3 );
562       }
563    }
564
565
566    if (DO_FLAT) {
567          VERT_RESTORE_RGBA( 0 );
568          VERT_RESTORE_RGBA( 1 );
569          VERT_RESTORE_RGBA( 2 );
570          if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
571             VERT_RESTORE_SPEC( 0 );
572             VERT_RESTORE_SPEC( 1 );
573             VERT_RESTORE_SPEC( 2 );
574          }
575    }
576 }
577 #else
578 static void TAG(quadr)( struct gl_context *ctx, GLuint e0,
579                        GLuint e1, GLuint e2, GLuint e3 )
580 {
581    if (DO_UNFILLED) {
582       struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
583       GLubyte ef1 = VB->EdgeFlag[e1];
584       GLubyte ef3 = VB->EdgeFlag[e3];
585       VB->EdgeFlag[e1] = 0;
586       TAG(triangle)( ctx, e0, e1, e3 );
587       VB->EdgeFlag[e1] = ef1;
588       VB->EdgeFlag[e3] = 0;
589       TAG(triangle)( ctx, e1, e2, e3 );
590       VB->EdgeFlag[e3] = ef3;
591    } else {
592       TAG(triangle)( ctx, e0, e1, e3 );
593       TAG(triangle)( ctx, e1, e2, e3 );
594    }
595 }
596 #endif
597 #endif
598
599 #if DO_LINE
600 static void TAG(line)( struct gl_context *ctx, GLuint e0, GLuint e1 )
601 {
602    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
603    VERTEX *v[2];
604    LOCAL_VARS(2);
605
606    v[0] = (VERTEX *)GET_VERTEX(e0);
607    v[1] = (VERTEX *)GET_VERTEX(e1);
608
609    if (DO_FLAT) {
610          VERT_SAVE_RGBA( 0 );
611          VERT_COPY_RGBA( v[0], v[1] );
612          if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
613             VERT_SAVE_SPEC( 0 );
614             VERT_COPY_SPEC( v[0], v[1] );
615          }
616    }
617
618    LINE( v[0], v[1] );
619
620    if (DO_FLAT) {
621          VERT_RESTORE_RGBA( 0 );
622
623          if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
624             VERT_RESTORE_SPEC( 0 );
625          }
626    }
627 }
628 #endif
629
630 #if DO_POINTS
631 static void TAG(points)( struct gl_context *ctx, GLuint first, GLuint last )
632 {
633    struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
634    GLuint i;
635    LOCAL_VARS(1);
636
637    if (VB->Elts == 0) {
638       for ( i = first ; i < last ; i++ ) {
639          if ( VB->ClipMask[i] == 0 ) {
640             VERTEX *v = (VERTEX *)GET_VERTEX(i);
641             POINT( v );
642          }
643       }
644    } else {
645       for ( i = first ; i < last ; i++ ) {
646          GLuint e = VB->Elts[i];
647          if ( VB->ClipMask[e] == 0 ) {
648             VERTEX *v = (VERTEX *)GET_VERTEX(e);
649             POINT( v );
650          }
651       }
652    }
653 }
654 #endif
655
656 static void TAG(init)( void )
657 {
658 #if DO_QUAD
659    TAB[IND].quad = TAG(quadr);
660 #endif
661 #if DO_TRI
662    TAB[IND].triangle = TAG(triangle);
663 #endif
664 #if DO_LINE
665    TAB[IND].line = TAG(line);
666 #endif
667 #if DO_POINTS
668    TAB[IND].points = TAG(points);
669 #endif
670 }
671
672 #undef IND
673 #undef TAG
674
675 #if HAVE_BACK_COLORS
676 #undef VERT_SET_RGBA
677 #endif
678
679 #if !HAVE_SPEC
680 #undef VERT_SET_SPEC
681 #undef VERT_COPY_SPEC
682 #undef VERT_SAVE_SPEC
683 #undef VERT_RESTORE_SPEC
684 #if HAVE_BACK_COLORS
685 #undef VERT_COPY_SPEC1
686 #endif
687 #else
688 #if HAVE_BACK_COLORS
689 #undef VERT_SET_SPEC
690 #endif
691 #endif
692
693 #if !HAVE_BACK_COLORS
694 #undef VERT_COPY_SPEC1
695 #undef VERT_COPY_RGBA1
696 #endif
697
698 #ifndef INSANE_VERTICES
699 #undef VERT_SET_Z
700 #undef VERT_Z_ADD
701 #endif