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