t_dd_dmatmp.h: Silence unused value warning in render_line_loop_verts.
[mesa.git] / src / mesa / tnl_dd / t_dd_dmatmp2.h
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5.1
4 *
5 * Copyright (C) 1999-2006 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 /**
30 * \file t_dd_dmatmp2.h
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.
35 *
36 */
37
38 #if !HAVE_TRIANGLES || !HAVE_POINTS || !HAVE_LINES
39 #error "must have points, lines & triangles to use render template"
40 #endif
41
42 #if !HAVE_TRI_STRIPS || !HAVE_TRI_FANS
43 #error "must have tri strip and fans to use render template"
44 #endif
45
46 #if !HAVE_LINE_STRIPS
47 #error "must have line strips to use render template"
48 #endif
49
50 #if !HAVE_POLYGONS
51 #error "must have polygons to use render template"
52 #endif
53
54 #if !HAVE_ELTS
55 #error "must have elts to use render template"
56 #endif
57
58
59 #ifndef EMIT_TWO_ELTS
60 #define EMIT_TWO_ELTS( dest, offset, elt0, elt1 ) \
61 do { \
62 (dest)[offset] = (elt0); \
63 (dest)[offset+1] = (elt1); \
64 } while (0)
65 #endif
66
67
68 /**********************************************************************/
69 /* Render whole begin/end objects */
70 /**********************************************************************/
71
72
73 static ELT_TYPE *TAG(emit_elts)( GLcontext *ctx,
74 ELT_TYPE *dest,
75 GLuint *elts, GLuint nr )
76 {
77 GLint i;
78 LOCAL_VARS;
79
80 for ( i = 0 ; i+1 < nr ; i+=2, elts += 2 ) {
81 EMIT_TWO_ELTS( dest, 0, elts[0], elts[1] );
82 dest += 2;
83 }
84 if (i < nr) {
85 EMIT_ELT( dest, 0, elts[0] );
86 dest += 1;
87 }
88
89 return dest;
90 }
91
92 static ELT_TYPE *TAG(emit_consecutive_elts)( GLcontext *ctx,
93 ELT_TYPE *dest,
94 GLuint start, GLuint nr )
95 {
96 GLint i;
97 LOCAL_VARS;
98
99 for ( i = 0 ; i+1 < nr ; i+=2, start += 2 ) {
100 EMIT_TWO_ELTS( dest, 0, start, start+1 );
101 dest += 2;
102 }
103 if (i < nr) {
104 EMIT_ELT( dest, 0, start );
105 dest += 1;
106 }
107
108 return dest;
109 }
110
111 /***********************************************************************
112 * Render non-indexed primitives.
113 ***********************************************************************/
114
115
116
117 static void TAG(render_points_verts)( GLcontext *ctx,
118 GLuint start,
119 GLuint count,
120 GLuint flags )
121 {
122 if (start < count) {
123 LOCAL_VARS;
124 if (0) fprintf(stderr, "%s\n", __FUNCTION__);
125 EMIT_PRIM( ctx, GL_POINTS, HW_POINTS, start, count );
126 }
127 }
128
129 static void TAG(render_lines_verts)( GLcontext *ctx,
130 GLuint start,
131 GLuint count,
132 GLuint flags )
133 {
134 LOCAL_VARS;
135 if (0) fprintf(stderr, "%s\n", __FUNCTION__);
136 count -= (count-start) & 1;
137
138 if (start+1 >= count)
139 return;
140
141 if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag) {
142 RESET_STIPPLE();
143 AUTO_STIPPLE( GL_TRUE );
144 }
145
146 EMIT_PRIM( ctx, GL_LINES, HW_LINES, start, count );
147
148 if ((flags & PRIM_END) && ctx->Line.StippleFlag)
149 AUTO_STIPPLE( GL_FALSE );
150 }
151
152
153 static void TAG(render_line_strip_verts)( GLcontext *ctx,
154 GLuint start,
155 GLuint count,
156 GLuint flags )
157 {
158 LOCAL_VARS;
159 if (0) fprintf(stderr, "%s\n", __FUNCTION__);
160
161 if (start+1 >= count)
162 return;
163
164 if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag)
165 RESET_STIPPLE();
166
167
168 if (PREFER_DISCRETE_ELT_PRIM( count-start, HW_LINES ))
169 {
170 int dmasz = GET_MAX_HW_ELTS();
171 GLuint j, nr;
172
173 ELT_INIT( GL_LINES, HW_LINES );
174
175 /* Emit whole number of lines in each full buffer.
176 */
177 dmasz = dmasz/2;
178
179
180 for (j = start; j + 1 < count; j += nr - 1 ) {
181 ELT_TYPE *dest;
182 GLint i;
183
184 nr = MIN2( dmasz, count - j );
185 dest = ALLOC_ELTS( (nr-1)*2 );
186
187 for ( i = j ; i+1 < j+nr ; i+=1 ) {
188 EMIT_TWO_ELTS( dest, 0, (i+0), (i+1) );
189 dest += 2;
190 }
191
192 CLOSE_ELTS();
193 }
194 }
195 else
196 EMIT_PRIM( ctx, GL_LINE_STRIP, HW_LINE_STRIP, start, count );
197 }
198
199
200 static void TAG(render_line_loop_verts)( GLcontext *ctx,
201 GLuint start,
202 GLuint count,
203 GLuint flags )
204 {
205 LOCAL_VARS;
206 GLuint j, nr;
207 if (0) fprintf(stderr, "%s\n", __FUNCTION__);
208
209 if (flags & PRIM_BEGIN) {
210 j = start;
211 if (ctx->Line.StippleFlag)
212 RESET_STIPPLE( );
213 }
214 else
215 j = start + 1;
216
217 if (flags & PRIM_END) {
218
219 if (start+1 >= count)
220 return;
221
222 if (PREFER_DISCRETE_ELT_PRIM( count-start, HW_LINES )) {
223 int dmasz = GET_MAX_HW_ELTS();
224
225 ELT_INIT( GL_LINES, HW_LINES );
226
227 /* Emit whole number of lines in each full buffer.
228 */
229 dmasz = dmasz/2;
230
231 /* Ensure last vertex doesn't wrap:
232 */
233 dmasz--;
234
235 for (; j + 1 < count; ) {
236 GLint i;
237 ELT_TYPE *dest;
238
239 nr = MIN2( dmasz, count - j );
240 dest = ALLOC_ELTS( nr*2 ); /* allocs room for 1 more line */
241
242 for ( i = 0 ; i < nr - 1 ; i+=1 ) {
243 EMIT_TWO_ELTS( dest, 0, (j+i), (j+i+1) );
244 dest += 2;
245 }
246
247 j += nr - 1;
248
249 /* Emit 1 more line into space alloced above */
250 if (j + 1 >= count) {
251 EMIT_TWO_ELTS( dest, 0, (j), (start) );
252 dest += 2;
253 }
254
255 CLOSE_ELTS();
256 }
257 }
258 else
259 {
260 int dmasz = GET_MAX_HW_ELTS() - 1;
261
262 ELT_INIT( GL_LINE_STRIP, HW_LINE_STRIP );
263
264 for ( ; j + 1 < count; ) {
265 nr = MIN2( dmasz, count - j );
266 if (j + nr < count) {
267 ELT_TYPE *dest = ALLOC_ELTS( nr );
268 dest = TAG(emit_consecutive_elts)( ctx, dest, j, nr );
269 j += nr - 1;
270 CLOSE_ELTS();
271 }
272 else if (nr) {
273 ELT_TYPE *dest = ALLOC_ELTS( nr + 1 );
274 dest = TAG(emit_consecutive_elts)( ctx, dest, j, nr );
275 dest = TAG(emit_consecutive_elts)( ctx, dest, start, 1 );
276 j += nr;
277 CLOSE_ELTS();
278 }
279 }
280 }
281 } else {
282 TAG(render_line_strip_verts)( ctx, j, count, flags );
283 }
284 }
285
286
287 static void TAG(render_triangles_verts)( GLcontext *ctx,
288 GLuint start,
289 GLuint count,
290 GLuint flags )
291 {
292 LOCAL_VARS;
293 if (0) fprintf(stderr, "%s\n", __FUNCTION__);
294
295 count -= (count-start)%3;
296
297 if (start+2 >= count) {
298 return;
299 }
300
301 /* need a PREFER_DISCRETE_ELT_PRIM here too..
302 */
303 EMIT_PRIM( ctx, GL_TRIANGLES, HW_TRIANGLES, start, count );
304 }
305
306
307
308 static void TAG(render_tri_strip_verts)( GLcontext *ctx,
309 GLuint start,
310 GLuint count,
311 GLuint flags )
312 {
313 LOCAL_VARS;
314 if (0) fprintf(stderr, "%s\n", __FUNCTION__);
315
316 if (start + 2 >= count)
317 return;
318
319 if (PREFER_DISCRETE_ELT_PRIM( count-start, HW_TRIANGLES ))
320 {
321 int dmasz = GET_MAX_HW_ELTS();
322 int parity = 0;
323 GLuint j, nr;
324
325 ELT_INIT( GL_TRIANGLES, HW_TRIANGLES );
326
327 /* Emit even number of tris in each full buffer.
328 */
329 dmasz = dmasz/3;
330 dmasz -= dmasz & 1;
331
332 for (j = start; j + 2 < count; j += nr - 2 ) {
333 ELT_TYPE *dest;
334 GLint i;
335
336 nr = MIN2( dmasz, count - j );
337 dest = ALLOC_ELTS( (nr-2)*3 );
338
339 for ( i = j ; i+2 < j+nr ; i++, parity^=1 ) {
340 EMIT_ELT( dest, 0, (i+0+parity) );
341 EMIT_ELT( dest, 1, (i+1-parity) );
342 EMIT_ELT( dest, 2, (i+2) );
343 dest += 3;
344 }
345
346 CLOSE_ELTS();
347 }
348 }
349 else
350 EMIT_PRIM( ctx, GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_0, start, count );
351 }
352
353 static void TAG(render_tri_fan_verts)( GLcontext *ctx,
354 GLuint start,
355 GLuint count,
356 GLuint flags )
357 {
358 LOCAL_VARS;
359 if (0) fprintf(stderr, "%s\n", __FUNCTION__);
360
361 if (start+2 >= count)
362 return;
363
364 if (PREFER_DISCRETE_ELT_PRIM( count-start, HW_TRIANGLES ))
365 {
366 int dmasz = GET_MAX_HW_ELTS();
367 GLuint j, nr;
368
369 ELT_INIT( GL_TRIANGLES, HW_TRIANGLES );
370
371 dmasz = dmasz/3;
372
373 for (j = start + 1; j + 1 < count; j += nr - 1 ) {
374 ELT_TYPE *dest;
375 GLint i;
376
377 nr = MIN2( dmasz, count - j );
378 dest = ALLOC_ELTS( (nr-1)*3 );
379
380 for ( i = j ; i+1 < j+nr ; i++ ) {
381 EMIT_ELT( dest, 0, (start) );
382 EMIT_ELT( dest, 1, (i) );
383 EMIT_ELT( dest, 2, (i+1) );
384 dest += 3;
385 }
386
387 CLOSE_ELTS();
388 }
389 }
390 else {
391 EMIT_PRIM( ctx, GL_TRIANGLE_FAN, HW_TRIANGLE_FAN, start, count );
392 }
393 }
394
395
396 static void TAG(render_poly_verts)( GLcontext *ctx,
397 GLuint start,
398 GLuint count,
399 GLuint flags )
400 {
401 LOCAL_VARS;
402 if (0) fprintf(stderr, "%s\n", __FUNCTION__);
403
404 if (start+2 >= count)
405 return;
406
407 EMIT_PRIM( ctx, GL_POLYGON, HW_POLYGON, start, count );
408 }
409
410 static void TAG(render_quad_strip_verts)( GLcontext *ctx,
411 GLuint start,
412 GLuint count,
413 GLuint flags )
414 {
415 LOCAL_VARS;
416 if (0) fprintf(stderr, "%s\n", __FUNCTION__);
417
418 count -= (count-start) & 1;
419
420 if (start+3 >= count)
421 return;
422
423 if (HAVE_QUAD_STRIPS) {
424 EMIT_PRIM( ctx, GL_QUAD_STRIP, HW_QUAD_STRIP, start, count );
425 }
426 else if (ctx->Light.ShadeModel == GL_FLAT) {
427 LOCAL_VARS;
428 int dmasz = GET_MAX_HW_ELTS();
429 GLuint j, nr;
430
431 ELT_INIT( GL_TRIANGLES, HW_TRIANGLES );
432
433 /* Emit whole number of quads in total, and in each buffer.
434 */
435 dmasz = (dmasz/6)*2;
436
437 for (j = start; j + 3 < count; j += nr - 2 ) {
438 ELT_TYPE *dest;
439 GLint quads, i;
440
441 nr = MIN2( dmasz, count - j );
442 quads = (nr/2)-1;
443 dest = ALLOC_ELTS( quads*6 );
444
445 for ( i = j ; i < j+quads*2 ; i+=2 ) {
446 EMIT_TWO_ELTS( dest, 0, (i+0), (i+1) );
447 EMIT_TWO_ELTS( dest, 2, (i+2), (i+1) );
448 EMIT_TWO_ELTS( dest, 4, (i+3), (i+2) );
449 dest += 6;
450 }
451
452 CLOSE_ELTS();
453 }
454 }
455 else {
456 EMIT_PRIM( ctx, GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_0, start, count );
457 }
458 }
459
460
461 static void TAG(render_quads_verts)( GLcontext *ctx,
462 GLuint start,
463 GLuint count,
464 GLuint flags )
465 {
466 LOCAL_VARS;
467 if (0) fprintf(stderr, "%s\n", __FUNCTION__);
468 count -= (count-start)%4;
469
470 if (start+3 >= count)
471 return;
472
473 if (HAVE_QUADS) {
474 EMIT_PRIM( ctx, GL_QUADS, HW_QUADS, start, count );
475 }
476 else {
477 /* Hardware doesn't have a quad primitive type -- simulate it
478 * using indexed vertices and the triangle primitive:
479 */
480 LOCAL_VARS;
481 int dmasz = GET_MAX_HW_ELTS();
482 GLuint j, nr;
483
484 ELT_INIT( GL_TRIANGLES, HW_TRIANGLES );
485
486 /* Adjust for rendering as triangles:
487 */
488 dmasz = (dmasz/6)*4;
489
490 for (j = start; j < count; j += nr ) {
491 ELT_TYPE *dest;
492 GLint quads, i;
493
494 nr = MIN2( dmasz, count - j );
495 quads = nr/4;
496 dest = ALLOC_ELTS( quads*6 );
497
498 for ( i = j ; i < j+quads*4 ; i+=4 ) {
499 EMIT_TWO_ELTS( dest, 0, (i+0), (i+1) );
500 EMIT_TWO_ELTS( dest, 2, (i+3), (i+1) );
501 EMIT_TWO_ELTS( dest, 4, (i+2), (i+3) );
502 dest += 6;
503 }
504
505 CLOSE_ELTS();
506 }
507 }
508 }
509
510 static void TAG(render_noop)( GLcontext *ctx,
511 GLuint start,
512 GLuint count,
513 GLuint flags )
514 {
515 }
516
517
518
519
520 static tnl_render_func TAG(render_tab_verts)[GL_POLYGON+2] =
521 {
522 TAG(render_points_verts),
523 TAG(render_lines_verts),
524 TAG(render_line_loop_verts),
525 TAG(render_line_strip_verts),
526 TAG(render_triangles_verts),
527 TAG(render_tri_strip_verts),
528 TAG(render_tri_fan_verts),
529 TAG(render_quads_verts),
530 TAG(render_quad_strip_verts),
531 TAG(render_poly_verts),
532 TAG(render_noop),
533 };
534
535
536 /****************************************************************************
537 * Render elts using hardware indexed verts *
538 ****************************************************************************/
539
540 static void TAG(render_points_elts)( GLcontext *ctx,
541 GLuint start,
542 GLuint count,
543 GLuint flags )
544 {
545 LOCAL_VARS;
546 int dmasz = GET_MAX_HW_ELTS();
547 GLuint *elts = GET_MESA_ELTS();
548 GLuint j, nr;
549 ELT_TYPE *dest;
550
551 ELT_INIT( GL_POINTS, HW_POINTS );
552
553 for (j = start; j < count; j += nr ) {
554 nr = MIN2( dmasz, count - j );
555 dest = ALLOC_ELTS( nr );
556 dest = TAG(emit_elts)( ctx, dest, elts+j, nr );
557 CLOSE_ELTS();
558 }
559 }
560
561
562
563 static void TAG(render_lines_elts)( GLcontext *ctx,
564 GLuint start,
565 GLuint count,
566 GLuint flags )
567 {
568 LOCAL_VARS;
569 int dmasz = GET_MAX_HW_ELTS();
570 GLuint *elts = GET_MESA_ELTS();
571 GLuint j, nr;
572 ELT_TYPE *dest;
573
574 if (start+1 >= count)
575 return;
576
577 if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag) {
578 RESET_STIPPLE();
579 AUTO_STIPPLE( GL_TRUE );
580 }
581
582 ELT_INIT( GL_LINES, HW_LINES );
583
584 /* Emit whole number of lines in total and in each buffer:
585 */
586 count -= (count-start) & 1;
587 dmasz -= dmasz & 1;
588
589 for (j = start; j < count; j += nr ) {
590 nr = MIN2( dmasz, count - j );
591 dest = ALLOC_ELTS( nr );
592 dest = TAG(emit_elts)( ctx, dest, elts+j, nr );
593 CLOSE_ELTS();
594 }
595
596 if ((flags & PRIM_END) && ctx->Line.StippleFlag)
597 AUTO_STIPPLE( GL_FALSE );
598 }
599
600
601 static void TAG(render_line_strip_elts)( GLcontext *ctx,
602 GLuint start,
603 GLuint count,
604 GLuint flags )
605 {
606 LOCAL_VARS;
607 int dmasz = GET_MAX_HW_ELTS();
608 GLuint *elts = GET_MESA_ELTS();
609 GLuint j, nr;
610 ELT_TYPE *dest;
611
612 if (start+1 >= count)
613 return;
614
615 ELT_INIT( GL_LINE_STRIP, HW_LINE_STRIP );
616
617 if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag)
618 RESET_STIPPLE();
619
620 for (j = start; j + 1 < count; j += nr - 1 ) {
621 nr = MIN2( dmasz, count - j );
622 dest = ALLOC_ELTS( nr );
623 dest = TAG(emit_elts)( ctx, dest, elts+j, nr );
624 CLOSE_ELTS();
625 }
626 }
627
628
629 static void TAG(render_line_loop_elts)( GLcontext *ctx,
630 GLuint start,
631 GLuint count,
632 GLuint flags )
633 {
634 LOCAL_VARS;
635 int dmasz = GET_MAX_HW_ELTS();
636 GLuint *elts = GET_MESA_ELTS();
637 GLuint j, nr;
638 ELT_TYPE *dest;
639
640 if (0) fprintf(stderr, "%s\n", __FUNCTION__);
641
642 if (flags & PRIM_BEGIN)
643 j = start;
644 else
645 j = start + 1;
646
647
648 if (flags & PRIM_END) {
649 if (start+1 >= count)
650 return;
651 }
652 else {
653 if (j+1 >= count)
654 return;
655 }
656
657 ELT_INIT( GL_LINE_STRIP, HW_LINE_STRIP );
658
659 if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag)
660 RESET_STIPPLE();
661
662
663 /* Ensure last vertex doesn't wrap:
664 */
665 dmasz--;
666
667 for ( ; j + 1 < count; ) {
668 nr = MIN2( dmasz, count - j );
669 dest = ALLOC_ELTS( nr+1 ); /* Reserve possible space for last elt */
670 dest = TAG(emit_elts)( ctx, dest, elts+j, nr );
671 j += nr - 1;
672 if (j + 1 >= count && (flags & PRIM_END)) {
673 dest = TAG(emit_elts)( ctx, dest, elts+start, 1 );
674 }
675 CLOSE_ELTS();
676 }
677 }
678
679
680 static void TAG(render_triangles_elts)( GLcontext *ctx,
681 GLuint start,
682 GLuint count,
683 GLuint flags )
684 {
685 LOCAL_VARS;
686 GLuint *elts = GET_MESA_ELTS();
687 int dmasz = GET_MAX_HW_ELTS()/3*3;
688 GLuint j, nr;
689 ELT_TYPE *dest;
690
691 if (start+2 >= count)
692 return;
693
694 ELT_INIT( GL_TRIANGLES, HW_TRIANGLES );
695
696
697 /* Emit whole number of tris in total. dmasz is already a multiple
698 * of 3.
699 */
700 count -= (count-start)%3;
701
702 for (j = start; j < count; j += nr) {
703 nr = MIN2( dmasz, count - j );
704 dest = ALLOC_ELTS( nr );
705 dest = TAG(emit_elts)( ctx, dest, elts+j, nr );
706 CLOSE_ELTS();
707 }
708 }
709
710
711
712 static void TAG(render_tri_strip_elts)( GLcontext *ctx,
713 GLuint start,
714 GLuint count,
715 GLuint flags )
716 {
717 LOCAL_VARS;
718 GLuint j, nr;
719 GLuint *elts = GET_MESA_ELTS();
720 int dmasz = GET_MAX_HW_ELTS();
721 ELT_TYPE *dest;
722
723 if (start+2 >= count)
724 return;
725
726 ELT_INIT( GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_0 );
727
728 /* Keep the same winding over multiple buffers:
729 */
730 dmasz -= (dmasz & 1);
731
732 for (j = start ; j + 2 < count; j += nr - 2 ) {
733 nr = MIN2( dmasz, count - j );
734
735 dest = ALLOC_ELTS( nr );
736 dest = TAG(emit_elts)( ctx, dest, elts+j, nr );
737 CLOSE_ELTS();
738 }
739 }
740
741 static void TAG(render_tri_fan_elts)( GLcontext *ctx,
742 GLuint start,
743 GLuint count,
744 GLuint flags )
745 {
746 LOCAL_VARS;
747 GLuint *elts = GET_MESA_ELTS();
748 GLuint j, nr;
749 int dmasz = GET_MAX_HW_ELTS();
750 ELT_TYPE *dest;
751
752 if (start+2 >= count)
753 return;
754
755 ELT_INIT( GL_TRIANGLE_FAN, HW_TRIANGLE_FAN );
756
757 for (j = start + 1 ; j + 1 < count; j += nr - 1 ) {
758 nr = MIN2( dmasz, count - j + 1 );
759 dest = ALLOC_ELTS( nr );
760 dest = TAG(emit_elts)( ctx, dest, elts+start, 1 );
761 dest = TAG(emit_elts)( ctx, dest, elts+j, nr - 1 );
762 CLOSE_ELTS();
763 }
764 }
765
766
767 static void TAG(render_poly_elts)( GLcontext *ctx,
768 GLuint start,
769 GLuint count,
770 GLuint flags )
771 {
772 LOCAL_VARS;
773 GLuint *elts = GET_MESA_ELTS();
774 GLuint j, nr;
775 int dmasz = GET_MAX_HW_ELTS();
776 ELT_TYPE *dest;
777
778 if (start+2 >= count)
779 return;
780
781 ELT_INIT( GL_POLYGON, HW_POLYGON );
782
783 for (j = start + 1 ; j + 1 < count ; j += nr - 1 ) {
784 nr = MIN2( dmasz, count - j + 1 );
785 dest = ALLOC_ELTS( nr );
786 dest = TAG(emit_elts)( ctx, dest, elts+start, 1 );
787 dest = TAG(emit_elts)( ctx, dest, elts+j, nr - 1 );
788 CLOSE_ELTS();
789 }
790 }
791
792 static void TAG(render_quad_strip_elts)( GLcontext *ctx,
793 GLuint start,
794 GLuint count,
795 GLuint flags )
796 {
797 if (start+3 >= count)
798 return;
799
800 if (HAVE_QUAD_STRIPS && 0) {
801 }
802 else {
803 LOCAL_VARS;
804 GLuint *elts = GET_MESA_ELTS();
805 int dmasz = GET_MAX_HW_ELTS();
806 GLuint j, nr;
807 ELT_TYPE *dest;
808
809 /* Emit whole number of quads in total, and in each buffer.
810 */
811 dmasz -= dmasz & 1;
812 count -= (count-start) & 1;
813
814 if (ctx->Light.ShadeModel == GL_FLAT) {
815 ELT_INIT( GL_TRIANGLES, HW_TRIANGLES );
816
817 dmasz = dmasz/6*2;
818
819 for (j = start; j + 3 < count; j += nr - 2 ) {
820 nr = MIN2( dmasz, count - j );
821
822 if (nr >= 4)
823 {
824 GLint quads = (nr/2)-1;
825 ELT_TYPE *dest = ALLOC_ELTS( quads*6 );
826 GLint i;
827
828 for ( i = j-start ; i < j-start+quads ; i++, elts += 2 ) {
829 EMIT_TWO_ELTS( dest, 0, elts[0], elts[1] );
830 EMIT_TWO_ELTS( dest, 2, elts[2], elts[1] );
831 EMIT_TWO_ELTS( dest, 4, elts[3], elts[2] );
832 dest += 6;
833 }
834
835 CLOSE_ELTS();
836 }
837 }
838 }
839 else {
840 ELT_INIT( GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_0 );
841
842 for (j = start; j + 3 < count; j += nr - 2 ) {
843 nr = MIN2( dmasz, count - j );
844 dest = ALLOC_ELTS( nr );
845 dest = TAG(emit_elts)( ctx, dest, elts+j, nr );
846 CLOSE_ELTS();
847 }
848 }
849 }
850 }
851
852
853 static void TAG(render_quads_elts)( GLcontext *ctx,
854 GLuint start,
855 GLuint count,
856 GLuint flags )
857 {
858 if (start+3 >= count)
859 return;
860
861 if (HAVE_QUADS && 0) {
862 } else {
863 LOCAL_VARS;
864 GLuint *elts = GET_MESA_ELTS();
865 int dmasz = GET_MAX_HW_ELTS();
866 GLuint j, nr;
867
868 ELT_INIT( GL_TRIANGLES, HW_TRIANGLES );
869
870 /* Emit whole number of quads in total, and in each buffer.
871 */
872 dmasz -= dmasz & 3;
873 count -= (count-start) & 3;
874
875 /* Adjust for rendering as triangles:
876 */
877 dmasz = dmasz/6*4;
878
879 for (j = start; j + 3 < count; j += nr ) {
880 nr = MIN2( dmasz, count - j );
881
882 {
883 GLint quads = nr/4;
884 ELT_TYPE *dest = ALLOC_ELTS( quads * 6 );
885 GLint i;
886
887 for ( i = j-start ; i < j-start+quads ; i++, elts += 4 ) {
888 EMIT_TWO_ELTS( dest, 0, elts[0], elts[1] );
889 EMIT_TWO_ELTS( dest, 2, elts[3], elts[1] );
890 EMIT_TWO_ELTS( dest, 4, elts[2], elts[3] );
891 dest += 6;
892 }
893
894 CLOSE_ELTS();
895 }
896 }
897 }
898 }
899
900
901
902 static tnl_render_func TAG(render_tab_elts)[GL_POLYGON+2] =
903 {
904 TAG(render_points_elts),
905 TAG(render_lines_elts),
906 TAG(render_line_loop_elts),
907 TAG(render_line_strip_elts),
908 TAG(render_triangles_elts),
909 TAG(render_tri_strip_elts),
910 TAG(render_tri_fan_elts),
911 TAG(render_quads_elts),
912 TAG(render_quad_strip_elts),
913 TAG(render_poly_elts),
914 TAG(render_noop),
915 };