2 * Mesa 3-D graphics library
4 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
25 * Keith Whitwell <keithw@vmware.com>
31 * Template for render stages which build and emit vertices directly
32 * to fixed-size dma buffers. Useful for rendering strips and other
33 * native primitives where clipping and per-vertex tweaks such as
34 * those in t_dd_tritmp.h are not required.
36 * Produces code for both inline triangles and indexed triangles.
37 * Where various primitive types are unaccelerated by hardware, the
38 * code attempts to fallback to other primitive types (quadstrips to
39 * tristrips, lineloops to linestrips), or to indexed vertices.
42 #if !HAVE_TRIANGLES || !HAVE_LINES || !HAVE_LINE_STRIPS || !HAVE_TRI_STRIPS
43 #error "must have lines, line strips, triangles, and triangle strips to use render template"
46 #if HAVE_QUAD_STRIPS || HAVE_QUADS
47 #error "quads and quad strips not supported by render template"
51 #define ELTS_VARS(buf)
52 #define ALLOC_ELTS(nr) 0
53 #define EMIT_ELT( offset, elt )
54 #define EMIT_TWO_ELTS( offset, elt0, elt1 )
55 #define INCR_ELTS( nr )
56 #define ELT_INIT(prim)
57 #define GET_CURRENT_VB_MAX_ELTS() 0
58 #define GET_SUBSEQUENT_VB_MAX_ELTS() 0
59 #define RELEASE_ELT_VERTS()
60 #define EMIT_INDEXED_VERTS( ctx, start, count )
64 #define EMIT_TWO_ELTS( offset, elt0, elt1 ) \
66 EMIT_ELT( offset, elt0 ); \
67 EMIT_ELT( offset+1, elt1 ); \
72 /**********************************************************************/
73 /* Render whole begin/end objects */
74 /**********************************************************************/
80 static void *TAG(emit_elts
)( struct gl_context
*ctx
, GLuint
*elts
, GLuint nr
,
87 for ( i
= 0 ; i
+1 < nr
; i
+=2, elts
+= 2 ) {
88 EMIT_TWO_ELTS( 0, elts
[0], elts
[1] );
93 EMIT_ELT( 0, elts
[0] );
97 return (void *)ELTPTR
;
101 static __inline
void *TAG(emit_verts
)( struct gl_context
*ctx
, GLuint start
,
102 GLuint count
, void *buf
)
104 return EMIT_VERTS(ctx
, start
, count
, buf
);
107 /***********************************************************************
108 * Render non-indexed primitives.
109 ***********************************************************************/
111 static void TAG(render_points_verts
)( struct gl_context
*ctx
,
118 int dmasz
= GET_SUBSEQUENT_VB_MAX_VERTS();
124 currentsz
= GET_CURRENT_VB_MAX_VERTS();
128 for (j
= 0; j
< count
; j
+= nr
) {
129 nr
= MIN2( currentsz
, count
- j
);
130 TAG(emit_verts
)(ctx
, start
+ j
, nr
, ALLOC_VERTS(nr
));
135 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
140 static void TAG(render_lines_verts
)(struct gl_context
*ctx
,
146 int dmasz
= GET_SUBSEQUENT_VB_MAX_VERTS();
152 /* Emit whole number of lines in total and in each buffer:
155 currentsz
= GET_CURRENT_VB_MAX_VERTS();
156 currentsz
-= currentsz
& 1;
162 for (j
= 0; j
< count
; j
+= nr
) {
163 nr
= MIN2(currentsz
, count
- j
);
164 TAG(emit_verts
)(ctx
, start
+ j
, nr
, ALLOC_VERTS(nr
));
170 static void TAG(render_line_strip_verts
)(struct gl_context
*ctx
,
176 int dmasz
= GET_SUBSEQUENT_VB_MAX_VERTS();
182 currentsz
= GET_CURRENT_VB_MAX_VERTS();
186 for (j
= 0; j
+ 1 < count
; j
+= nr
- 1) {
187 nr
= MIN2(currentsz
, count
- j
);
188 TAG(emit_verts
)(ctx
, start
+ j
, nr
, ALLOC_VERTS(nr
));
196 static void TAG(render_line_loop_verts
)(struct gl_context
*ctx
,
202 int dmasz
= GET_SUBSEQUENT_VB_MAX_VERTS();
208 j
= (flags
& PRIM_BEGIN
) ? 0 : 1;
210 /* Ensure last vertex won't wrap buffers:
212 currentsz
= GET_CURRENT_VB_MAX_VERTS();
220 for (/* empty */; j
+ 1 < count
; j
+= nr
- 1) {
221 nr
= MIN2(currentsz
, count
- j
);
223 if (j
+ nr
>= count
&&
225 (flags
& PRIM_END
)) {
227 tmp
= ALLOC_VERTS(nr
+1);
228 tmp
= TAG(emit_verts
)(ctx
, start
+ j
, nr
, tmp
);
229 tmp
= TAG(emit_verts
)( ctx
, start
, 1, tmp
);
232 TAG(emit_verts
)(ctx
, start
+ j
, nr
, ALLOC_VERTS(nr
));
236 } else if (count
> 1 && (flags
& PRIM_END
)) {
238 tmp
= ALLOC_VERTS(2);
239 tmp
= TAG(emit_verts
)( ctx
, start
+1, 1, tmp
);
240 tmp
= TAG(emit_verts
)( ctx
, start
, 1, tmp
);
248 static void TAG(render_triangles_verts
)( struct gl_context
*ctx
,
254 int dmasz
= (GET_SUBSEQUENT_VB_MAX_VERTS()/3) * 3;
260 currentsz
= (GET_CURRENT_VB_MAX_VERTS()/3) * 3;
262 /* Emit whole number of tris in total. dmasz is already a multiple
270 for (j
= 0; j
< count
; j
+= nr
) {
271 nr
= MIN2( currentsz
, count
- j
);
272 TAG(emit_verts
)(ctx
, start
+ j
, nr
, ALLOC_VERTS(nr
));
279 static void TAG(render_tri_strip_verts
)( struct gl_context
*ctx
,
286 int dmasz
= GET_SUBSEQUENT_VB_MAX_VERTS();
289 INIT(GL_TRIANGLE_STRIP
);
291 currentsz
= GET_CURRENT_VB_MAX_VERTS();
297 /* From here on emit even numbers of tris when wrapping over buffers:
299 dmasz
-= (dmasz
& 1);
300 currentsz
-= (currentsz
& 1);
302 for (j
= 0; j
+ 2 < count
; j
+= nr
- 2) {
303 nr
= MIN2( currentsz
, count
- j
);
304 TAG(emit_verts
)(ctx
, start
+ j
, nr
, ALLOC_VERTS(nr
));
311 static void TAG(render_tri_fan_verts
)( struct gl_context
*ctx
,
319 int dmasz
= GET_SUBSEQUENT_VB_MAX_VERTS();
322 INIT(GL_TRIANGLE_FAN
);
324 currentsz
= GET_CURRENT_VB_MAX_VERTS();
329 for (j
= 1; j
+ 1 < count
; j
+= nr
- 2) {
331 nr
= MIN2( currentsz
, count
- j
+ 1 );
332 tmp
= ALLOC_VERTS( nr
);
333 tmp
= TAG(emit_verts
)( ctx
, start
, 1, tmp
);
334 tmp
= TAG(emit_verts
)( ctx
, start
+ j
, nr
- 1, tmp
);
342 /* Could write code to emit these as indexed vertices (for the
343 * g400, for instance).
345 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
351 static void TAG(render_poly_verts
)( struct gl_context
*ctx
,
359 int dmasz
= GET_SUBSEQUENT_VB_MAX_VERTS();
364 currentsz
= GET_CURRENT_VB_MAX_VERTS();
369 for (j
= 1 ; j
+ 1 < count
; j
+= nr
- 2 ) {
371 nr
= MIN2( currentsz
, count
- j
+ 1 );
372 tmp
= ALLOC_VERTS( nr
);
373 tmp
= TAG(emit_verts
)( ctx
, start
, 1, tmp
);
374 tmp
= TAG(emit_verts
)(ctx
, start
+ j
, nr
- 1, tmp
);
381 else if (HAVE_TRI_FANS
&& ctx
->Light
.ShadeModel
== GL_SMOOTH
) {
382 TAG(render_tri_fan_verts
)( ctx
, start
, count
, flags
);
384 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
389 static void TAG(render_quad_strip_verts
)( struct gl_context
*ctx
,
396 if (ctx
->Light
.ShadeModel
== GL_FLAT
&&
397 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[_TNL_ATTRIB_COLOR0
]->stride
) {
400 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
404 EMIT_INDEXED_VERTS( ctx
, start
, count
);
406 /* Simulate flat-shaded quadstrips using indexed vertices:
408 ELT_INIT( GL_TRIANGLES
);
410 currentsz
= GET_CURRENT_VB_MAX_ELTS();
412 /* Emit whole number of quads in total, and in each buffer.
416 currentsz
-= currentsz
& 1;
421 currentsz
= currentsz
/6*2;
424 for (j
= 0; j
+ 3 < count
; j
+= nr
- 2) {
425 nr
= MIN2( currentsz
, count
- j
);
427 GLint quads
= (nr
/2)-1;
429 ELTS_VARS( ALLOC_ELTS( quads
*6 ) );
431 for (i
= j
; i
< j
+ quads
* 2; i
+= 2) {
432 EMIT_TWO_ELTS( 0, (i
+0), (i
+1) );
433 EMIT_TWO_ELTS( 2, (i
+2), (i
+1) );
434 EMIT_TWO_ELTS( 4, (i
+3), (i
+2) );
447 /* Vertices won't fit in a single buffer or elts not
448 * available - should never happen.
450 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
456 int dmasz
= GET_SUBSEQUENT_VB_MAX_VERTS();
459 /* Emit smooth-shaded quadstrips as tristrips:
462 INIT( GL_TRIANGLE_STRIP
);
464 /* Emit whole number of quads in total, and in each buffer.
467 currentsz
= GET_CURRENT_VB_MAX_VERTS();
468 currentsz
-= currentsz
& 1;
475 for (j
= 0; j
+ 3 < count
; j
+= nr
- 2) {
476 nr
= MIN2( currentsz
, count
- j
);
477 TAG(emit_verts
)(ctx
, start
+ j
, nr
, ALLOC_VERTS(nr
));
486 static void TAG(render_quads_verts
)(struct gl_context
*ctx
,
491 /* Emit whole number of quads in total. */
495 /* Hardware doesn't have a quad primitive type -- try to
496 * simulate it using indexed vertices and the triangle
500 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
504 EMIT_INDEXED_VERTS( ctx
, start
, count
);
507 ELT_INIT( GL_TRIANGLES
);
508 currentsz
= GET_CURRENT_VB_MAX_ELTS();
510 /* Emit whole number of quads in total, and in each buffer.
513 currentsz
-= currentsz
& 3;
515 /* Adjust for rendering as triangles:
517 currentsz
= currentsz
/6*4;
523 for (j
= 0; j
< count
; j
+= nr
) {
524 nr
= MIN2( currentsz
, count
- j
);
528 ELTS_VARS( ALLOC_ELTS( quads
*6 ) );
530 for (i
= j
; i
< j
+ quads
* 4; i
+= 4) {
531 EMIT_TWO_ELTS( 0, (i
+0), (i
+1) );
532 EMIT_TWO_ELTS( 2, (i
+3), (i
+1) );
533 EMIT_TWO_ELTS( 4, (i
+2), (i
+3) );
545 /* Hardware doesn't have a quad primitive type -- try to
546 * simulate it using triangle primitive. This is a win for
547 * gears, but is it useful in the broader world?
554 for (j
= 0; j
+ 3 < count
; j
+= 4) {
555 void *tmp
= ALLOC_VERTS( 6 );
558 tmp
= EMIT_VERTS(ctx
, start
+ j
, 2, tmp
);
559 tmp
= EMIT_VERTS(ctx
, start
+ j
+ 3, 1, tmp
);
562 tmp
= EMIT_VERTS(ctx
, start
+ j
+ 1, 3, tmp
);
568 static void TAG(render_noop
)( struct gl_context
*ctx
,
578 static tnl_render_func
TAG(render_tab_verts
)[GL_POLYGON
+2] =
580 TAG(render_points_verts
),
581 TAG(render_lines_verts
),
582 TAG(render_line_loop_verts
),
583 TAG(render_line_strip_verts
),
584 TAG(render_triangles_verts
),
585 TAG(render_tri_strip_verts
),
586 TAG(render_tri_fan_verts
),
587 TAG(render_quads_verts
),
588 TAG(render_quad_strip_verts
),
589 TAG(render_poly_verts
),
594 /****************************************************************************
595 * Render elts using hardware indexed verts *
596 ****************************************************************************/
599 static void TAG(render_points_elts
)( struct gl_context
*ctx
,
606 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
608 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
611 ELT_INIT( GL_POINTS
);
613 currentsz
= GET_CURRENT_VB_MAX_ELTS();
617 for (j
= 0; j
< count
; j
+= nr
) {
618 nr
= MIN2( currentsz
, count
- j
);
619 TAG(emit_elts
)(ctx
, elts
+ start
+ j
, nr
, ALLOC_ELTS(nr
));
624 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
631 static void TAG(render_lines_elts
)(struct gl_context
*ctx
,
637 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
639 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
644 /* Emit whole number of lines in total and in each buffer:
647 currentsz
-= currentsz
& 1;
650 currentsz
= GET_CURRENT_VB_MAX_ELTS();
654 for (j
= 0; j
< count
; j
+= nr
) {
655 nr
= MIN2(currentsz
, count
- j
);
656 TAG(emit_elts
)(ctx
, elts
+ start
+ j
, nr
, ALLOC_ELTS(nr
));
663 static void TAG(render_line_strip_elts
)(struct gl_context
*ctx
,
669 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
671 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
674 FLUSH(); /* always a new primitive */
675 ELT_INIT(GL_LINE_STRIP
);
677 currentsz
= GET_CURRENT_VB_MAX_ELTS();
681 for (j
= 0; j
+ 1 < count
; j
+= nr
- 1) {
682 nr
= MIN2(currentsz
, count
- j
);
683 TAG(emit_elts
)(ctx
, elts
+ start
+ j
, nr
, ALLOC_ELTS(nr
));
690 static void TAG(render_line_loop_elts
)(struct gl_context
*ctx
,
696 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
698 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
702 ELT_INIT(GL_LINE_STRIP
);
704 j
= (flags
& PRIM_BEGIN
) ? 0 : 1;
706 currentsz
= GET_CURRENT_VB_MAX_ELTS();
710 /* Ensure last vertex doesn't wrap:
716 for (/* empty */; j
+ 1 < count
; j
+= nr
- 1) {
717 nr
= MIN2(currentsz
, count
- j
);
719 if (j
+ nr
>= count
&&
721 (flags
& PRIM_END
)) {
723 tmp
= ALLOC_ELTS(nr
+1);
724 tmp
= TAG(emit_elts
)(ctx
, elts
+ start
+ j
, nr
, tmp
);
725 tmp
= TAG(emit_elts
)(ctx
, elts
+ start
, 1, tmp
);
728 TAG(emit_elts
)(ctx
, elts
+ start
+ j
, nr
, ALLOC_ELTS(nr
));
732 } else if (count
> 1 && (flags
& PRIM_END
)) {
735 tmp
= TAG(emit_elts
)( ctx
, elts
+start
+1, 1, tmp
);
736 tmp
= TAG(emit_elts
)( ctx
, elts
+start
, 1, tmp
);
744 /* For verts, we still eliminate the copy from main memory to dma
745 * buffers. For elts, this is probably no better (worse?) than the
748 static void TAG(render_triangles_elts
)( struct gl_context
*ctx
,
754 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
755 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS()/3*3;
760 ELT_INIT( GL_TRIANGLES
);
762 currentsz
= GET_CURRENT_VB_MAX_ELTS();
764 /* Emit whole number of tris in total. dmasz is already a multiple
768 currentsz
-= currentsz
%3;
772 for (j
= 0; j
< count
; j
+= nr
) {
773 nr
= MIN2( currentsz
, count
- j
);
774 TAG(emit_elts
)(ctx
, elts
+ start
+ j
, nr
, ALLOC_ELTS(nr
));
782 static void TAG(render_tri_strip_elts
)( struct gl_context
*ctx
,
789 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
790 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
794 ELT_INIT( GL_TRIANGLE_STRIP
);
796 currentsz
= GET_CURRENT_VB_MAX_ELTS();
801 /* Keep the same winding over multiple buffers:
803 dmasz
-= (dmasz
& 1);
804 currentsz
-= (currentsz
& 1);
806 for (j
= 0; j
+ 2 < count
; j
+= nr
- 2) {
807 nr
= MIN2( currentsz
, count
- j
);
808 TAG(emit_elts
)( ctx
, elts
+ start
+ j
, nr
, ALLOC_ELTS(nr
) );
814 static void TAG(render_tri_fan_elts
)( struct gl_context
*ctx
,
821 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
823 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
827 ELT_INIT( GL_TRIANGLE_FAN
);
829 currentsz
= GET_CURRENT_VB_MAX_ELTS();
834 for (j
= 1; j
+ 1 < count
; j
+= nr
- 2) {
836 nr
= MIN2( currentsz
, count
- j
+ 1 );
837 tmp
= ALLOC_ELTS( nr
);
838 tmp
= TAG(emit_elts
)( ctx
, elts
+start
, 1, tmp
);
839 tmp
= TAG(emit_elts
)(ctx
, elts
+ start
+ j
, nr
- 1, tmp
);
845 /* TODO: try to emit as indexed triangles */
846 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
852 static void TAG(render_poly_elts
)( struct gl_context
*ctx
,
859 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
861 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
865 ELT_INIT( GL_POLYGON
);
867 currentsz
= GET_CURRENT_VB_MAX_ELTS();
872 for (j
= 1 ; j
+ 1 < count
; j
+= nr
- 2) {
874 nr
= MIN2( currentsz
, count
- j
+ 1 );
875 tmp
= ALLOC_ELTS( nr
);
876 tmp
= TAG(emit_elts
)( ctx
, elts
+start
, 1, tmp
);
877 tmp
= TAG(emit_elts
)(ctx
, elts
+ start
+ j
, nr
- 1, tmp
);
882 } else if (HAVE_TRI_FANS
&& ctx
->Light
.ShadeModel
== GL_SMOOTH
) {
883 TAG(render_tri_fan_verts
)( ctx
, start
, count
, flags
);
885 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
890 static void TAG(render_quad_strip_elts
)( struct gl_context
*ctx
,
896 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
897 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
902 currentsz
= GET_CURRENT_VB_MAX_ELTS();
904 /* Emit whole number of quads in total, and in each buffer.
908 currentsz
-= currentsz
& 1;
913 if (ctx
->Light
.ShadeModel
== GL_FLAT
) {
914 ELT_INIT( GL_TRIANGLES
);
916 currentsz
= currentsz
/6*2;
919 for (j
= 0; j
+ 3 < count
; j
+= nr
- 2) {
920 nr
= MIN2( currentsz
, count
- j
);
925 GLint quads
= (nr
/2)-1;
926 ELTS_VARS( ALLOC_ELTS( quads
*6 ) );
928 for (i
= j
; i
< j
+ quads
; i
++, elts
+= 2) {
929 EMIT_TWO_ELTS( 0, elts
[0], elts
[1] );
930 EMIT_TWO_ELTS( 2, elts
[2], elts
[1] );
931 EMIT_TWO_ELTS( 4, elts
[3], elts
[2] );
942 ELT_INIT( GL_TRIANGLE_STRIP
);
944 for (j
= 0; j
+ 3 < count
; j
+= nr
- 2) {
945 nr
= MIN2( currentsz
, count
- j
);
946 TAG(emit_elts
)(ctx
, elts
+ start
+ j
, nr
, ALLOC_ELTS(nr
));
954 static void TAG(render_quads_elts
)(struct gl_context
*ctx
,
960 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
961 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
965 ELT_INIT(GL_TRIANGLES
);
966 currentsz
= GET_CURRENT_VB_MAX_ELTS();
968 /* Emit whole number of quads in total, and in each buffer.
972 currentsz
-= currentsz
& 3;
974 /* Adjust for rendering as triangles:
976 currentsz
= currentsz
/ 6 * 4;
977 dmasz
= dmasz
/ 6 * 4;
982 for (j
= 0; j
+ 3 < count
; j
+= nr
- 2) {
983 nr
= MIN2(currentsz
, count
- j
);
986 GLint quads
= nr
/ 4;
988 ELTS_VARS(ALLOC_ELTS(quads
* 6));
990 for (i
= j
; i
< j
+ quads
; i
++, elts
+= 4) {
991 EMIT_TWO_ELTS(0, elts
[0], elts
[1]);
992 EMIT_TWO_ELTS(2, elts
[3], elts
[1]);
993 EMIT_TWO_ELTS(4, elts
[2], elts
[3]);
1006 static tnl_render_func
TAG(render_tab_elts
)[GL_POLYGON
+2] =
1008 TAG(render_points_elts
),
1009 TAG(render_lines_elts
),
1010 TAG(render_line_loop_elts
),
1011 TAG(render_line_strip_elts
),
1012 TAG(render_triangles_elts
),
1013 TAG(render_tri_strip_elts
),
1014 TAG(render_tri_fan_elts
),
1015 TAG(render_quads_elts
),
1016 TAG(render_quad_strip_elts
),
1017 TAG(render_poly_elts
),
1027 /* Pre-check the primitives in the VB to prevent the need for
1028 * fallbacks later on.
1030 static GLboolean
TAG(validate_render
)( struct gl_context
*ctx
,
1031 struct vertex_buffer
*VB
)
1035 if (VB
->ClipOrMask
& ~CLIP_CULL_BIT
)
1038 if (VB
->Elts
&& !HAVE_ELTS
)
1041 for (i
= 0 ; i
< VB
->PrimitiveCount
; i
++) {
1042 GLuint prim
= VB
->Primitive
[i
].mode
;
1043 GLuint count
= VB
->Primitive
[i
].count
;
1044 GLboolean ok
= GL_FALSE
;
1049 switch (prim
& PRIM_MODE_MASK
) {
1056 ok
= !ctx
->Line
.StippleFlag
;
1061 case GL_TRIANGLE_STRIP
:
1064 case GL_TRIANGLE_FAN
:
1068 if (HAVE_POLYGONS
) {
1072 ok
= (HAVE_TRI_FANS
&& ctx
->Light
.ShadeModel
== GL_SMOOTH
);
1078 } else if (ctx
->Light
.ShadeModel
== GL_FLAT
&&
1079 VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->stride
!= 0) {
1081 ok
= (GLint
) count
< GET_SUBSEQUENT_VB_MAX_ELTS();
1092 ok
= (GLint
) count
< GET_SUBSEQUENT_VB_MAX_ELTS();
1095 ok
= GL_TRUE
; /* flatshading is ok. */
1103 /* fprintf(stderr, "not ok %s\n", _mesa_enum_to_string(prim & PRIM_MODE_MASK)); */