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 !defined(HAVE_TRIANGLES) || !HAVE_LINES
43 #error "must have lines and triangles 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
,
175 if (HAVE_LINE_STRIPS
) {
177 int dmasz
= GET_SUBSEQUENT_VB_MAX_VERTS();
181 INIT( GL_LINE_STRIP
);
183 currentsz
= GET_CURRENT_VB_MAX_VERTS();
187 for (j
= 0; j
+ 1 < count
; j
+= nr
- 1 ) {
188 nr
= MIN2( currentsz
, count
- j
);
189 TAG(emit_verts
)(ctx
, start
+ j
, nr
, ALLOC_VERTS(nr
));
196 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
202 static void TAG(render_line_loop_verts
)( struct gl_context
*ctx
,
207 if (HAVE_LINE_STRIPS
) {
209 int dmasz
= GET_SUBSEQUENT_VB_MAX_VERTS();
213 INIT( GL_LINE_STRIP
);
215 j
= (flags
& PRIM_BEGIN
) ? 0 : 1;
217 /* Ensure last vertex won't wrap buffers:
219 currentsz
= GET_CURRENT_VB_MAX_VERTS();
228 for ( ; j
+ 1 < count
; j
+= nr
- 1 ) {
229 nr
= MIN2( currentsz
, count
- j
);
231 if (j
+ nr
>= count
&&
236 tmp
= ALLOC_VERTS(nr
+1);
237 tmp
= TAG(emit_verts
)(ctx
, start
+ j
, nr
, tmp
);
238 tmp
= TAG(emit_verts
)( ctx
, start
, 1, tmp
);
242 TAG(emit_verts
)(ctx
, start
+ j
, nr
, ALLOC_VERTS(nr
));
248 else if (count
> 1 && (flags
& PRIM_END
)) {
250 tmp
= ALLOC_VERTS(2);
251 tmp
= TAG(emit_verts
)( ctx
, start
+1, 1, tmp
);
252 tmp
= TAG(emit_verts
)( ctx
, start
, 1, tmp
);
259 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
265 static void TAG(render_triangles_verts
)( struct gl_context
*ctx
,
271 int dmasz
= (GET_SUBSEQUENT_VB_MAX_VERTS()/3) * 3;
277 currentsz
= (GET_CURRENT_VB_MAX_VERTS()/3) * 3;
279 /* Emit whole number of tris in total. dmasz is already a multiple
287 for (j
= 0; j
< count
; j
+= nr
) {
288 nr
= MIN2( currentsz
, count
- j
);
289 TAG(emit_verts
)(ctx
, start
+ j
, nr
, ALLOC_VERTS(nr
));
296 static void TAG(render_tri_strip_verts
)( struct gl_context
*ctx
,
301 if (HAVE_TRI_STRIPS
) {
304 int dmasz
= GET_SUBSEQUENT_VB_MAX_VERTS();
307 INIT(GL_TRIANGLE_STRIP
);
309 currentsz
= GET_CURRENT_VB_MAX_VERTS();
315 /* From here on emit even numbers of tris when wrapping over buffers:
317 dmasz
-= (dmasz
& 1);
318 currentsz
-= (currentsz
& 1);
320 for (j
= 0; j
+ 2 < count
; j
+= nr
- 2) {
321 nr
= MIN2( currentsz
, count
- j
);
322 TAG(emit_verts
)(ctx
, start
+ j
, nr
, ALLOC_VERTS(nr
));
329 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
334 static void TAG(render_tri_fan_verts
)( struct gl_context
*ctx
,
342 int dmasz
= GET_SUBSEQUENT_VB_MAX_VERTS();
345 INIT(GL_TRIANGLE_FAN
);
347 currentsz
= GET_CURRENT_VB_MAX_VERTS();
352 for (j
= 1; j
+ 1 < count
; j
+= nr
- 2) {
354 nr
= MIN2( currentsz
, count
- j
+ 1 );
355 tmp
= ALLOC_VERTS( nr
);
356 tmp
= TAG(emit_verts
)( ctx
, start
, 1, tmp
);
357 tmp
= TAG(emit_verts
)( ctx
, start
+ j
, nr
- 1, tmp
);
365 /* Could write code to emit these as indexed vertices (for the
366 * g400, for instance).
368 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
374 static void TAG(render_poly_verts
)( struct gl_context
*ctx
,
382 int dmasz
= GET_SUBSEQUENT_VB_MAX_VERTS();
387 currentsz
= GET_CURRENT_VB_MAX_VERTS();
392 for (j
= 1 ; j
+ 1 < count
; j
+= nr
- 2 ) {
394 nr
= MIN2( currentsz
, count
- j
+ 1 );
395 tmp
= ALLOC_VERTS( nr
);
396 tmp
= TAG(emit_verts
)( ctx
, start
, 1, tmp
);
397 tmp
= TAG(emit_verts
)(ctx
, start
+ j
, nr
- 1, tmp
);
404 else if (HAVE_TRI_FANS
&& ctx
->Light
.ShadeModel
== GL_SMOOTH
) {
405 TAG(render_tri_fan_verts
)( ctx
, start
, count
, flags
);
407 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
412 static void TAG(render_quad_strip_verts
)( struct gl_context
*ctx
,
419 if (HAVE_TRI_STRIPS
&&
420 ctx
->Light
.ShadeModel
== GL_FLAT
&&
421 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[_TNL_ATTRIB_COLOR0
]->stride
) {
424 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
428 EMIT_INDEXED_VERTS( ctx
, start
, count
);
430 /* Simulate flat-shaded quadstrips using indexed vertices:
432 ELT_INIT( GL_TRIANGLES
);
434 currentsz
= GET_CURRENT_VB_MAX_ELTS();
436 /* Emit whole number of quads in total, and in each buffer.
440 currentsz
-= currentsz
& 1;
445 currentsz
= currentsz
/6*2;
448 for (j
= 0; j
+ 3 < count
; j
+= nr
- 2) {
449 nr
= MIN2( currentsz
, count
- j
);
451 GLint quads
= (nr
/2)-1;
453 ELTS_VARS( ALLOC_ELTS( quads
*6 ) );
455 for (i
= j
; i
< j
+ quads
* 2; i
+= 2) {
456 EMIT_TWO_ELTS( 0, (i
+0), (i
+1) );
457 EMIT_TWO_ELTS( 2, (i
+2), (i
+1) );
458 EMIT_TWO_ELTS( 4, (i
+3), (i
+2) );
471 /* Vertices won't fit in a single buffer or elts not
472 * available - should never happen.
474 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
478 else if (HAVE_TRI_STRIPS
) {
480 int dmasz
= GET_SUBSEQUENT_VB_MAX_VERTS();
483 /* Emit smooth-shaded quadstrips as tristrips:
486 INIT( GL_TRIANGLE_STRIP
);
488 /* Emit whole number of quads in total, and in each buffer.
491 currentsz
= GET_CURRENT_VB_MAX_VERTS();
492 currentsz
-= currentsz
& 1;
499 for (j
= 0; j
+ 3 < count
; j
+= nr
- 2) {
500 nr
= MIN2( currentsz
, count
- j
);
501 TAG(emit_verts
)(ctx
, start
+ j
, nr
, ALLOC_VERTS(nr
));
508 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
514 static void TAG(render_quads_verts
)(struct gl_context
*ctx
,
519 /* Emit whole number of quads in total. */
523 /* Hardware doesn't have a quad primitive type -- try to
524 * simulate it using indexed vertices and the triangle
528 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
532 EMIT_INDEXED_VERTS( ctx
, start
, count
);
535 ELT_INIT( GL_TRIANGLES
);
536 currentsz
= GET_CURRENT_VB_MAX_ELTS();
538 /* Emit whole number of quads in total, and in each buffer.
541 currentsz
-= currentsz
& 3;
543 /* Adjust for rendering as triangles:
545 currentsz
= currentsz
/6*4;
551 for (j
= 0; j
< count
; j
+= nr
) {
552 nr
= MIN2( currentsz
, count
- j
);
556 ELTS_VARS( ALLOC_ELTS( quads
*6 ) );
558 for (i
= j
; i
< j
+ quads
* 4; i
+= 4) {
559 EMIT_TWO_ELTS( 0, (i
+0), (i
+1) );
560 EMIT_TWO_ELTS( 2, (i
+3), (i
+1) );
561 EMIT_TWO_ELTS( 4, (i
+2), (i
+3) );
572 else if (HAVE_TRIANGLES
) {
573 /* Hardware doesn't have a quad primitive type -- try to
574 * simulate it using triangle primitive. This is a win for
575 * gears, but is it useful in the broader world?
582 for (j
= 0; j
+ 3 < count
; j
+= 4) {
583 void *tmp
= ALLOC_VERTS( 6 );
586 tmp
= EMIT_VERTS(ctx
, start
+ j
, 2, tmp
);
587 tmp
= EMIT_VERTS(ctx
, start
+ j
+ 3, 1, tmp
);
590 tmp
= EMIT_VERTS(ctx
, start
+ j
+ 1, 3, tmp
);
595 /* Vertices won't fit in a single buffer, should never happen.
597 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
602 static void TAG(render_noop
)( struct gl_context
*ctx
,
612 static tnl_render_func
TAG(render_tab_verts
)[GL_POLYGON
+2] =
614 TAG(render_points_verts
),
615 TAG(render_lines_verts
),
616 TAG(render_line_loop_verts
),
617 TAG(render_line_strip_verts
),
618 TAG(render_triangles_verts
),
619 TAG(render_tri_strip_verts
),
620 TAG(render_tri_fan_verts
),
621 TAG(render_quads_verts
),
622 TAG(render_quad_strip_verts
),
623 TAG(render_poly_verts
),
628 /****************************************************************************
629 * Render elts using hardware indexed verts *
630 ****************************************************************************/
633 static void TAG(render_points_elts
)( struct gl_context
*ctx
,
640 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
642 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
645 ELT_INIT( GL_POINTS
);
647 currentsz
= GET_CURRENT_VB_MAX_ELTS();
651 for (j
= 0; j
< count
; j
+= nr
) {
652 nr
= MIN2( currentsz
, count
- j
);
653 TAG(emit_elts
)(ctx
, elts
+ start
+ j
, nr
, ALLOC_ELTS(nr
));
658 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
665 static void TAG(render_lines_elts
)( struct gl_context
*ctx
,
671 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
673 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
676 ELT_INIT( GL_LINES
);
678 /* Emit whole number of lines in total and in each buffer:
681 currentsz
-= currentsz
& 1;
684 currentsz
= GET_CURRENT_VB_MAX_ELTS();
688 for (j
= 0; j
< count
; j
+= nr
) {
689 nr
= MIN2( currentsz
, count
- j
);
690 TAG(emit_elts
)(ctx
, elts
+ start
+ j
, nr
, ALLOC_ELTS(nr
));
697 static void TAG(render_line_strip_elts
)( struct gl_context
*ctx
,
702 if (HAVE_LINE_STRIPS
) {
704 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
706 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
709 FLUSH(); /* always a new primitive */
710 ELT_INIT( GL_LINE_STRIP
);
712 currentsz
= GET_CURRENT_VB_MAX_ELTS();
716 for (j
= 0; j
+ 1 < count
; j
+= nr
- 1) {
717 nr
= MIN2( currentsz
, count
- j
);
718 TAG(emit_elts
)( ctx
, elts
+ start
+ j
, nr
, ALLOC_ELTS(nr
));
723 /* TODO: Try to emit as indexed lines.
725 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
731 static void TAG(render_line_loop_elts
)( struct gl_context
*ctx
,
736 if (HAVE_LINE_STRIPS
) {
738 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
740 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
744 ELT_INIT( GL_LINE_STRIP
);
746 j
= (flags
& PRIM_BEGIN
) ? 0 : 1;
748 currentsz
= GET_CURRENT_VB_MAX_ELTS();
753 /* Ensure last vertex doesn't wrap:
759 for ( ; j
+ 1 < count
; j
+= nr
- 1 ) {
760 nr
= MIN2( currentsz
, count
- j
);
762 if (j
+ nr
>= count
&&
767 tmp
= ALLOC_ELTS(nr
+1);
768 tmp
= TAG(emit_elts
)(ctx
, elts
+ start
+ j
, nr
, tmp
);
769 tmp
= TAG(emit_elts
)( ctx
, elts
+start
, 1, tmp
);
773 TAG(emit_elts
)(ctx
, elts
+ start
+ j
, nr
, ALLOC_ELTS(nr
));
779 else if (count
> 1 && (flags
& PRIM_END
)) {
782 tmp
= TAG(emit_elts
)( ctx
, elts
+start
+1, 1, tmp
);
783 tmp
= TAG(emit_elts
)( ctx
, elts
+start
, 1, tmp
);
789 /* TODO: Try to emit as indexed lines */
790 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
796 /* For verts, we still eliminate the copy from main memory to dma
797 * buffers. For elts, this is probably no better (worse?) than the
800 static void TAG(render_triangles_elts
)( struct gl_context
*ctx
,
806 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
807 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS()/3*3;
812 ELT_INIT( GL_TRIANGLES
);
814 currentsz
= GET_CURRENT_VB_MAX_ELTS();
816 /* Emit whole number of tris in total. dmasz is already a multiple
820 currentsz
-= currentsz
%3;
824 for (j
= 0; j
< count
; j
+= nr
) {
825 nr
= MIN2( currentsz
, count
- j
);
826 TAG(emit_elts
)(ctx
, elts
+ start
+ j
, nr
, ALLOC_ELTS(nr
));
834 static void TAG(render_tri_strip_elts
)( struct gl_context
*ctx
,
839 if (HAVE_TRI_STRIPS
) {
842 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
843 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
847 ELT_INIT( GL_TRIANGLE_STRIP
);
849 currentsz
= GET_CURRENT_VB_MAX_ELTS();
854 /* Keep the same winding over multiple buffers:
856 dmasz
-= (dmasz
& 1);
857 currentsz
-= (currentsz
& 1);
859 for (j
= 0; j
+ 2 < count
; j
+= nr
- 2) {
860 nr
= MIN2( currentsz
, count
- j
);
861 TAG(emit_elts
)( ctx
, elts
+ start
+ j
, nr
, ALLOC_ELTS(nr
) );
866 /* TODO: try to emit as indexed triangles */
867 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
872 static void TAG(render_tri_fan_elts
)( struct gl_context
*ctx
,
879 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
881 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
885 ELT_INIT( GL_TRIANGLE_FAN
);
887 currentsz
= GET_CURRENT_VB_MAX_ELTS();
892 for (j
= 1; j
+ 1 < count
; j
+= nr
- 2) {
894 nr
= MIN2( currentsz
, count
- j
+ 1 );
895 tmp
= ALLOC_ELTS( nr
);
896 tmp
= TAG(emit_elts
)( ctx
, elts
+start
, 1, tmp
);
897 tmp
= TAG(emit_elts
)(ctx
, elts
+ start
+ j
, nr
- 1, tmp
);
903 /* TODO: try to emit as indexed triangles */
904 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
910 static void TAG(render_poly_elts
)( struct gl_context
*ctx
,
917 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
919 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
923 ELT_INIT( GL_POLYGON
);
925 currentsz
= GET_CURRENT_VB_MAX_ELTS();
930 for (j
= 1 ; j
+ 1 < count
; j
+= nr
- 2) {
932 nr
= MIN2( currentsz
, count
- j
+ 1 );
933 tmp
= ALLOC_ELTS( nr
);
934 tmp
= TAG(emit_elts
)( ctx
, elts
+start
, 1, tmp
);
935 tmp
= TAG(emit_elts
)(ctx
, elts
+ start
+ j
, nr
- 1, tmp
);
940 } else if (HAVE_TRI_FANS
&& ctx
->Light
.ShadeModel
== GL_SMOOTH
) {
941 TAG(render_tri_fan_verts
)( ctx
, start
, count
, flags
);
943 fprintf(stderr
, "%s - cannot draw primitive\n", __func__
);
948 static void TAG(render_quad_strip_elts
)( struct gl_context
*ctx
,
953 if (HAVE_TRI_STRIPS
) {
955 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
956 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
961 currentsz
= GET_CURRENT_VB_MAX_ELTS();
963 /* Emit whole number of quads in total, and in each buffer.
967 currentsz
-= currentsz
& 1;
972 if (ctx
->Light
.ShadeModel
== GL_FLAT
) {
973 ELT_INIT( GL_TRIANGLES
);
975 currentsz
= currentsz
/6*2;
978 for (j
= 0; j
+ 3 < count
; j
+= nr
- 2) {
979 nr
= MIN2( currentsz
, count
- j
);
984 GLint quads
= (nr
/2)-1;
985 ELTS_VARS( ALLOC_ELTS( quads
*6 ) );
987 for (i
= j
; i
< j
+ quads
; i
++, elts
+= 2) {
988 EMIT_TWO_ELTS( 0, elts
[0], elts
[1] );
989 EMIT_TWO_ELTS( 2, elts
[2], elts
[1] );
990 EMIT_TWO_ELTS( 4, elts
[3], elts
[2] );
1001 ELT_INIT( GL_TRIANGLE_STRIP
);
1003 for (j
= 0; j
+ 3 < count
; j
+= nr
- 2) {
1004 nr
= MIN2( currentsz
, count
- j
);
1005 TAG(emit_elts
)(ctx
, elts
+ start
+ j
, nr
, ALLOC_ELTS(nr
));
1014 static void TAG(render_quads_elts
)(struct gl_context
*ctx
,
1020 GLuint
*elts
= TNL_CONTEXT(ctx
)->vb
.Elts
;
1021 int dmasz
= GET_SUBSEQUENT_VB_MAX_ELTS();
1025 ELT_INIT(GL_TRIANGLES
);
1026 currentsz
= GET_CURRENT_VB_MAX_ELTS();
1028 /* Emit whole number of quads in total, and in each buffer.
1032 currentsz
-= currentsz
& 3;
1034 /* Adjust for rendering as triangles:
1036 currentsz
= currentsz
/ 6 * 4;
1037 dmasz
= dmasz
/ 6 * 4;
1042 for (j
= 0; j
+ 3 < count
; j
+= nr
- 2) {
1043 nr
= MIN2(currentsz
, count
- j
);
1046 GLint quads
= nr
/ 4;
1048 ELTS_VARS(ALLOC_ELTS(quads
* 6));
1050 for (i
= j
; i
< j
+ quads
; i
++, elts
+= 4) {
1051 EMIT_TWO_ELTS(0, elts
[0], elts
[1]);
1052 EMIT_TWO_ELTS(2, elts
[3], elts
[1]);
1053 EMIT_TWO_ELTS(4, elts
[2], elts
[3]);
1066 static tnl_render_func
TAG(render_tab_elts
)[GL_POLYGON
+2] =
1068 TAG(render_points_elts
),
1069 TAG(render_lines_elts
),
1070 TAG(render_line_loop_elts
),
1071 TAG(render_line_strip_elts
),
1072 TAG(render_triangles_elts
),
1073 TAG(render_tri_strip_elts
),
1074 TAG(render_tri_fan_elts
),
1075 TAG(render_quads_elts
),
1076 TAG(render_quad_strip_elts
),
1077 TAG(render_poly_elts
),
1087 /* Pre-check the primitives in the VB to prevent the need for
1088 * fallbacks later on.
1090 static GLboolean
TAG(validate_render
)( struct gl_context
*ctx
,
1091 struct vertex_buffer
*VB
)
1095 if (VB
->ClipOrMask
& ~CLIP_CULL_BIT
)
1098 if (VB
->Elts
&& !HAVE_ELTS
)
1101 for (i
= 0 ; i
< VB
->PrimitiveCount
; i
++) {
1102 GLuint prim
= VB
->Primitive
[i
].mode
;
1103 GLuint count
= VB
->Primitive
[i
].count
;
1104 GLboolean ok
= GL_FALSE
;
1109 switch (prim
& PRIM_MODE_MASK
) {
1114 ok
= !ctx
->Line
.StippleFlag
;
1117 ok
= HAVE_LINE_STRIPS
&& !ctx
->Line
.StippleFlag
;
1120 ok
= HAVE_LINE_STRIPS
&& !ctx
->Line
.StippleFlag
;
1123 ok
= HAVE_TRIANGLES
;
1125 case GL_TRIANGLE_STRIP
:
1126 ok
= HAVE_TRI_STRIPS
;
1128 case GL_TRIANGLE_FAN
:
1132 if (HAVE_POLYGONS
) {
1136 ok
= (HAVE_TRI_FANS
&& ctx
->Light
.ShadeModel
== GL_SMOOTH
);
1141 ok
= HAVE_TRI_STRIPS
;
1142 } else if (HAVE_TRI_STRIPS
&&
1143 ctx
->Light
.ShadeModel
== GL_FLAT
&&
1144 VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->stride
!= 0) {
1146 ok
= (GLint
) count
< GET_SUBSEQUENT_VB_MAX_ELTS();
1153 ok
= HAVE_TRI_STRIPS
;
1157 ok
= (GLint
) count
< GET_SUBSEQUENT_VB_MAX_ELTS();
1160 ok
= HAVE_TRIANGLES
; /* flatshading is ok. */
1168 /* fprintf(stderr, "not ok %s\n", _mesa_enum_to_string(prim & PRIM_MODE_MASK)); */