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