1848b8605Smrg/*
2848b8605Smrg * Mesa 3-D graphics library
3848b8605Smrg *
4848b8605Smrg * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
5848b8605Smrg *
6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
7848b8605Smrg * copy of this software and associated documentation files (the "Software"),
8848b8605Smrg * to deal in the Software without restriction, including without limitation
9848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the
11848b8605Smrg * Software is furnished to do so, subject to the following conditions:
12848b8605Smrg *
13848b8605Smrg * The above copyright notice and this permission notice shall be included
14848b8605Smrg * in all copies or substantial portions of the Software.
15848b8605Smrg *
16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE.
23848b8605Smrg *
24848b8605Smrg * Authors:
25848b8605Smrg *    Keith Whitwell <keithw@vmware.com>
26848b8605Smrg */
27848b8605Smrg
28848b8605Smrg
29848b8605Smrg#ifndef POSTFIX
30848b8605Smrg#define POSTFIX
31848b8605Smrg#endif
32848b8605Smrg
33848b8605Smrg#ifndef INIT
34848b8605Smrg#define INIT(x)
35848b8605Smrg#endif
36848b8605Smrg
37848b8605Smrg#ifndef NEED_EDGEFLAG_SETUP
38848b8605Smrg#define NEED_EDGEFLAG_SETUP 0
39848b8605Smrg#define EDGEFLAG_GET(a) 0
40848b8605Smrg#define EDGEFLAG_SET(a,b) (void)b
41848b8605Smrg#endif
42848b8605Smrg
43848b8605Smrg#ifndef RESET_STIPPLE
44848b8605Smrg#define RESET_STIPPLE
45848b8605Smrg#endif
46848b8605Smrg
47848b8605Smrg#ifndef TEST_PRIM_END
48848b8605Smrg#define TEST_PRIM_END(prim) (flags & PRIM_END)
49848b8605Smrg#define TEST_PRIM_BEGIN(prim) (flags & PRIM_BEGIN)
50848b8605Smrg#endif
51848b8605Smrg
52848b8605Smrg#ifndef ELT
53848b8605Smrg#define ELT(x) x
54848b8605Smrg#endif
55848b8605Smrg
56848b8605Smrg#ifndef RENDER_TAB_QUALIFIER
57848b8605Smrg#define RENDER_TAB_QUALIFIER static
58848b8605Smrg#endif
59848b8605Smrg
60848b8605Smrgstatic void TAG(render_points)( struct gl_context *ctx,
61848b8605Smrg				GLuint start,
62848b8605Smrg				GLuint count,
63848b8605Smrg				GLuint flags )
64848b8605Smrg{
65848b8605Smrg   LOCAL_VARS;
66848b8605Smrg   (void) flags;
67848b8605Smrg
68848b8605Smrg   INIT(GL_POINTS);
69848b8605Smrg   RENDER_POINTS( start, count );
70848b8605Smrg   POSTFIX;
71848b8605Smrg}
72848b8605Smrg
73848b8605Smrgstatic void TAG(render_lines)( struct gl_context *ctx,
74848b8605Smrg			       GLuint start,
75848b8605Smrg			       GLuint count,
76848b8605Smrg			       GLuint flags )
77848b8605Smrg{
78848b8605Smrg   GLuint j;
79848b8605Smrg   LOCAL_VARS;
80848b8605Smrg   (void) flags;
81848b8605Smrg
82848b8605Smrg   INIT(GL_LINES);
83848b8605Smrg   for (j=start+1; j<count; j+=2 ) {
84848b8605Smrg      RESET_STIPPLE;
85848b8605Smrg      if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
86848b8605Smrg         RENDER_LINE( ELT(j-1), ELT(j) );
87848b8605Smrg      else
88848b8605Smrg         RENDER_LINE( ELT(j), ELT(j-1) );
89848b8605Smrg   }
90848b8605Smrg   POSTFIX;
91848b8605Smrg}
92848b8605Smrg
93848b8605Smrg
94848b8605Smrgstatic void TAG(render_line_strip)( struct gl_context *ctx,
95848b8605Smrg				    GLuint start,
96848b8605Smrg				    GLuint count,
97848b8605Smrg				    GLuint flags )
98848b8605Smrg{
99848b8605Smrg   GLuint j;
100848b8605Smrg   LOCAL_VARS;
101848b8605Smrg   (void) flags;
102848b8605Smrg
103848b8605Smrg   INIT(GL_LINE_STRIP);
104848b8605Smrg
105848b8605Smrg   if (TEST_PRIM_BEGIN(flags)) {
106848b8605Smrg      RESET_STIPPLE;
107848b8605Smrg   }
108848b8605Smrg
109848b8605Smrg   for (j=start+1; j<count; j++ ) {
110848b8605Smrg      if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
111848b8605Smrg         RENDER_LINE( ELT(j-1), ELT(j) );
112848b8605Smrg      else
113848b8605Smrg         RENDER_LINE( ELT(j), ELT(j-1) );
114848b8605Smrg   }
115848b8605Smrg   POSTFIX;
116848b8605Smrg}
117848b8605Smrg
118848b8605Smrg
119848b8605Smrgstatic void TAG(render_line_loop)( struct gl_context *ctx,
120848b8605Smrg				   GLuint start,
121848b8605Smrg				   GLuint count,
122848b8605Smrg				   GLuint flags )
123848b8605Smrg{
124848b8605Smrg   GLuint i;
125848b8605Smrg   LOCAL_VARS;
126848b8605Smrg
127848b8605Smrg   INIT(GL_LINE_LOOP);
128848b8605Smrg
129848b8605Smrg   if (start+1 < count) {
130848b8605Smrg      if (TEST_PRIM_BEGIN(flags)) {
131848b8605Smrg	 RESET_STIPPLE;
132b8e80941Smrg         /* draw the first line from v[0] to v[1] */
133848b8605Smrg         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
134848b8605Smrg            RENDER_LINE( ELT(start), ELT(start+1) );
135848b8605Smrg         else
136848b8605Smrg            RENDER_LINE( ELT(start+1), ELT(start) );
137848b8605Smrg      }
138848b8605Smrg
139b8e80941Smrg      /* draw lines from v[1] to v[n-1] */
140848b8605Smrg      for ( i = start+2 ; i < count ; i++) {
141848b8605Smrg         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
142848b8605Smrg            RENDER_LINE( ELT(i-1), ELT(i) );
143848b8605Smrg         else
144848b8605Smrg            RENDER_LINE( ELT(i), ELT(i-1) );
145848b8605Smrg      }
146848b8605Smrg
147848b8605Smrg      if ( TEST_PRIM_END(flags)) {
148b8e80941Smrg         /* draw final line from v[n-1] to v[0] (the very first vertex) */
149848b8605Smrg         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
150848b8605Smrg            RENDER_LINE( ELT(count-1), ELT(start) );
151848b8605Smrg         else
152848b8605Smrg            RENDER_LINE( ELT(start), ELT(count-1) );
153848b8605Smrg      }
154848b8605Smrg   }
155848b8605Smrg
156848b8605Smrg   POSTFIX;
157848b8605Smrg}
158848b8605Smrg
159848b8605Smrg
160848b8605Smrgstatic void TAG(render_triangles)( struct gl_context *ctx,
161848b8605Smrg				   GLuint start,
162848b8605Smrg				   GLuint count,
163848b8605Smrg				   GLuint flags )
164848b8605Smrg{
165848b8605Smrg   GLuint j;
166848b8605Smrg   LOCAL_VARS;
167848b8605Smrg   (void) flags;
168848b8605Smrg
169848b8605Smrg   INIT(GL_TRIANGLES);
170848b8605Smrg   if (NEED_EDGEFLAG_SETUP) {
171848b8605Smrg      for (j=start+2; j<count; j+=3) {
172848b8605Smrg	 /* Leave the edgeflags as supplied by the user.
173848b8605Smrg	  */
174848b8605Smrg	 RESET_STIPPLE;
175848b8605Smrg         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
176848b8605Smrg            RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
177848b8605Smrg         else
178848b8605Smrg            RENDER_TRI( ELT(j-1), ELT(j), ELT(j-2) );
179848b8605Smrg      }
180848b8605Smrg   } else {
181848b8605Smrg      for (j=start+2; j<count; j+=3) {
182848b8605Smrg         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
183848b8605Smrg            RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
184848b8605Smrg         else
185848b8605Smrg            RENDER_TRI( ELT(j-1), ELT(j), ELT(j-2) );
186848b8605Smrg      }
187848b8605Smrg   }
188848b8605Smrg   POSTFIX;
189848b8605Smrg}
190848b8605Smrg
191848b8605Smrg
192848b8605Smrg
193848b8605Smrgstatic void TAG(render_tri_strip)( struct gl_context *ctx,
194848b8605Smrg				   GLuint start,
195848b8605Smrg				   GLuint count,
196848b8605Smrg				   GLuint flags )
197848b8605Smrg{
198848b8605Smrg   GLuint j;
199848b8605Smrg   GLuint parity = 0;
200848b8605Smrg   LOCAL_VARS;
201848b8605Smrg
202848b8605Smrg   INIT(GL_TRIANGLE_STRIP);
203848b8605Smrg   if (NEED_EDGEFLAG_SETUP) {
204848b8605Smrg      for (j=start+2;j<count;j++,parity^=1) {
205848b8605Smrg         GLuint ej2, ej1, ej;
206848b8605Smrg         GLboolean ef2, ef1, ef;
207848b8605Smrg         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT) {
208848b8605Smrg            ej2 = ELT(j-2+parity);
209848b8605Smrg            ej1 = ELT(j-1-parity);
210848b8605Smrg            ej = ELT(j);
211848b8605Smrg         }
212848b8605Smrg         else {
213848b8605Smrg            ej2 = ELT(j-1+parity);
214848b8605Smrg            ej1 = ELT(j-parity);
215848b8605Smrg            ej = ELT(j-2);
216848b8605Smrg         }
217848b8605Smrg	 ef2 = EDGEFLAG_GET( ej2 );
218848b8605Smrg	 ef1 = EDGEFLAG_GET( ej1 );
219848b8605Smrg	 ef = EDGEFLAG_GET( ej );
220848b8605Smrg	 if (TEST_PRIM_BEGIN(flags)) {
221848b8605Smrg	    RESET_STIPPLE;
222848b8605Smrg	 }
223848b8605Smrg	 EDGEFLAG_SET( ej2, GL_TRUE );
224848b8605Smrg	 EDGEFLAG_SET( ej1, GL_TRUE );
225848b8605Smrg	 EDGEFLAG_SET( ej, GL_TRUE );
226848b8605Smrg         RENDER_TRI( ej2, ej1, ej );
227848b8605Smrg	 EDGEFLAG_SET( ej2, ef2 );
228848b8605Smrg	 EDGEFLAG_SET( ej1, ef1 );
229848b8605Smrg	 EDGEFLAG_SET( ej, ef );
230848b8605Smrg      }
231848b8605Smrg   } else {
232848b8605Smrg      for (j=start+2; j<count ; j++, parity^=1) {
233848b8605Smrg         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
234848b8605Smrg            RENDER_TRI( ELT(j-2+parity), ELT(j-1-parity), ELT(j) );
235848b8605Smrg         else
236848b8605Smrg            RENDER_TRI( ELT(j-1+parity), ELT(j-parity), ELT(j-2) );
237848b8605Smrg      }
238848b8605Smrg   }
239848b8605Smrg   POSTFIX;
240848b8605Smrg}
241848b8605Smrg
242848b8605Smrg
243848b8605Smrgstatic void TAG(render_tri_fan)( struct gl_context *ctx,
244848b8605Smrg				 GLuint start,
245848b8605Smrg				 GLuint count,
246848b8605Smrg				 GLuint flags )
247848b8605Smrg{
248848b8605Smrg   GLuint j;
249848b8605Smrg   LOCAL_VARS;
250848b8605Smrg   (void) flags;
251848b8605Smrg
252848b8605Smrg   INIT(GL_TRIANGLE_FAN);
253848b8605Smrg   if (NEED_EDGEFLAG_SETUP) {
254848b8605Smrg      for (j=start+2;j<count;j++) {
255848b8605Smrg	 /* For trifans, all edges are boundary.
256848b8605Smrg	  */
257848b8605Smrg	 GLuint ejs = ELT(start);
258848b8605Smrg	 GLuint ej1 = ELT(j-1);
259848b8605Smrg	 GLuint ej = ELT(j);
260848b8605Smrg	 GLboolean efs = EDGEFLAG_GET( ejs );
261848b8605Smrg	 GLboolean ef1 = EDGEFLAG_GET( ej1 );
262848b8605Smrg	 GLboolean ef = EDGEFLAG_GET( ej );
263848b8605Smrg	 if (TEST_PRIM_BEGIN(flags)) {
264848b8605Smrg	    RESET_STIPPLE;
265848b8605Smrg	 }
266848b8605Smrg	 EDGEFLAG_SET( ejs, GL_TRUE );
267848b8605Smrg	 EDGEFLAG_SET( ej1, GL_TRUE );
268848b8605Smrg	 EDGEFLAG_SET( ej, GL_TRUE );
269848b8605Smrg         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
270848b8605Smrg            RENDER_TRI( ejs, ej1, ej);
271848b8605Smrg         else
272848b8605Smrg            RENDER_TRI( ej, ejs, ej1);
273848b8605Smrg	 EDGEFLAG_SET( ejs, efs );
274848b8605Smrg	 EDGEFLAG_SET( ej1, ef1 );
275848b8605Smrg	 EDGEFLAG_SET( ej, ef );
276848b8605Smrg      }
277848b8605Smrg   } else {
278848b8605Smrg      for (j=start+2;j<count;j++) {
279848b8605Smrg         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT)
280848b8605Smrg            RENDER_TRI( ELT(start), ELT(j-1), ELT(j) );
281848b8605Smrg         else
282848b8605Smrg            RENDER_TRI( ELT(j), ELT(start), ELT(j-1) );
283848b8605Smrg      }
284848b8605Smrg   }
285848b8605Smrg
286848b8605Smrg   POSTFIX;
287848b8605Smrg}
288848b8605Smrg
289848b8605Smrg
290848b8605Smrgstatic void TAG(render_poly)( struct gl_context *ctx,
291848b8605Smrg			      GLuint start,
292848b8605Smrg			      GLuint count,
293848b8605Smrg			      GLuint flags )
294848b8605Smrg{
295848b8605Smrg   GLuint j = start+2;
296848b8605Smrg   LOCAL_VARS;
297848b8605Smrg   (void) flags;
298848b8605Smrg
299848b8605Smrg   INIT(GL_POLYGON);
300848b8605Smrg   if (NEED_EDGEFLAG_SETUP) {
301848b8605Smrg      GLboolean efstart = EDGEFLAG_GET( ELT(start) );
302848b8605Smrg      GLboolean efcount = EDGEFLAG_GET( ELT(count-1) );
303848b8605Smrg
304848b8605Smrg      /* If the primitive does not begin here, the first edge
305848b8605Smrg       * is non-boundary.
306848b8605Smrg       */
307848b8605Smrg      if (!TEST_PRIM_BEGIN(flags))
308848b8605Smrg	 EDGEFLAG_SET( ELT(start), GL_FALSE );
309848b8605Smrg      else {
310848b8605Smrg	 RESET_STIPPLE;
311848b8605Smrg      }
312848b8605Smrg
313848b8605Smrg      /* If the primitive does not end here, the final edge is
314848b8605Smrg       * non-boundary.
315848b8605Smrg       */
316848b8605Smrg      if (!TEST_PRIM_END(flags))
317848b8605Smrg	 EDGEFLAG_SET( ELT(count-1), GL_FALSE );
318848b8605Smrg
319848b8605Smrg      /* Draw the first triangles (possibly zero)
320848b8605Smrg       */
321848b8605Smrg      if (j+1<count) {
322848b8605Smrg	 GLboolean ef = EDGEFLAG_GET( ELT(j) );
323848b8605Smrg	 EDGEFLAG_SET( ELT(j), GL_FALSE );
324848b8605Smrg	 RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
325848b8605Smrg	 EDGEFLAG_SET( ELT(j), ef );
326848b8605Smrg	 j++;
327848b8605Smrg
328848b8605Smrg	 /* Don't render the first edge again:
329848b8605Smrg	  */
330848b8605Smrg	 EDGEFLAG_SET( ELT(start), GL_FALSE );
331848b8605Smrg
332848b8605Smrg	 for (;j+1<count;j++) {
333848b8605Smrg	    GLboolean efj = EDGEFLAG_GET( ELT(j) );
334848b8605Smrg	    EDGEFLAG_SET( ELT(j), GL_FALSE );
335848b8605Smrg	    RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
336848b8605Smrg	    EDGEFLAG_SET( ELT(j), efj );
337848b8605Smrg	 }
338848b8605Smrg      }
339848b8605Smrg
340848b8605Smrg      /* Draw the last or only triangle
341848b8605Smrg       */
342848b8605Smrg      if (j < count)
343848b8605Smrg	 RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
344848b8605Smrg
345848b8605Smrg      /* Restore the first and last edgeflags:
346848b8605Smrg       */
347848b8605Smrg      EDGEFLAG_SET( ELT(count-1), efcount );
348848b8605Smrg      EDGEFLAG_SET( ELT(start), efstart );
349848b8605Smrg
350848b8605Smrg   }
351848b8605Smrg   else {
352848b8605Smrg      for (j=start+2;j<count;j++) {
353848b8605Smrg	 RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
354848b8605Smrg      }
355848b8605Smrg   }
356848b8605Smrg   POSTFIX;
357848b8605Smrg}
358848b8605Smrg
359848b8605Smrgstatic void TAG(render_quads)( struct gl_context *ctx,
360848b8605Smrg			       GLuint start,
361848b8605Smrg			       GLuint count,
362848b8605Smrg			       GLuint flags )
363848b8605Smrg{
364848b8605Smrg   GLuint j;
365848b8605Smrg   LOCAL_VARS;
366848b8605Smrg   (void) flags;
367848b8605Smrg
368848b8605Smrg   INIT(GL_QUADS);
369848b8605Smrg   if (NEED_EDGEFLAG_SETUP) {
370848b8605Smrg      for (j=start+3; j<count; j+=4) {
371848b8605Smrg	 /* Use user-specified edgeflags for quads.
372848b8605Smrg	  */
373848b8605Smrg	 RESET_STIPPLE;
374848b8605Smrg         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT ||
375848b8605Smrg             !ctx->Const.QuadsFollowProvokingVertexConvention)
376848b8605Smrg            RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
377848b8605Smrg         else
378848b8605Smrg            RENDER_QUAD( ELT(j-2), ELT(j-1), ELT(j), ELT(j-3) );
379848b8605Smrg      }
380848b8605Smrg   } else {
381848b8605Smrg      for (j=start+3; j<count; j+=4) {
382848b8605Smrg         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT ||
383848b8605Smrg             !ctx->Const.QuadsFollowProvokingVertexConvention)
384848b8605Smrg            RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
385848b8605Smrg         else
386848b8605Smrg            RENDER_QUAD( ELT(j-2), ELT(j-1), ELT(j), ELT(j-3) );
387848b8605Smrg      }
388848b8605Smrg   }
389848b8605Smrg   POSTFIX;
390848b8605Smrg}
391848b8605Smrg
392848b8605Smrgstatic void TAG(render_quad_strip)( struct gl_context *ctx,
393848b8605Smrg				    GLuint start,
394848b8605Smrg				    GLuint count,
395848b8605Smrg				    GLuint flags )
396848b8605Smrg{
397848b8605Smrg   GLuint j;
398848b8605Smrg   LOCAL_VARS;
399848b8605Smrg   (void) flags;
400848b8605Smrg
401848b8605Smrg   INIT(GL_QUAD_STRIP);
402848b8605Smrg   if (NEED_EDGEFLAG_SETUP) {
403848b8605Smrg      for (j=start+3;j<count;j+=2) {
404848b8605Smrg	 /* All edges are boundary.  Set edgeflags to 1, draw the
405848b8605Smrg	  * quad, and restore them to the original values.
406848b8605Smrg	  */
407848b8605Smrg	 GLboolean ef3 = EDGEFLAG_GET( ELT(j-3) );
408848b8605Smrg	 GLboolean ef2 = EDGEFLAG_GET( ELT(j-2) );
409848b8605Smrg	 GLboolean ef1 = EDGEFLAG_GET( ELT(j-1) );
410848b8605Smrg	 GLboolean ef = EDGEFLAG_GET( ELT(j) );
411848b8605Smrg	 if (TEST_PRIM_BEGIN(flags)) {
412848b8605Smrg	    RESET_STIPPLE;
413848b8605Smrg	 }
414848b8605Smrg	 EDGEFLAG_SET( ELT(j-3), GL_TRUE );
415848b8605Smrg	 EDGEFLAG_SET( ELT(j-2), GL_TRUE );
416848b8605Smrg	 EDGEFLAG_SET( ELT(j-1), GL_TRUE );
417848b8605Smrg	 EDGEFLAG_SET( ELT(j), GL_TRUE );
418848b8605Smrg         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT ||
419848b8605Smrg             !ctx->Const.QuadsFollowProvokingVertexConvention)
420848b8605Smrg            RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
421848b8605Smrg         else
422848b8605Smrg            RENDER_QUAD( ELT(j-2), ELT(j), ELT(j-1), ELT(j-3) );
423848b8605Smrg	 EDGEFLAG_SET( ELT(j-3), ef3 );
424848b8605Smrg	 EDGEFLAG_SET( ELT(j-2), ef2 );
425848b8605Smrg	 EDGEFLAG_SET( ELT(j-1), ef1 );
426848b8605Smrg	 EDGEFLAG_SET( ELT(j), ef );
427848b8605Smrg      }
428848b8605Smrg   } else {
429848b8605Smrg      for (j=start+3;j<count;j+=2) {
430848b8605Smrg         if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION_EXT ||
431848b8605Smrg             !ctx->Const.QuadsFollowProvokingVertexConvention)
432848b8605Smrg            RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
433848b8605Smrg         else
434848b8605Smrg            RENDER_QUAD( ELT(j-2), ELT(j), ELT(j-1), ELT(j-3) );
435848b8605Smrg      }
436848b8605Smrg   }
437848b8605Smrg   POSTFIX;
438848b8605Smrg}
439848b8605Smrg
440848b8605Smrgstatic void TAG(render_noop)( struct gl_context *ctx,
441848b8605Smrg			      GLuint start,
442848b8605Smrg			      GLuint count,
443848b8605Smrg			      GLuint flags )
444848b8605Smrg{
445848b8605Smrg   (void)(ctx && start && count && flags);
446848b8605Smrg}
447848b8605Smrg
448848b8605SmrgRENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON+2])(struct gl_context *,
449848b8605Smrg							   GLuint,
450848b8605Smrg							   GLuint,
451848b8605Smrg							   GLuint) =
452848b8605Smrg{
453848b8605Smrg   TAG(render_points),
454848b8605Smrg   TAG(render_lines),
455848b8605Smrg   TAG(render_line_loop),
456848b8605Smrg   TAG(render_line_strip),
457848b8605Smrg   TAG(render_triangles),
458848b8605Smrg   TAG(render_tri_strip),
459848b8605Smrg   TAG(render_tri_fan),
460848b8605Smrg   TAG(render_quads),
461848b8605Smrg   TAG(render_quad_strip),
462848b8605Smrg   TAG(render_poly),
463848b8605Smrg   TAG(render_noop),
464848b8605Smrg};
465848b8605Smrg
466848b8605Smrg
467848b8605Smrg
468848b8605Smrg#ifndef PRESERVE_VB_DEFS
469848b8605Smrg#undef RENDER_TRI
470848b8605Smrg#undef RENDER_QUAD
471848b8605Smrg#undef RENDER_LINE
472848b8605Smrg#undef RENDER_POINTS
473848b8605Smrg#undef LOCAL_VARS
474848b8605Smrg#undef INIT
475848b8605Smrg#undef POSTFIX
476848b8605Smrg#undef RESET_STIPPLE
477848b8605Smrg#undef DBG
478848b8605Smrg#undef ELT
479848b8605Smrg#undef RENDER_TAB_QUALIFIER
480848b8605Smrg#endif
481848b8605Smrg
482848b8605Smrg#ifndef PRESERVE_TAG
483848b8605Smrg#undef TAG
484848b8605Smrg#endif
485848b8605Smrg
486848b8605Smrg#undef PRESERVE_VB_DEFS
487848b8605Smrg#undef PRESERVE_TAG
488