2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
25 * Keith Whitwell <keith@tungstengraphics.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 !defined(HAVE_TRIANGLES)
43 #error "must have at least triangles to use render template"
47 #define ELTS_VARS(buf)
48 #define ALLOC_ELTS(nr) 0
49 #define EMIT_ELT( offset, elt )
50 #define EMIT_TWO_ELTS( offset, elt0, elt1 )
51 #define INCR_ELTS( nr )
52 #define ELT_INIT(prim)
53 #define GET_CURRENT_VB_MAX_ELTS() 0
54 #define GET_SUBSEQUENT_VB_MAX_ELTS() 0
55 #define RELEASE_ELT_VERTS()
56 #define EMIT_INDEXED_VERTS( ctx, start, count )
60 #define EMIT_TWO_ELTS( offset, elt0, elt1 ) \
62 EMIT_ELT( offset, elt0 ); \
63 EMIT_ELT( offset+1, elt1 ); \
68 /**********************************************************************/
69 /* Render whole begin/end objects */
70 /**********************************************************************/
76 static void *TAG(emit_elts)( struct gl_context *ctx, GLuint *elts, GLuint nr,
83 for ( i = 0 ; i+1 < nr ; i+=2, elts += 2 ) {
84 EMIT_TWO_ELTS( 0, elts[0], elts[1] );
89 EMIT_ELT( 0, elts[0] );
93 return (void *)ELTPTR;
97 static __inline void *TAG(emit_verts)( struct gl_context *ctx, GLuint start,
98 GLuint count, void *buf )
100 return EMIT_VERTS(ctx, start, count, buf);
103 /***********************************************************************
104 * Render non-indexed primitives.
105 ***********************************************************************/
107 static void TAG(render_points_verts)( struct gl_context *ctx,
114 int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
120 currentsz = GET_CURRENT_VB_MAX_VERTS();
124 for (j = start; j < count; j += nr ) {
125 nr = MIN2( currentsz, count - j );
126 TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
131 fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
136 static void TAG(render_lines_verts)( struct gl_context *ctx,
143 int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
149 /* Emit whole number of lines in total and in each buffer:
151 count -= (count-start) & 1;
152 currentsz = GET_CURRENT_VB_MAX_VERTS();
153 currentsz -= currentsz & 1;
159 for (j = start; j < count; j += nr ) {
160 nr = MIN2( currentsz, count - j );
161 TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
166 fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
172 static void TAG(render_line_strip_verts)( struct gl_context *ctx,
177 if (HAVE_LINE_STRIPS) {
179 int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
183 INIT( GL_LINE_STRIP );
185 currentsz = GET_CURRENT_VB_MAX_VERTS();
189 for (j = start; j + 1 < count; j += nr - 1 ) {
190 nr = MIN2( currentsz, count - j );
191 TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
198 fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
204 static void TAG(render_line_loop_verts)( struct gl_context *ctx,
209 if (HAVE_LINE_STRIPS) {
211 int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
215 INIT( GL_LINE_STRIP );
217 if (flags & PRIM_BEGIN)
222 /* Ensure last vertex won't wrap buffers:
224 currentsz = GET_CURRENT_VB_MAX_VERTS();
233 for ( ; j + 1 < count; j += nr - 1 ) {
234 nr = MIN2( currentsz, count - j );
236 if (j + nr >= count &&
241 tmp = ALLOC_VERTS(nr+1);
242 tmp = TAG(emit_verts)( ctx, j, nr, tmp );
243 tmp = TAG(emit_verts)( ctx, start, 1, tmp );
247 TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
253 else if (start + 1 < count && (flags & PRIM_END)) {
255 tmp = ALLOC_VERTS(2);
256 tmp = TAG(emit_verts)( ctx, start+1, 1, tmp );
257 tmp = TAG(emit_verts)( ctx, start, 1, tmp );
264 fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
270 static void TAG(render_triangles_verts)( struct gl_context *ctx,
276 int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS()/3) * 3;
282 currentsz = (GET_CURRENT_VB_MAX_VERTS()/3) * 3;
284 /* Emit whole number of tris in total. dmasz is already a multiple
287 count -= (count-start)%3;
292 for (j = start; j < count; j += nr) {
293 nr = MIN2( currentsz, count - j );
294 TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
301 static void TAG(render_tri_strip_verts)( struct gl_context *ctx,
306 if (HAVE_TRI_STRIPS) {
309 int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
312 INIT(GL_TRIANGLE_STRIP);
314 currentsz = GET_CURRENT_VB_MAX_VERTS();
320 /* From here on emit even numbers of tris when wrapping over buffers:
322 dmasz -= (dmasz & 1);
323 currentsz -= (currentsz & 1);
325 for (j = start ; j + 2 < count; j += nr - 2 ) {
326 nr = MIN2( currentsz, count - j );
327 TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
334 fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
339 static void TAG(render_tri_fan_verts)( struct gl_context *ctx,
347 int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
350 INIT(GL_TRIANGLE_FAN);
352 currentsz = GET_CURRENT_VB_MAX_VERTS();
357 for (j = start + 1 ; j + 1 < count; j += nr - 2 ) {
359 nr = MIN2( currentsz, count - j + 1 );
360 tmp = ALLOC_VERTS( nr );
361 tmp = TAG(emit_verts)( ctx, start, 1, tmp );
362 tmp = TAG(emit_verts)( ctx, j, nr - 1, tmp );
370 /* Could write code to emit these as indexed vertices (for the
371 * g400, for instance).
373 fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
379 static void TAG(render_poly_verts)( struct gl_context *ctx,
387 int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
392 currentsz = GET_CURRENT_VB_MAX_VERTS();
397 for (j = start + 1 ; j + 1 < count ; j += nr - 2 ) {
399 nr = MIN2( currentsz, count - j + 1 );
400 tmp = ALLOC_VERTS( nr );
401 tmp = TAG(emit_verts)( ctx, start, 1, tmp );
402 tmp = TAG(emit_verts)( ctx, j, nr - 1, tmp );
409 else if (HAVE_TRI_FANS && ctx->Light.ShadeModel == GL_SMOOTH) {
410 TAG(render_tri_fan_verts)( ctx, start, count, flags );
412 fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
417 static void TAG(render_quad_strip_verts)( struct gl_context *ctx,
424 if (HAVE_QUAD_STRIPS) {
427 int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
432 currentsz = GET_CURRENT_VB_MAX_VERTS();
437 dmasz -= (dmasz & 2);
438 currentsz -= (currentsz & 2);
440 for (j = start ; j + 3 < count; j += nr - 2 ) {
441 nr = MIN2( currentsz, count - j );
442 TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
448 } else if (HAVE_TRI_STRIPS &&
449 ctx->Light.ShadeModel == GL_FLAT &&
450 TNL_CONTEXT(ctx)->vb.AttribPtr[_TNL_ATTRIB_COLOR0]->stride) {
453 int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
457 EMIT_INDEXED_VERTS( ctx, start, count );
459 /* Simulate flat-shaded quadstrips using indexed vertices:
461 ELT_INIT( GL_TRIANGLES );
463 currentsz = GET_CURRENT_VB_MAX_ELTS();
465 /* Emit whole number of quads in total, and in each buffer.
468 count -= (count-start) & 1;
469 currentsz -= currentsz & 1;
474 currentsz = currentsz/6*2;
477 for (j = start; j + 3 < count; j += nr - 2 ) {
478 nr = MIN2( currentsz, count - j );
480 GLint quads = (nr/2)-1;
482 ELTS_VARS( ALLOC_ELTS( quads*6 ) );
484 for ( i = j-start ; i < j-start+quads*2 ; i+=2 ) {
485 EMIT_TWO_ELTS( 0, (i+0), (i+1) );
486 EMIT_TWO_ELTS( 2, (i+2), (i+1) );
487 EMIT_TWO_ELTS( 4, (i+3), (i+2) );
500 /* Vertices won't fit in a single buffer or elts not
501 * available - should never happen.
503 fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
507 else if (HAVE_TRI_STRIPS) {
509 int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
512 /* Emit smooth-shaded quadstrips as tristrips:
515 INIT( GL_TRIANGLE_STRIP );
517 /* Emit whole number of quads in total, and in each buffer.
520 currentsz = GET_CURRENT_VB_MAX_VERTS();
521 currentsz -= currentsz & 1;
522 count -= (count-start) & 1;
528 for (j = start; j + 3 < count; j += nr - 2 ) {
529 nr = MIN2( currentsz, count - j );
530 TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
537 fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
543 static void TAG(render_quads_verts)( struct gl_context *ctx,
550 int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS()/4) * 4;
556 /* Emit whole number of quads in total. dmasz is already a multiple
559 count -= (count-start)%4;
561 currentsz = (GET_CURRENT_VB_MAX_VERTS()/4) * 4;
565 for (j = start; j < count; j += nr) {
566 nr = MIN2( currentsz, count - j );
567 TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
571 else if (HAVE_ELTS) {
572 /* Hardware doesn't have a quad primitive type -- try to
573 * simulate it using indexed vertices and the triangle
577 int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
581 EMIT_INDEXED_VERTS( ctx, start, count );
584 ELT_INIT( GL_TRIANGLES );
585 currentsz = GET_CURRENT_VB_MAX_ELTS();
587 /* Emit whole number of quads in total, and in each buffer.
590 count -= (count-start) & 3;
591 currentsz -= currentsz & 3;
593 /* Adjust for rendering as triangles:
595 currentsz = currentsz/6*4;
601 for (j = start; j < count; j += nr ) {
602 nr = MIN2( currentsz, count - j );
606 ELTS_VARS( ALLOC_ELTS( quads*6 ) );
608 for ( i = j-start ; i < j-start+quads*4 ; i+=4 ) {
609 EMIT_TWO_ELTS( 0, (i+0), (i+1) );
610 EMIT_TWO_ELTS( 2, (i+3), (i+1) );
611 EMIT_TWO_ELTS( 4, (i+2), (i+3) );
622 else if (HAVE_TRIANGLES) {
623 /* Hardware doesn't have a quad primitive type -- try to
624 * simulate it using triangle primitive. This is a win for
625 * gears, but is it useful in the broader world?
632 for (j = start; j < count-3; j += 4) {
633 void *tmp = ALLOC_VERTS( 6 );
636 tmp = EMIT_VERTS(ctx, j, 2, tmp);
637 tmp = EMIT_VERTS(ctx, j + 3, 1, tmp);
640 tmp = EMIT_VERTS(ctx, j + 1, 3, tmp);
645 /* Vertices won't fit in a single buffer, should never happen.
647 fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
652 static void TAG(render_noop)( struct gl_context *ctx,
662 static tnl_render_func TAG(render_tab_verts)[GL_POLYGON+2] =
664 TAG(render_points_verts),
665 TAG(render_lines_verts),
666 TAG(render_line_loop_verts),
667 TAG(render_line_strip_verts),
668 TAG(render_triangles_verts),
669 TAG(render_tri_strip_verts),
670 TAG(render_tri_fan_verts),
671 TAG(render_quads_verts),
672 TAG(render_quad_strip_verts),
673 TAG(render_poly_verts),
678 /****************************************************************************
679 * Render elts using hardware indexed verts *
680 ****************************************************************************/
683 static void TAG(render_points_elts)( struct gl_context *ctx,
690 int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
692 GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
695 ELT_INIT( GL_POINTS );
697 currentsz = GET_CURRENT_VB_MAX_ELTS();
701 for (j = start; j < count; j += nr ) {
702 nr = MIN2( currentsz, count - j );
703 TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
708 fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
715 static void TAG(render_lines_elts)( struct gl_context *ctx,
722 int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
724 GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
727 ELT_INIT( GL_LINES );
729 /* Emit whole number of lines in total and in each buffer:
731 count -= (count-start) & 1;
732 currentsz -= currentsz & 1;
735 currentsz = GET_CURRENT_VB_MAX_ELTS();
739 for (j = start; j < count; j += nr ) {
740 nr = MIN2( currentsz, count - j );
741 TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
746 fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
752 static void TAG(render_line_strip_elts)( struct gl_context *ctx,
757 if (HAVE_LINE_STRIPS) {
759 int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
761 GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
764 FLUSH(); /* always a new primitive */
765 ELT_INIT( GL_LINE_STRIP );
767 currentsz = GET_CURRENT_VB_MAX_ELTS();
771 for (j = start; j + 1 < count; j += nr - 1 ) {
772 nr = MIN2( currentsz, count - j );
773 TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
778 /* TODO: Try to emit as indexed lines.
780 fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
786 static void TAG(render_line_loop_elts)( struct gl_context *ctx,
791 if (HAVE_LINE_STRIPS) {
793 int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
795 GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
799 ELT_INIT( GL_LINE_STRIP );
801 if (flags & PRIM_BEGIN)
806 currentsz = GET_CURRENT_VB_MAX_ELTS();
811 /* Ensure last vertex doesn't wrap:
817 for ( ; j + 1 < count; j += nr - 1 ) {
818 nr = MIN2( currentsz, count - j );
820 if (j + nr >= count &&
825 tmp = ALLOC_ELTS(nr+1);
826 tmp = TAG(emit_elts)( ctx, elts+j, nr, tmp );
827 tmp = TAG(emit_elts)( ctx, elts+start, 1, tmp );
831 TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
837 else if (start + 1 < count && (flags & PRIM_END)) {
840 tmp = TAG(emit_elts)( ctx, elts+start+1, 1, tmp );
841 tmp = TAG(emit_elts)( ctx, elts+start, 1, tmp );
847 /* TODO: Try to emit as indexed lines */
848 fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
854 /* For verts, we still eliminate the copy from main memory to dma
855 * buffers. For elts, this is probably no better (worse?) than the
858 static void TAG(render_triangles_elts)( struct gl_context *ctx,
864 GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
865 int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS()/3*3;
870 ELT_INIT( GL_TRIANGLES );
872 currentsz = GET_CURRENT_VB_MAX_ELTS();
874 /* Emit whole number of tris in total. dmasz is already a multiple
877 count -= (count-start)%3;
878 currentsz -= currentsz%3;
882 for (j = start; j < count; j += nr) {
883 nr = MIN2( currentsz, count - j );
884 TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
892 static void TAG(render_tri_strip_elts)( struct gl_context *ctx,
897 if (HAVE_TRI_STRIPS) {
900 GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
901 int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
905 ELT_INIT( GL_TRIANGLE_STRIP );
907 currentsz = GET_CURRENT_VB_MAX_ELTS();
912 /* Keep the same winding over multiple buffers:
914 dmasz -= (dmasz & 1);
915 currentsz -= (currentsz & 1);
917 for (j = start ; j + 2 < count; j += nr - 2 ) {
918 nr = MIN2( currentsz, count - j );
919 TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
924 /* TODO: try to emit as indexed triangles */
925 fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
930 static void TAG(render_tri_fan_elts)( struct gl_context *ctx,
937 GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
939 int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
943 ELT_INIT( GL_TRIANGLE_FAN );
945 currentsz = GET_CURRENT_VB_MAX_ELTS();
950 for (j = start + 1 ; j + 1 < count; j += nr - 2 ) {
952 nr = MIN2( currentsz, count - j + 1 );
953 tmp = ALLOC_ELTS( nr );
954 tmp = TAG(emit_elts)( ctx, elts+start, 1, tmp );
955 tmp = TAG(emit_elts)( ctx, elts+j, nr - 1, tmp );
961 /* TODO: try to emit as indexed triangles */
962 fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
968 static void TAG(render_poly_elts)( struct gl_context *ctx,
975 GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
977 int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
981 ELT_INIT( GL_POLYGON );
983 currentsz = GET_CURRENT_VB_MAX_ELTS();
988 for (j = start + 1 ; j + 1 < count; j += nr - 2 ) {
990 nr = MIN2( currentsz, count - j + 1 );
991 tmp = ALLOC_ELTS( nr );
992 tmp = TAG(emit_elts)( ctx, elts+start, 1, tmp );
993 tmp = TAG(emit_elts)( ctx, elts+j, nr - 1, tmp );
998 } else if (HAVE_TRI_FANS && ctx->Light.ShadeModel == GL_SMOOTH) {
999 TAG(render_tri_fan_verts)( ctx, start, count, flags );
1001 fprintf(stderr, "%s - cannot draw primitive\n", __FUNCTION__);
1006 static void TAG(render_quad_strip_elts)( struct gl_context *ctx,
1011 if (HAVE_QUAD_STRIPS && 0) {
1013 else if (HAVE_TRI_STRIPS) {
1015 GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
1016 int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
1021 currentsz = GET_CURRENT_VB_MAX_ELTS();
1023 /* Emit whole number of quads in total, and in each buffer.
1026 count -= (count-start) & 1;
1027 currentsz -= currentsz & 1;
1032 if (ctx->Light.ShadeModel == GL_FLAT) {
1033 ELT_INIT( GL_TRIANGLES );
1035 currentsz = currentsz/6*2;
1038 for (j = start; j + 3 < count; j += nr - 2 ) {
1039 nr = MIN2( currentsz, count - j );
1044 GLint quads = (nr/2)-1;
1045 ELTS_VARS( ALLOC_ELTS( quads*6 ) );
1047 for ( i = j-start ; i < j-start+quads ; i++, elts += 2 ) {
1048 EMIT_TWO_ELTS( 0, elts[0], elts[1] );
1049 EMIT_TWO_ELTS( 2, elts[2], elts[1] );
1050 EMIT_TWO_ELTS( 4, elts[3], elts[2] );
1061 ELT_INIT( GL_TRIANGLE_STRIP );
1063 for (j = start; j + 3 < count; j += nr - 2 ) {
1064 nr = MIN2( currentsz, count - j );
1065 TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
1074 static void TAG(render_quads_elts)( struct gl_context *ctx,
1081 GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
1082 int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS()/4*4;
1087 ELT_INIT( GL_TRIANGLES );
1089 currentsz = GET_CURRENT_VB_MAX_ELTS()/4*4;
1091 count -= (count-start)%4;
1096 for (j = start; j < count; j += nr) {
1097 nr = MIN2( currentsz, count - j );
1098 TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
1104 GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts;
1105 int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
1109 ELT_INIT( GL_TRIANGLES );
1110 currentsz = GET_CURRENT_VB_MAX_ELTS();
1112 /* Emit whole number of quads in total, and in each buffer.
1115 count -= (count-start) & 3;
1116 currentsz -= currentsz & 3;
1118 /* Adjust for rendering as triangles:
1120 currentsz = currentsz/6*4;
1126 for (j = start; j + 3 < count; j += nr - 2 ) {
1127 nr = MIN2( currentsz, count - j );
1133 ELTS_VARS( ALLOC_ELTS( quads * 6 ) );
1135 for ( i = j-start ; i < j-start+quads ; i++, elts += 4 ) {
1136 EMIT_TWO_ELTS( 0, elts[0], elts[1] );
1137 EMIT_TWO_ELTS( 2, elts[3], elts[1] );
1138 EMIT_TWO_ELTS( 4, elts[2], elts[3] );
1152 static tnl_render_func TAG(render_tab_elts)[GL_POLYGON+2] =
1154 TAG(render_points_elts),
1155 TAG(render_lines_elts),
1156 TAG(render_line_loop_elts),
1157 TAG(render_line_strip_elts),
1158 TAG(render_triangles_elts),
1159 TAG(render_tri_strip_elts),
1160 TAG(render_tri_fan_elts),
1161 TAG(render_quads_elts),
1162 TAG(render_quad_strip_elts),
1163 TAG(render_poly_elts),
1173 /* Pre-check the primitives in the VB to prevent the need for
1174 * fallbacks later on.
1176 static GLboolean TAG(validate_render)( struct gl_context *ctx,
1177 struct vertex_buffer *VB )
1181 if (VB->ClipOrMask & ~CLIP_CULL_BIT)
1184 if (VB->Elts && !HAVE_ELTS)
1187 for (i = 0 ; i < VB->PrimitiveCount ; i++) {
1188 GLuint prim = VB->Primitive[i].mode;
1189 GLuint count = VB->Primitive[i].count;
1190 GLboolean ok = GL_FALSE;
1195 switch (prim & PRIM_MODE_MASK) {
1200 ok = HAVE_LINES && !ctx->Line.StippleFlag;
1203 ok = HAVE_LINE_STRIPS && !ctx->Line.StippleFlag;
1206 ok = HAVE_LINE_STRIPS && !ctx->Line.StippleFlag;
1209 ok = HAVE_TRIANGLES;
1211 case GL_TRIANGLE_STRIP:
1212 ok = HAVE_TRI_STRIPS;
1214 case GL_TRIANGLE_FAN:
1218 if (HAVE_POLYGONS) {
1222 ok = (HAVE_TRI_FANS && ctx->Light.ShadeModel == GL_SMOOTH);
1227 ok = HAVE_TRI_STRIPS;
1229 else if (HAVE_QUAD_STRIPS) {
1231 } else if (HAVE_TRI_STRIPS &&
1232 ctx->Light.ShadeModel == GL_FLAT &&
1233 VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride != 0) {
1235 ok = (GLint) count < GET_SUBSEQUENT_VB_MAX_ELTS();
1242 ok = HAVE_TRI_STRIPS;
1247 } else if (HAVE_ELTS) {
1248 ok = (GLint) count < GET_SUBSEQUENT_VB_MAX_ELTS();
1251 ok = HAVE_TRIANGLES; /* flatshading is ok. */
1259 /* fprintf(stderr, "not ok %s\n", _mesa_lookup_enum_by_nr(prim & PRIM_MODE_MASK)); */