t_dd_dmatmp2.h revision 47909141985a5aa38a49ea45b3aea795f1922dfb
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 ) \ 60do { \ 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 72static 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 91static 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 116static 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 128static 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 152static 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 199static 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 286static 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 307static 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 352static 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 395static 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 409static 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 460static 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 509static void TAG(render_noop)( GLcontext *ctx, 510 GLuint start, 511 GLuint count, 512 GLuint flags ) 513{ 514} 515 516 517 518 519static 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 539static 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 562static 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 600static 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 628static 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 679static 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 711static 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 740static 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 766static 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 791static 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 852static 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 901static 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}; 915