1/************************************************************************** 2 * 3 * Copyright 2003 VMware, Inc. 4 * Copyright 2009 VMware, Inc. 5 * 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 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation the rights to use, copy, modify, merge, publish, 11 * distribute, sub license, and/or sell copies of the Software, and to 12 * permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the 16 * next paragraph) shall be included in all copies or substantial portions 17 * of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * 27 **************************************************************************/ 28 29#include <stdio.h> 30#include "arrayobj.h" 31#include "glheader.h" 32#include "c99_alloca.h" 33#include "context.h" 34#include "state.h" 35#include "draw.h" 36#include "draw_validate.h" 37#include "dispatch.h" 38#include "varray.h" 39#include "bufferobj.h" 40#include "enums.h" 41#include "macros.h" 42#include "transformfeedback.h" 43 44typedef struct { 45 GLuint count; 46 GLuint primCount; 47 GLuint first; 48 GLuint baseInstance; 49} DrawArraysIndirectCommand; 50 51typedef struct { 52 GLuint count; 53 GLuint primCount; 54 GLuint firstIndex; 55 GLint baseVertex; 56 GLuint baseInstance; 57} DrawElementsIndirectCommand; 58 59 60/** 61 * Check that element 'j' of the array has reasonable data. 62 * Map VBO if needed. 63 * For debugging purposes; not normally used. 64 */ 65static void 66check_array_data(struct gl_context *ctx, struct gl_vertex_array_object *vao, 67 GLuint attrib, GLuint j) 68{ 69 const struct gl_array_attributes *array = &vao->VertexAttrib[attrib]; 70 if (vao->Enabled & VERT_BIT(attrib)) { 71 const struct gl_vertex_buffer_binding *binding = 72 &vao->BufferBinding[array->BufferBindingIndex]; 73 struct gl_buffer_object *bo = binding->BufferObj; 74 const void *data = array->Ptr; 75 if (_mesa_is_bufferobj(bo)) { 76 data = ADD_POINTERS(_mesa_vertex_attrib_address(array, binding), 77 bo->Mappings[MAP_INTERNAL].Pointer); 78 } 79 switch (array->Format.Type) { 80 case GL_FLOAT: 81 { 82 GLfloat *f = (GLfloat *) ((GLubyte *) data + binding->Stride * j); 83 GLint k; 84 for (k = 0; k < array->Format.Size; k++) { 85 if (IS_INF_OR_NAN(f[k]) || f[k] >= 1.0e20F || f[k] <= -1.0e10F) { 86 printf("Bad array data:\n"); 87 printf(" Element[%u].%u = %f\n", j, k, f[k]); 88 printf(" Array %u at %p\n", attrib, (void *) array); 89 printf(" Type 0x%x, Size %d, Stride %d\n", 90 array->Format.Type, array->Format.Size, 91 binding->Stride); 92 printf(" Address/offset %p in Buffer Object %u\n", 93 array->Ptr, bo->Name); 94 f[k] = 1.0F; /* XXX replace the bad value! */ 95 } 96 /*assert(!IS_INF_OR_NAN(f[k])); */ 97 } 98 } 99 break; 100 default: 101 ; 102 } 103 } 104} 105 106 107static inline int 108sizeof_ib_type(GLenum type) 109{ 110 switch (type) { 111 case GL_UNSIGNED_INT: 112 return sizeof(GLuint); 113 case GL_UNSIGNED_SHORT: 114 return sizeof(GLushort); 115 case GL_UNSIGNED_BYTE: 116 return sizeof(GLubyte); 117 default: 118 assert(!"unsupported index data type"); 119 /* In case assert is turned off */ 120 return 0; 121 } 122} 123 124/** 125 * Examine the array's data for NaNs, etc. 126 * For debug purposes; not normally used. 127 */ 128static void 129check_draw_elements_data(struct gl_context *ctx, GLsizei count, 130 GLenum elemType, const void *elements, 131 GLint basevertex) 132{ 133 struct gl_vertex_array_object *vao = ctx->Array.VAO; 134 GLint i; 135 GLuint k; 136 137 _mesa_vao_map(ctx, vao, GL_MAP_READ_BIT); 138 139 if (_mesa_is_bufferobj(vao->IndexBufferObj)) 140 elements = 141 ADD_POINTERS(vao->IndexBufferObj->Mappings[MAP_INTERNAL].Pointer, elements); 142 143 for (i = 0; i < count; i++) { 144 GLuint j; 145 146 /* j = element[i] */ 147 switch (elemType) { 148 case GL_UNSIGNED_BYTE: 149 j = ((const GLubyte *) elements)[i]; 150 break; 151 case GL_UNSIGNED_SHORT: 152 j = ((const GLushort *) elements)[i]; 153 break; 154 case GL_UNSIGNED_INT: 155 j = ((const GLuint *) elements)[i]; 156 break; 157 default: 158 unreachable("Unexpected index buffer type"); 159 } 160 161 /* check element j of each enabled array */ 162 for (k = 0; k < VERT_ATTRIB_MAX; k++) { 163 check_array_data(ctx, vao, k, j); 164 } 165 } 166 167 _mesa_vao_unmap(ctx, vao); 168} 169 170 171/** 172 * Check array data, looking for NaNs, etc. 173 */ 174static void 175check_draw_arrays_data(struct gl_context *ctx, GLint start, GLsizei count) 176{ 177 /* TO DO */ 178} 179 180 181/** 182 * Check if we should skip the draw call even after validation was successful. 183 */ 184static bool 185skip_validated_draw(struct gl_context *ctx) 186{ 187 switch (ctx->API) { 188 case API_OPENGLES2: 189 /* For ES2, we can draw if we have a vertex program/shader). */ 190 return ctx->VertexProgram._Current == NULL; 191 192 case API_OPENGLES: 193 /* For OpenGL ES, only draw if we have vertex positions 194 */ 195 if (!(ctx->Array.VAO->Enabled & VERT_BIT_POS)) 196 return true; 197 break; 198 199 case API_OPENGL_CORE: 200 /* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec 201 * says: 202 * 203 * "If there is no active program for the vertex or fragment shader 204 * stages, the results of vertex and/or fragment processing will be 205 * undefined. However, this is not an error." 206 * 207 * The fragment shader is not tested here because other state (e.g., 208 * GL_RASTERIZER_DISCARD) affects whether or not we actually care. 209 */ 210 return ctx->VertexProgram._Current == NULL; 211 212 case API_OPENGL_COMPAT: 213 if (ctx->VertexProgram._Current != NULL) { 214 /* Draw regardless of whether or not we have any vertex arrays. 215 * (Ex: could draw a point using a constant vertex pos) 216 */ 217 return false; 218 } else { 219 /* Draw if we have vertex positions (GL_VERTEX_ARRAY or generic 220 * array [0]). 221 */ 222 return !(ctx->Array.VAO->Enabled & (VERT_BIT_POS|VERT_BIT_GENERIC0)); 223 } 224 break; 225 226 default: 227 unreachable("Invalid API value in check_valid_to_render()"); 228 } 229 230 return false; 231} 232 233 234/** 235 * Print info/data for glDrawArrays(), for debugging. 236 */ 237static void 238print_draw_arrays(struct gl_context *ctx, 239 GLenum mode, GLint start, GLsizei count) 240{ 241 struct gl_vertex_array_object *vao = ctx->Array.VAO; 242 243 printf("_mesa_DrawArrays(mode 0x%x, start %d, count %d):\n", 244 mode, start, count); 245 246 _mesa_vao_map_arrays(ctx, vao, GL_MAP_READ_BIT); 247 248 GLbitfield mask = vao->Enabled; 249 while (mask) { 250 const gl_vert_attrib i = u_bit_scan(&mask); 251 const struct gl_array_attributes *array = &vao->VertexAttrib[i]; 252 253 const struct gl_vertex_buffer_binding *binding = 254 &vao->BufferBinding[array->BufferBindingIndex]; 255 struct gl_buffer_object *bufObj = binding->BufferObj; 256 257 printf("attr %s: size %d stride %d " 258 "ptr %p Bufobj %u\n", 259 gl_vert_attrib_name((gl_vert_attrib) i), 260 array->Format.Size, binding->Stride, 261 array->Ptr, bufObj->Name); 262 263 if (_mesa_is_bufferobj(bufObj)) { 264 GLubyte *p = bufObj->Mappings[MAP_INTERNAL].Pointer; 265 int offset = (int) (GLintptr) 266 _mesa_vertex_attrib_address(array, binding); 267 268 unsigned multiplier; 269 switch (array->Format.Type) { 270 case GL_DOUBLE: 271 case GL_INT64_ARB: 272 case GL_UNSIGNED_INT64_ARB: 273 multiplier = 2; 274 break; 275 default: 276 multiplier = 1; 277 } 278 279 float *f = (float *) (p + offset); 280 int *k = (int *) f; 281 int i = 0; 282 int n = (count - 1) * (binding->Stride / (4 * multiplier)) 283 + array->Format.Size; 284 if (n > 32) 285 n = 32; 286 printf(" Data at offset %d:\n", offset); 287 do { 288 if (multiplier == 2) 289 printf(" double[%d] = 0x%016llx %lf\n", i, 290 ((unsigned long long *) k)[i], ((double *) f)[i]); 291 else 292 printf(" float[%d] = 0x%08x %f\n", i, k[i], f[i]); 293 i++; 294 } while (i < n); 295 } 296 } 297 298 _mesa_vao_unmap_arrays(ctx, vao); 299} 300 301 302/** 303 * Return a filter mask for the net enabled vao arrays. 304 * This is to mask out arrays that would otherwise supersed required current 305 * values for the fixed function shaders for example. 306 */ 307static GLbitfield 308enabled_filter(const struct gl_context *ctx) 309{ 310 switch (ctx->VertexProgram._VPMode) { 311 case VP_MODE_FF: 312 /* When no vertex program is active (or the vertex program is generated 313 * from fixed-function state). We put the material values into the 314 * generic slots. Since the vao has no material arrays, mute these 315 * slots from the enabled arrays so that the current material values 316 * are pulled instead of the vao arrays. 317 */ 318 return VERT_BIT_FF_ALL; 319 320 case VP_MODE_SHADER: 321 /* There are no shaders in OpenGL ES 1.x, so this code path should be 322 * impossible to reach. The meta code is careful to not use shaders in 323 * ES1. 324 */ 325 assert(ctx->API != API_OPENGLES); 326 327 /* Other parts of the code assume that inputs[VERT_ATTRIB_POS] through 328 * inputs[VERT_ATTRIB_FF_MAX] will be non-NULL. However, in OpenGL 329 * ES 2.0+ or OpenGL core profile, none of these arrays should ever 330 * be enabled. 331 */ 332 if (ctx->API != API_OPENGL_COMPAT) 333 return VERT_BIT_GENERIC_ALL; 334 335 return VERT_BIT_ALL; 336 337 default: 338 assert(0); 339 return 0; 340 } 341} 342 343 344/** 345 * Helper function called by the other DrawArrays() functions below. 346 * This is where we handle primitive restart for drawing non-indexed 347 * arrays. If primitive restart is enabled, it typically means 348 * splitting one DrawArrays() into two. 349 */ 350static void 351_mesa_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, 352 GLsizei count, GLuint numInstances, GLuint baseInstance, 353 GLuint drawID) 354{ 355 struct _mesa_prim prim; 356 357 if (skip_validated_draw(ctx)) 358 return; 359 360 /* OpenGL 4.5 says that primitive restart is ignored with non-indexed 361 * draws. 362 */ 363 memset(&prim, 0, sizeof(prim)); 364 prim.begin = 1; 365 prim.end = 1; 366 prim.mode = mode; 367 prim.num_instances = numInstances; 368 prim.base_instance = baseInstance; 369 prim.draw_id = drawID; 370 prim.is_indirect = 0; 371 prim.start = start; 372 prim.count = count; 373 374 ctx->Driver.Draw(ctx, &prim, 1, NULL, 375 GL_TRUE, start, start + count - 1, NULL, 0, NULL); 376 377 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 378 _mesa_flush(ctx); 379 } 380} 381 382 383/** 384 * Execute a glRectf() function. 385 */ 386static void GLAPIENTRY 387_mesa_exec_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) 388{ 389 GET_CURRENT_CONTEXT(ctx); 390 ASSERT_OUTSIDE_BEGIN_END(ctx); 391 392 CALL_Begin(GET_DISPATCH(), (GL_QUADS)); 393 CALL_Vertex2f(GET_DISPATCH(), (x1, y1)); 394 CALL_Vertex2f(GET_DISPATCH(), (x2, y1)); 395 CALL_Vertex2f(GET_DISPATCH(), (x2, y2)); 396 CALL_Vertex2f(GET_DISPATCH(), (x1, y2)); 397 CALL_End(GET_DISPATCH(), ()); 398} 399 400 401static void GLAPIENTRY 402_mesa_exec_EvalMesh1(GLenum mode, GLint i1, GLint i2) 403{ 404 GET_CURRENT_CONTEXT(ctx); 405 GLint i; 406 GLfloat u, du; 407 GLenum prim; 408 409 switch (mode) { 410 case GL_POINT: 411 prim = GL_POINTS; 412 break; 413 case GL_LINE: 414 prim = GL_LINE_STRIP; 415 break; 416 default: 417 _mesa_error(ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)"); 418 return; 419 } 420 421 /* No effect if vertex maps disabled. 422 */ 423 if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3) 424 return; 425 426 du = ctx->Eval.MapGrid1du; 427 u = ctx->Eval.MapGrid1u1 + i1 * du; 428 429 CALL_Begin(GET_DISPATCH(), (prim)); 430 for (i = i1; i <= i2; i++, u += du) { 431 CALL_EvalCoord1f(GET_DISPATCH(), (u)); 432 } 433 CALL_End(GET_DISPATCH(), ()); 434} 435 436 437static void GLAPIENTRY 438_mesa_exec_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) 439{ 440 GET_CURRENT_CONTEXT(ctx); 441 GLfloat u, du, v, dv, v1, u1; 442 GLint i, j; 443 444 switch (mode) { 445 case GL_POINT: 446 case GL_LINE: 447 case GL_FILL: 448 break; 449 default: 450 _mesa_error(ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)"); 451 return; 452 } 453 454 /* No effect if vertex maps disabled. 455 */ 456 if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3) 457 return; 458 459 du = ctx->Eval.MapGrid2du; 460 dv = ctx->Eval.MapGrid2dv; 461 v1 = ctx->Eval.MapGrid2v1 + j1 * dv; 462 u1 = ctx->Eval.MapGrid2u1 + i1 * du; 463 464 switch (mode) { 465 case GL_POINT: 466 CALL_Begin(GET_DISPATCH(), (GL_POINTS)); 467 for (v = v1, j = j1; j <= j2; j++, v += dv) { 468 for (u = u1, i = i1; i <= i2; i++, u += du) { 469 CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); 470 } 471 } 472 CALL_End(GET_DISPATCH(), ()); 473 break; 474 case GL_LINE: 475 for (v = v1, j = j1; j <= j2; j++, v += dv) { 476 CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP)); 477 for (u = u1, i = i1; i <= i2; i++, u += du) { 478 CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); 479 } 480 CALL_End(GET_DISPATCH(), ()); 481 } 482 for (u = u1, i = i1; i <= i2; i++, u += du) { 483 CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP)); 484 for (v = v1, j = j1; j <= j2; j++, v += dv) { 485 CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); 486 } 487 CALL_End(GET_DISPATCH(), ()); 488 } 489 break; 490 case GL_FILL: 491 for (v = v1, j = j1; j < j2; j++, v += dv) { 492 CALL_Begin(GET_DISPATCH(), (GL_TRIANGLE_STRIP)); 493 for (u = u1, i = i1; i <= i2; i++, u += du) { 494 CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); 495 CALL_EvalCoord2f(GET_DISPATCH(), (u, v + dv)); 496 } 497 CALL_End(GET_DISPATCH(), ()); 498 } 499 break; 500 } 501} 502 503 504/** 505 * Called from glDrawArrays when in immediate mode (not display list mode). 506 */ 507void GLAPIENTRY 508_mesa_DrawArrays(GLenum mode, GLint start, GLsizei count) 509{ 510 GET_CURRENT_CONTEXT(ctx); 511 512 if (MESA_VERBOSE & VERBOSE_DRAW) 513 _mesa_debug(ctx, "glDrawArrays(%s, %d, %d)\n", 514 _mesa_enum_to_string(mode), start, count); 515 516 FLUSH_FOR_DRAW(ctx); 517 518 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 519 520 if (_mesa_is_no_error_enabled(ctx)) { 521 if (ctx->NewState) 522 _mesa_update_state(ctx); 523 } else { 524 if (!_mesa_validate_DrawArrays(ctx, mode, count)) 525 return; 526 } 527 528 if (0) 529 check_draw_arrays_data(ctx, start, count); 530 531 _mesa_draw_arrays(ctx, mode, start, count, 1, 0, 0); 532 533 if (0) 534 print_draw_arrays(ctx, mode, start, count); 535} 536 537 538/** 539 * Called from glDrawArraysInstanced when in immediate mode (not 540 * display list mode). 541 */ 542void GLAPIENTRY 543_mesa_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count, 544 GLsizei numInstances) 545{ 546 GET_CURRENT_CONTEXT(ctx); 547 548 if (MESA_VERBOSE & VERBOSE_DRAW) 549 _mesa_debug(ctx, "glDrawArraysInstanced(%s, %d, %d, %d)\n", 550 _mesa_enum_to_string(mode), start, count, numInstances); 551 552 FLUSH_FOR_DRAW(ctx); 553 554 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 555 556 if (_mesa_is_no_error_enabled(ctx)) { 557 if (ctx->NewState) 558 _mesa_update_state(ctx); 559 } else { 560 if (!_mesa_validate_DrawArraysInstanced(ctx, mode, start, count, 561 numInstances)) 562 return; 563 } 564 565 if (0) 566 check_draw_arrays_data(ctx, start, count); 567 568 _mesa_draw_arrays(ctx, mode, start, count, numInstances, 0, 0); 569 570 if (0) 571 print_draw_arrays(ctx, mode, start, count); 572} 573 574 575/** 576 * Called from glDrawArraysInstancedBaseInstance when in immediate mode. 577 */ 578static void GLAPIENTRY 579_mesa_exec_DrawArraysInstancedBaseInstance(GLenum mode, GLint first, 580 GLsizei count, GLsizei numInstances, 581 GLuint baseInstance) 582{ 583 GET_CURRENT_CONTEXT(ctx); 584 585 if (MESA_VERBOSE & VERBOSE_DRAW) 586 _mesa_debug(ctx, 587 "glDrawArraysInstancedBaseInstance(%s, %d, %d, %d, %d)\n", 588 _mesa_enum_to_string(mode), first, count, 589 numInstances, baseInstance); 590 591 FLUSH_FOR_DRAW(ctx); 592 593 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 594 595 if (_mesa_is_no_error_enabled(ctx)) { 596 if (ctx->NewState) 597 _mesa_update_state(ctx); 598 } else { 599 if (!_mesa_validate_DrawArraysInstanced(ctx, mode, first, count, 600 numInstances)) 601 return; 602 } 603 604 if (0) 605 check_draw_arrays_data(ctx, first, count); 606 607 _mesa_draw_arrays(ctx, mode, first, count, numInstances, baseInstance, 0); 608 609 if (0) 610 print_draw_arrays(ctx, mode, first, count); 611} 612 613 614/** 615 * Called from glMultiDrawArrays when in immediate mode. 616 */ 617static void GLAPIENTRY 618_mesa_exec_MultiDrawArrays(GLenum mode, const GLint *first, 619 const GLsizei *count, GLsizei primcount) 620{ 621 GET_CURRENT_CONTEXT(ctx); 622 GLint i; 623 624 if (MESA_VERBOSE & VERBOSE_DRAW) 625 _mesa_debug(ctx, 626 "glMultiDrawArrays(%s, %p, %p, %d)\n", 627 _mesa_enum_to_string(mode), first, count, primcount); 628 629 FLUSH_FOR_DRAW(ctx); 630 631 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 632 633 if (_mesa_is_no_error_enabled(ctx)) { 634 if (ctx->NewState) 635 _mesa_update_state(ctx); 636 } else { 637 if (!_mesa_validate_MultiDrawArrays(ctx, mode, count, primcount)) 638 return; 639 } 640 641 for (i = 0; i < primcount; i++) { 642 if (count[i] > 0) { 643 if (0) 644 check_draw_arrays_data(ctx, first[i], count[i]); 645 646 /* The GL_ARB_shader_draw_parameters spec adds the following after the 647 * pseudo-code describing glMultiDrawArrays: 648 * 649 * "The index of the draw (<i> in the above pseudo-code) may be 650 * read by a vertex shader as <gl_DrawIDARB>, as described in 651 * Section 11.1.3.9." 652 */ 653 _mesa_draw_arrays(ctx, mode, first[i], count[i], 1, 0, i); 654 655 if (0) 656 print_draw_arrays(ctx, mode, first[i], count[i]); 657 } 658 } 659} 660 661 662 663/** 664 * Map GL_ELEMENT_ARRAY_BUFFER and print contents. 665 * For debugging. 666 */ 667#if 0 668static void 669dump_element_buffer(struct gl_context *ctx, GLenum type) 670{ 671 const GLvoid *map = 672 ctx->Driver.MapBufferRange(ctx, 0, 673 ctx->Array.VAO->IndexBufferObj->Size, 674 GL_MAP_READ_BIT, 675 ctx->Array.VAO->IndexBufferObj, 676 MAP_INTERNAL); 677 switch (type) { 678 case GL_UNSIGNED_BYTE: 679 { 680 const GLubyte *us = (const GLubyte *) map; 681 GLint i; 682 for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size; i++) { 683 printf("%02x ", us[i]); 684 if (i % 32 == 31) 685 printf("\n"); 686 } 687 printf("\n"); 688 } 689 break; 690 case GL_UNSIGNED_SHORT: 691 { 692 const GLushort *us = (const GLushort *) map; 693 GLint i; 694 for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size / 2; i++) { 695 printf("%04x ", us[i]); 696 if (i % 16 == 15) 697 printf("\n"); 698 } 699 printf("\n"); 700 } 701 break; 702 case GL_UNSIGNED_INT: 703 { 704 const GLuint *us = (const GLuint *) map; 705 GLint i; 706 for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size / 4; i++) { 707 printf("%08x ", us[i]); 708 if (i % 8 == 7) 709 printf("\n"); 710 } 711 printf("\n"); 712 } 713 break; 714 default: 715 ; 716 } 717 718 ctx->Driver.UnmapBuffer(ctx, ctx->Array.VAO->IndexBufferObj, MAP_INTERNAL); 719} 720#endif 721 722 723static bool 724skip_draw_elements(struct gl_context *ctx, GLsizei count, 725 const GLvoid *indices) 726{ 727 if (count == 0) 728 return true; 729 730 /* Not using a VBO for indices, so avoid NULL pointer derefs later. 731 */ 732 if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj) && indices == NULL) 733 return true; 734 735 if (skip_validated_draw(ctx)) 736 return true; 737 738 return false; 739} 740 741 742/** 743 * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements. 744 * Do the rendering for a glDrawElements or glDrawRangeElements call after 745 * we've validated buffer bounds, etc. 746 */ 747static void 748_mesa_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, 749 GLboolean index_bounds_valid, 750 GLuint start, GLuint end, 751 GLsizei count, GLenum type, 752 const GLvoid * indices, 753 GLint basevertex, GLuint numInstances, 754 GLuint baseInstance) 755{ 756 struct _mesa_index_buffer ib; 757 struct _mesa_prim prim; 758 759 if (!index_bounds_valid) { 760 assert(start == 0u); 761 assert(end == ~0u); 762 } 763 764 if (skip_draw_elements(ctx, count, indices)) 765 return; 766 767 ib.count = count; 768 ib.index_size = sizeof_ib_type(type); 769 ib.obj = ctx->Array.VAO->IndexBufferObj; 770 ib.ptr = indices; 771 772 prim.begin = 1; 773 prim.end = 1; 774 prim.pad = 0; 775 prim.mode = mode; 776 prim.start = 0; 777 prim.count = count; 778 prim.indexed = 1; 779 prim.is_indirect = 0; 780 prim.basevertex = basevertex; 781 prim.num_instances = numInstances; 782 prim.base_instance = baseInstance; 783 prim.draw_id = 0; 784 785 /* Need to give special consideration to rendering a range of 786 * indices starting somewhere above zero. Typically the 787 * application is issuing multiple DrawRangeElements() to draw 788 * successive primitives layed out linearly in the vertex arrays. 789 * Unless the vertex arrays are all in a VBO (or locked as with 790 * CVA), the OpenGL semantics imply that we need to re-read or 791 * re-upload the vertex data on each draw call. 792 * 793 * In the case of hardware tnl, we want to avoid starting the 794 * upload at zero, as it will mean every draw call uploads an 795 * increasing amount of not-used vertex data. Worse - in the 796 * software tnl module, all those vertices might be transformed and 797 * lit but never rendered. 798 * 799 * If we just upload or transform the vertices in start..end, 800 * however, the indices will be incorrect. 801 * 802 * At this level, we don't know exactly what the requirements of 803 * the backend are going to be, though it will likely boil down to 804 * either: 805 * 806 * 1) Do nothing, everything is in a VBO and is processed once 807 * only. 808 * 809 * 2) Adjust the indices and vertex arrays so that start becomes 810 * zero. 811 * 812 * Rather than doing anything here, I'll provide a helper function 813 * for the latter case elsewhere. 814 */ 815 816 ctx->Driver.Draw(ctx, &prim, 1, &ib, 817 index_bounds_valid, start, end, NULL, 0, NULL); 818 819 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 820 _mesa_flush(ctx); 821 } 822} 823 824 825/** 826 * Called by glDrawRangeElementsBaseVertex() in immediate mode. 827 */ 828void GLAPIENTRY 829_mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, 830 GLsizei count, GLenum type, 831 const GLvoid * indices, GLint basevertex) 832{ 833 static GLuint warnCount = 0; 834 GLboolean index_bounds_valid = GL_TRUE; 835 836 /* This is only useful to catch invalid values in the "end" parameter 837 * like ~0. 838 */ 839 GLuint max_element = 2 * 1000 * 1000 * 1000; /* just a big number */ 840 841 GET_CURRENT_CONTEXT(ctx); 842 843 if (MESA_VERBOSE & VERBOSE_DRAW) 844 _mesa_debug(ctx, 845 "glDrawRangeElementsBaseVertex(%s, %u, %u, %d, %s, %p, %d)\n", 846 _mesa_enum_to_string(mode), start, end, count, 847 _mesa_enum_to_string(type), indices, basevertex); 848 849 FLUSH_FOR_DRAW(ctx); 850 851 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 852 853 if (_mesa_is_no_error_enabled(ctx)) { 854 if (ctx->NewState) 855 _mesa_update_state(ctx); 856 } else { 857 if (!_mesa_validate_DrawRangeElements(ctx, mode, start, end, count, 858 type, indices)) 859 return; 860 } 861 862 if ((int) end + basevertex < 0 || start + basevertex >= max_element) { 863 /* The application requested we draw using a range of indices that's 864 * outside the bounds of the current VBO. This is invalid and appears 865 * to give undefined results. The safest thing to do is to simply 866 * ignore the range, in case the application botched their range tracking 867 * but did provide valid indices. Also issue a warning indicating that 868 * the application is broken. 869 */ 870 if (warnCount++ < 10) { 871 _mesa_warning(ctx, "glDrawRangeElements(start %u, end %u, " 872 "basevertex %d, count %d, type 0x%x, indices=%p):\n" 873 "\trange is outside VBO bounds (max=%u); ignoring.\n" 874 "\tThis should be fixed in the application.", 875 start, end, basevertex, count, type, indices, 876 max_element - 1); 877 } 878 index_bounds_valid = GL_FALSE; 879 } 880 881 /* NOTE: It's important that 'end' is a reasonable value. 882 * in _tnl_draw_prims(), we use end to determine how many vertices 883 * to transform. If it's too large, we can unnecessarily split prims 884 * or we can read/write out of memory in several different places! 885 */ 886 887 /* Catch/fix some potential user errors */ 888 if (type == GL_UNSIGNED_BYTE) { 889 start = MIN2(start, 0xff); 890 end = MIN2(end, 0xff); 891 } 892 else if (type == GL_UNSIGNED_SHORT) { 893 start = MIN2(start, 0xffff); 894 end = MIN2(end, 0xffff); 895 } 896 897 if (0) { 898 printf("glDraw[Range]Elements{,BaseVertex}" 899 "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, " 900 "base %d\n", 901 start, end, type, count, 902 ctx->Array.VAO->IndexBufferObj->Name, basevertex); 903 } 904 905 if ((int) start + basevertex < 0 || end + basevertex >= max_element) 906 index_bounds_valid = GL_FALSE; 907 908#if 0 909 check_draw_elements_data(ctx, count, type, indices, basevertex); 910#else 911 (void) check_draw_elements_data; 912#endif 913 914 if (!index_bounds_valid) { 915 start = 0; 916 end = ~0; 917 } 918 919 _mesa_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end, 920 count, type, indices, basevertex, 1, 0); 921} 922 923 924/** 925 * Called by glDrawRangeElements() in immediate mode. 926 */ 927void GLAPIENTRY 928_mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, 929 GLsizei count, GLenum type, const GLvoid * indices) 930{ 931 if (MESA_VERBOSE & VERBOSE_DRAW) { 932 GET_CURRENT_CONTEXT(ctx); 933 _mesa_debug(ctx, 934 "glDrawRangeElements(%s, %u, %u, %d, %s, %p)\n", 935 _mesa_enum_to_string(mode), start, end, count, 936 _mesa_enum_to_string(type), indices); 937 } 938 939 _mesa_DrawRangeElementsBaseVertex(mode, start, end, count, type, 940 indices, 0); 941} 942 943 944/** 945 * Called by glDrawElements() in immediate mode. 946 */ 947void GLAPIENTRY 948_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, 949 const GLvoid * indices) 950{ 951 GET_CURRENT_CONTEXT(ctx); 952 953 if (MESA_VERBOSE & VERBOSE_DRAW) 954 _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n", 955 _mesa_enum_to_string(mode), count, 956 _mesa_enum_to_string(type), indices); 957 958 FLUSH_FOR_DRAW(ctx); 959 960 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 961 962 if (_mesa_is_no_error_enabled(ctx)) { 963 if (ctx->NewState) 964 _mesa_update_state(ctx); 965 } else { 966 if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices)) 967 return; 968 } 969 970 _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0, 971 count, type, indices, 0, 1, 0); 972} 973 974 975/** 976 * Called by glDrawElementsBaseVertex() in immediate mode. 977 */ 978void GLAPIENTRY 979_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, 980 const GLvoid * indices, GLint basevertex) 981{ 982 GET_CURRENT_CONTEXT(ctx); 983 984 if (MESA_VERBOSE & VERBOSE_DRAW) 985 _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n", 986 _mesa_enum_to_string(mode), count, 987 _mesa_enum_to_string(type), indices); 988 989 FLUSH_FOR_DRAW(ctx); 990 991 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 992 993 if (_mesa_is_no_error_enabled(ctx)) { 994 if (ctx->NewState) 995 _mesa_update_state(ctx); 996 } else { 997 if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices)) 998 return; 999 } 1000 1001 _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0, 1002 count, type, indices, basevertex, 1, 0); 1003} 1004 1005 1006/** 1007 * Called by glDrawElementsInstanced() in immediate mode. 1008 */ 1009static void GLAPIENTRY 1010_mesa_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, 1011 const GLvoid * indices, GLsizei numInstances) 1012{ 1013 GET_CURRENT_CONTEXT(ctx); 1014 1015 if (MESA_VERBOSE & VERBOSE_DRAW) 1016 _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n", 1017 _mesa_enum_to_string(mode), count, 1018 _mesa_enum_to_string(type), indices); 1019 1020 FLUSH_FOR_DRAW(ctx); 1021 1022 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 1023 1024 if (_mesa_is_no_error_enabled(ctx)) { 1025 if (ctx->NewState) 1026 _mesa_update_state(ctx); 1027 } else { 1028 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, 1029 indices, numInstances)) 1030 return; 1031 } 1032 1033 _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0, 1034 count, type, indices, 0, numInstances, 0); 1035} 1036 1037 1038/** 1039 * Called by glDrawElementsInstancedBaseVertex() in immediate mode. 1040 */ 1041static void GLAPIENTRY 1042_mesa_exec_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, 1043 GLenum type, const GLvoid * indices, 1044 GLsizei numInstances, 1045 GLint basevertex) 1046{ 1047 GET_CURRENT_CONTEXT(ctx); 1048 1049 if (MESA_VERBOSE & VERBOSE_DRAW) 1050 _mesa_debug(ctx, 1051 "glDrawElementsInstancedBaseVertex" 1052 "(%s, %d, %s, %p, %d; %d)\n", 1053 _mesa_enum_to_string(mode), count, 1054 _mesa_enum_to_string(type), indices, 1055 numInstances, basevertex); 1056 1057 FLUSH_FOR_DRAW(ctx); 1058 1059 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 1060 1061 if (_mesa_is_no_error_enabled(ctx)) { 1062 if (ctx->NewState) 1063 _mesa_update_state(ctx); 1064 } else { 1065 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, 1066 indices, numInstances)) 1067 return; 1068 } 1069 1070 _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0, 1071 count, type, indices, 1072 basevertex, numInstances, 0); 1073} 1074 1075 1076/** 1077 * Called by glDrawElementsInstancedBaseInstance() in immediate mode. 1078 */ 1079static void GLAPIENTRY 1080_mesa_exec_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, 1081 GLenum type, 1082 const GLvoid *indices, 1083 GLsizei numInstances, 1084 GLuint baseInstance) 1085{ 1086 GET_CURRENT_CONTEXT(ctx); 1087 1088 if (MESA_VERBOSE & VERBOSE_DRAW) 1089 _mesa_debug(ctx, 1090 "glDrawElementsInstancedBaseInstance" 1091 "(%s, %d, %s, %p, %d, %d)\n", 1092 _mesa_enum_to_string(mode), count, 1093 _mesa_enum_to_string(type), indices, 1094 numInstances, baseInstance); 1095 1096 FLUSH_FOR_DRAW(ctx); 1097 1098 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 1099 1100 if (_mesa_is_no_error_enabled(ctx)) { 1101 if (ctx->NewState) 1102 _mesa_update_state(ctx); 1103 } else { 1104 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, 1105 indices, numInstances)) 1106 return; 1107 } 1108 1109 _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0, 1110 count, type, indices, 0, numInstances, 1111 baseInstance); 1112} 1113 1114 1115/** 1116 * Called by glDrawElementsInstancedBaseVertexBaseInstance() in immediate mode. 1117 */ 1118static void GLAPIENTRY 1119_mesa_exec_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, 1120 GLsizei count, 1121 GLenum type, 1122 const GLvoid *indices, 1123 GLsizei numInstances, 1124 GLint basevertex, 1125 GLuint baseInstance) 1126{ 1127 GET_CURRENT_CONTEXT(ctx); 1128 1129 if (MESA_VERBOSE & VERBOSE_DRAW) 1130 _mesa_debug(ctx, 1131 "glDrawElementsInstancedBaseVertexBaseInstance" 1132 "(%s, %d, %s, %p, %d, %d, %d)\n", 1133 _mesa_enum_to_string(mode), count, 1134 _mesa_enum_to_string(type), indices, 1135 numInstances, basevertex, baseInstance); 1136 1137 FLUSH_FOR_DRAW(ctx); 1138 1139 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 1140 1141 if (_mesa_is_no_error_enabled(ctx)) { 1142 if (ctx->NewState) 1143 _mesa_update_state(ctx); 1144 } else { 1145 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, 1146 indices, numInstances)) 1147 return; 1148 } 1149 1150 _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0, 1151 count, type, indices, basevertex, 1152 numInstances, baseInstance); 1153} 1154 1155 1156/** 1157 * Inner support for both _mesa_MultiDrawElements() and 1158 * _mesa_MultiDrawRangeElements(). 1159 * This does the actual rendering after we've checked array indexes, etc. 1160 */ 1161static void 1162_mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, 1163 const GLsizei *count, GLenum type, 1164 const GLvoid * const *indices, 1165 GLsizei primcount, const GLint *basevertex) 1166{ 1167 struct _mesa_index_buffer ib; 1168 struct _mesa_prim *prim; 1169 unsigned int index_type_size = sizeof_ib_type(type); 1170 uintptr_t min_index_ptr, max_index_ptr; 1171 GLboolean fallback = GL_FALSE; 1172 int i; 1173 1174 if (primcount == 0) 1175 return; 1176 1177 prim = calloc(primcount, sizeof(*prim)); 1178 if (prim == NULL) { 1179 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements"); 1180 return; 1181 } 1182 1183 min_index_ptr = (uintptr_t) indices[0]; 1184 max_index_ptr = 0; 1185 for (i = 0; i < primcount; i++) { 1186 min_index_ptr = MIN2(min_index_ptr, (uintptr_t) indices[i]); 1187 max_index_ptr = MAX2(max_index_ptr, (uintptr_t) indices[i] + 1188 index_type_size * count[i]); 1189 } 1190 1191 /* Check if we can handle this thing as a bunch of index offsets from the 1192 * same index pointer. If we can't, then we have to fall back to doing 1193 * a draw_prims per primitive. 1194 * Check that the difference between each prim's indexes is a multiple of 1195 * the index/element size. 1196 */ 1197 if (index_type_size != 1) { 1198 for (i = 0; i < primcount; i++) { 1199 if ((((uintptr_t) indices[i] - min_index_ptr) % index_type_size) != 1200 0) { 1201 fallback = GL_TRUE; 1202 break; 1203 } 1204 } 1205 } 1206 1207 /* Draw primitives individually if one count is zero, so we can easily skip 1208 * that primitive. 1209 */ 1210 for (i = 0; i < primcount; i++) { 1211 if (count[i] == 0) { 1212 fallback = GL_TRUE; 1213 break; 1214 } 1215 } 1216 1217 /* If the index buffer isn't in a VBO, then treating the application's 1218 * subranges of the index buffer as one large index buffer may lead to 1219 * us reading unmapped memory. 1220 */ 1221 if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) 1222 fallback = GL_TRUE; 1223 1224 if (!fallback) { 1225 ib.count = (max_index_ptr - min_index_ptr) / index_type_size; 1226 ib.index_size = sizeof_ib_type(type); 1227 ib.obj = ctx->Array.VAO->IndexBufferObj; 1228 ib.ptr = (void *) min_index_ptr; 1229 1230 for (i = 0; i < primcount; i++) { 1231 prim[i].begin = (i == 0); 1232 prim[i].end = (i == primcount - 1); 1233 prim[i].pad = 0; 1234 prim[i].mode = mode; 1235 prim[i].start = 1236 ((uintptr_t) indices[i] - min_index_ptr) / index_type_size; 1237 prim[i].count = count[i]; 1238 prim[i].indexed = 1; 1239 prim[i].num_instances = 1; 1240 prim[i].base_instance = 0; 1241 prim[i].draw_id = i; 1242 prim[i].is_indirect = 0; 1243 if (basevertex != NULL) 1244 prim[i].basevertex = basevertex[i]; 1245 else 1246 prim[i].basevertex = 0; 1247 } 1248 1249 ctx->Driver.Draw(ctx, prim, primcount, &ib, 1250 false, 0, ~0, NULL, 0, NULL); 1251 } 1252 else { 1253 /* render one prim at a time */ 1254 for (i = 0; i < primcount; i++) { 1255 if (count[i] == 0) 1256 continue; 1257 ib.count = count[i]; 1258 ib.index_size = sizeof_ib_type(type); 1259 ib.obj = ctx->Array.VAO->IndexBufferObj; 1260 ib.ptr = indices[i]; 1261 1262 prim[0].begin = 1; 1263 prim[0].end = 1; 1264 prim[0].pad = 0; 1265 prim[0].mode = mode; 1266 prim[0].start = 0; 1267 prim[0].count = count[i]; 1268 prim[0].indexed = 1; 1269 prim[0].num_instances = 1; 1270 prim[0].base_instance = 0; 1271 prim[0].draw_id = i; 1272 prim[0].is_indirect = 0; 1273 if (basevertex != NULL) 1274 prim[0].basevertex = basevertex[i]; 1275 else 1276 prim[0].basevertex = 0; 1277 1278 ctx->Driver.Draw(ctx, prim, 1, &ib, false, 0, ~0, NULL, 0, NULL); 1279 } 1280 } 1281 1282 free(prim); 1283 1284 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 1285 _mesa_flush(ctx); 1286 } 1287} 1288 1289 1290void GLAPIENTRY 1291_mesa_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, 1292 const GLvoid * const *indices, GLsizei primcount) 1293{ 1294 GET_CURRENT_CONTEXT(ctx); 1295 1296 FLUSH_FOR_DRAW(ctx); 1297 1298 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 1299 1300 if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices, 1301 primcount)) 1302 return; 1303 1304 if (skip_validated_draw(ctx)) 1305 return; 1306 1307 _mesa_validated_multidrawelements(ctx, mode, count, type, indices, primcount, 1308 NULL); 1309} 1310 1311 1312void GLAPIENTRY 1313_mesa_MultiDrawElementsBaseVertex(GLenum mode, 1314 const GLsizei *count, GLenum type, 1315 const GLvoid * const *indices, 1316 GLsizei primcount, 1317 const GLsizei *basevertex) 1318{ 1319 GET_CURRENT_CONTEXT(ctx); 1320 1321 FLUSH_FOR_DRAW(ctx); 1322 1323 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 1324 1325 if (_mesa_is_no_error_enabled(ctx)) { 1326 if (ctx->NewState) 1327 _mesa_update_state(ctx); 1328 } else { 1329 if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices, 1330 primcount)) 1331 return; 1332 } 1333 1334 if (skip_validated_draw(ctx)) 1335 return; 1336 1337 _mesa_validated_multidrawelements(ctx, mode, count, type, indices, primcount, 1338 basevertex); 1339} 1340 1341 1342/** 1343 * Draw a GL primitive using a vertex count obtained from transform feedback. 1344 * \param mode the type of GL primitive to draw 1345 * \param obj the transform feedback object to use 1346 * \param stream index of the transform feedback stream from which to 1347 * get the primitive count. 1348 * \param numInstances number of instances to draw 1349 */ 1350static void 1351_mesa_draw_transform_feedback(struct gl_context *ctx, GLenum mode, 1352 struct gl_transform_feedback_object *obj, 1353 GLuint stream, GLuint numInstances) 1354{ 1355 struct _mesa_prim prim; 1356 1357 FLUSH_FOR_DRAW(ctx); 1358 1359 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 1360 1361 if (_mesa_is_no_error_enabled(ctx)) { 1362 if (ctx->NewState) 1363 _mesa_update_state(ctx); 1364 } else { 1365 if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream, 1366 numInstances)) { 1367 return; 1368 } 1369 } 1370 1371 if (ctx->Driver.GetTransformFeedbackVertexCount && 1372 (ctx->Const.AlwaysUseGetTransformFeedbackVertexCount || 1373 !_mesa_all_varyings_in_vbos(ctx->Array.VAO))) { 1374 GLsizei n = 1375 ctx->Driver.GetTransformFeedbackVertexCount(ctx, obj, stream); 1376 _mesa_draw_arrays(ctx, mode, 0, n, numInstances, 0, 0); 1377 return; 1378 } 1379 1380 if (skip_validated_draw(ctx)) 1381 return; 1382 1383 /* init most fields to zero */ 1384 memset(&prim, 0, sizeof(prim)); 1385 prim.begin = 1; 1386 prim.end = 1; 1387 prim.mode = mode; 1388 prim.num_instances = numInstances; 1389 prim.base_instance = 0; 1390 prim.is_indirect = 0; 1391 1392 /* Maybe we should do some primitive splitting for primitive restart 1393 * (like in DrawArrays), but we have no way to know how many vertices 1394 * will be rendered. */ 1395 1396 ctx->Driver.Draw(ctx, &prim, 1, NULL, GL_FALSE, 0, ~0, obj, stream, NULL); 1397 1398 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 1399 _mesa_flush(ctx); 1400 } 1401} 1402 1403 1404/** 1405 * Like DrawArrays, but take the count from a transform feedback object. 1406 * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc. 1407 * \param name the transform feedback object 1408 * User still has to setup of the vertex attribute info with 1409 * glVertexPointer, glColorPointer, etc. 1410 * Part of GL_ARB_transform_feedback2. 1411 */ 1412void GLAPIENTRY 1413_mesa_DrawTransformFeedback(GLenum mode, GLuint name) 1414{ 1415 GET_CURRENT_CONTEXT(ctx); 1416 struct gl_transform_feedback_object *obj = 1417 _mesa_lookup_transform_feedback_object(ctx, name); 1418 1419 if (MESA_VERBOSE & VERBOSE_DRAW) 1420 _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n", 1421 _mesa_enum_to_string(mode), name); 1422 1423 _mesa_draw_transform_feedback(ctx, mode, obj, 0, 1); 1424} 1425 1426 1427static void GLAPIENTRY 1428_mesa_exec_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream) 1429{ 1430 GET_CURRENT_CONTEXT(ctx); 1431 struct gl_transform_feedback_object *obj = 1432 _mesa_lookup_transform_feedback_object(ctx, name); 1433 1434 if (MESA_VERBOSE & VERBOSE_DRAW) 1435 _mesa_debug(ctx, "glDrawTransformFeedbackStream(%s, %u, %u)\n", 1436 _mesa_enum_to_string(mode), name, stream); 1437 1438 _mesa_draw_transform_feedback(ctx, mode, obj, stream, 1); 1439} 1440 1441 1442static void GLAPIENTRY 1443_mesa_exec_DrawTransformFeedbackInstanced(GLenum mode, GLuint name, 1444 GLsizei primcount) 1445{ 1446 GET_CURRENT_CONTEXT(ctx); 1447 struct gl_transform_feedback_object *obj = 1448 _mesa_lookup_transform_feedback_object(ctx, name); 1449 1450 if (MESA_VERBOSE & VERBOSE_DRAW) 1451 _mesa_debug(ctx, "glDrawTransformFeedbackInstanced(%s, %d)\n", 1452 _mesa_enum_to_string(mode), name); 1453 1454 _mesa_draw_transform_feedback(ctx, mode, obj, 0, primcount); 1455} 1456 1457 1458static void GLAPIENTRY 1459_mesa_exec_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name, 1460 GLuint stream, 1461 GLsizei primcount) 1462{ 1463 GET_CURRENT_CONTEXT(ctx); 1464 struct gl_transform_feedback_object *obj = 1465 _mesa_lookup_transform_feedback_object(ctx, name); 1466 1467 if (MESA_VERBOSE & VERBOSE_DRAW) 1468 _mesa_debug(ctx, "glDrawTransformFeedbackStreamInstanced" 1469 "(%s, %u, %u, %i)\n", 1470 _mesa_enum_to_string(mode), name, stream, primcount); 1471 1472 _mesa_draw_transform_feedback(ctx, mode, obj, stream, primcount); 1473} 1474 1475 1476static void 1477_mesa_validated_drawarraysindirect(struct gl_context *ctx, 1478 GLenum mode, const GLvoid *indirect) 1479{ 1480 ctx->Driver.DrawIndirect(ctx, mode, 1481 ctx->DrawIndirectBuffer, (GLsizeiptr) indirect, 1482 1 /* draw_count */ , 16 /* stride */ , 1483 NULL, 0, NULL); 1484 1485 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) 1486 _mesa_flush(ctx); 1487} 1488 1489 1490static void 1491_mesa_validated_multidrawarraysindirect(struct gl_context *ctx, 1492 GLenum mode, 1493 const GLvoid *indirect, 1494 GLsizei primcount, GLsizei stride) 1495{ 1496 GLsizeiptr offset = (GLsizeiptr) indirect; 1497 1498 if (primcount == 0) 1499 return; 1500 1501 ctx->Driver.DrawIndirect(ctx, mode, ctx->DrawIndirectBuffer, offset, 1502 primcount, stride, NULL, 0, NULL); 1503 1504 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) 1505 _mesa_flush(ctx); 1506} 1507 1508 1509static void 1510_mesa_validated_drawelementsindirect(struct gl_context *ctx, 1511 GLenum mode, GLenum type, 1512 const GLvoid *indirect) 1513{ 1514 struct _mesa_index_buffer ib; 1515 1516 ib.count = 0; /* unknown */ 1517 ib.index_size = sizeof_ib_type(type); 1518 ib.obj = ctx->Array.VAO->IndexBufferObj; 1519 ib.ptr = NULL; 1520 1521 ctx->Driver.DrawIndirect(ctx, mode, 1522 ctx->DrawIndirectBuffer, (GLsizeiptr) indirect, 1523 1 /* draw_count */ , 20 /* stride */ , 1524 NULL, 0, &ib); 1525 1526 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) 1527 _mesa_flush(ctx); 1528} 1529 1530 1531static void 1532_mesa_validated_multidrawelementsindirect(struct gl_context *ctx, 1533 GLenum mode, GLenum type, 1534 const GLvoid *indirect, 1535 GLsizei primcount, GLsizei stride) 1536{ 1537 struct _mesa_index_buffer ib; 1538 GLsizeiptr offset = (GLsizeiptr) indirect; 1539 1540 if (primcount == 0) 1541 return; 1542 1543 /* NOTE: IndexBufferObj is guaranteed to be a VBO. */ 1544 1545 ib.count = 0; /* unknown */ 1546 ib.index_size = sizeof_ib_type(type); 1547 ib.obj = ctx->Array.VAO->IndexBufferObj; 1548 ib.ptr = NULL; 1549 1550 ctx->Driver.DrawIndirect(ctx, mode, 1551 ctx->DrawIndirectBuffer, offset, 1552 primcount, stride, NULL, 0, &ib); 1553 1554 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) 1555 _mesa_flush(ctx); 1556} 1557 1558 1559/** 1560 * Like [Multi]DrawArrays/Elements, but they take most arguments from 1561 * a buffer object. 1562 */ 1563static void GLAPIENTRY 1564_mesa_exec_DrawArraysIndirect(GLenum mode, const GLvoid *indirect) 1565{ 1566 GET_CURRENT_CONTEXT(ctx); 1567 1568 if (MESA_VERBOSE & VERBOSE_DRAW) 1569 _mesa_debug(ctx, "glDrawArraysIndirect(%s, %p)\n", 1570 _mesa_enum_to_string(mode), indirect); 1571 1572 /* From the ARB_draw_indirect spec: 1573 * 1574 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the 1575 * compatibility profile, this indicates that DrawArraysIndirect and 1576 * DrawElementsIndirect are to source their arguments directly from the 1577 * pointer passed as their <indirect> parameters." 1578 */ 1579 if (ctx->API == API_OPENGL_COMPAT && 1580 !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) { 1581 DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) indirect; 1582 1583 _mesa_exec_DrawArraysInstancedBaseInstance(mode, cmd->first, cmd->count, 1584 cmd->primCount, 1585 cmd->baseInstance); 1586 return; 1587 } 1588 1589 FLUSH_FOR_DRAW(ctx); 1590 1591 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 1592 1593 if (_mesa_is_no_error_enabled(ctx)) { 1594 if (ctx->NewState) 1595 _mesa_update_state(ctx); 1596 } else { 1597 if (!_mesa_validate_DrawArraysIndirect(ctx, mode, indirect)) 1598 return; 1599 } 1600 1601 if (skip_validated_draw(ctx)) 1602 return; 1603 1604 _mesa_validated_drawarraysindirect(ctx, mode, indirect); 1605} 1606 1607 1608static void GLAPIENTRY 1609_mesa_exec_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect) 1610{ 1611 GET_CURRENT_CONTEXT(ctx); 1612 1613 if (MESA_VERBOSE & VERBOSE_DRAW) 1614 _mesa_debug(ctx, "glDrawElementsIndirect(%s, %s, %p)\n", 1615 _mesa_enum_to_string(mode), 1616 _mesa_enum_to_string(type), indirect); 1617 1618 /* From the ARB_draw_indirect spec: 1619 * 1620 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the 1621 * compatibility profile, this indicates that DrawArraysIndirect and 1622 * DrawElementsIndirect are to source their arguments directly from the 1623 * pointer passed as their <indirect> parameters." 1624 */ 1625 if (ctx->API == API_OPENGL_COMPAT && 1626 !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) { 1627 /* 1628 * Unlike regular DrawElementsInstancedBaseVertex commands, the indices 1629 * may not come from a client array and must come from an index buffer. 1630 * If no element array buffer is bound, an INVALID_OPERATION error is 1631 * generated. 1632 */ 1633 if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) { 1634 _mesa_error(ctx, GL_INVALID_OPERATION, 1635 "glDrawElementsIndirect(no buffer bound " 1636 "to GL_ELEMENT_ARRAY_BUFFER)"); 1637 } else { 1638 DrawElementsIndirectCommand *cmd = 1639 (DrawElementsIndirectCommand *) indirect; 1640 1641 /* Convert offset to pointer */ 1642 void *offset = (void *) 1643 ((cmd->firstIndex * _mesa_sizeof_type(type)) & 0xffffffffUL); 1644 1645 _mesa_exec_DrawElementsInstancedBaseVertexBaseInstance(mode, cmd->count, 1646 type, offset, 1647 cmd->primCount, 1648 cmd->baseVertex, 1649 cmd->baseInstance); 1650 } 1651 1652 return; 1653 } 1654 1655 FLUSH_FOR_DRAW(ctx); 1656 1657 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 1658 1659 if (_mesa_is_no_error_enabled(ctx)) { 1660 if (ctx->NewState) 1661 _mesa_update_state(ctx); 1662 } else { 1663 if (!_mesa_validate_DrawElementsIndirect(ctx, mode, type, indirect)) 1664 return; 1665 } 1666 1667 if (skip_validated_draw(ctx)) 1668 return; 1669 1670 _mesa_validated_drawelementsindirect(ctx, mode, type, indirect); 1671} 1672 1673 1674static void GLAPIENTRY 1675_mesa_exec_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect, 1676 GLsizei primcount, GLsizei stride) 1677{ 1678 GET_CURRENT_CONTEXT(ctx); 1679 1680 if (MESA_VERBOSE & VERBOSE_DRAW) 1681 _mesa_debug(ctx, "glMultiDrawArraysIndirect(%s, %p, %i, %i)\n", 1682 _mesa_enum_to_string(mode), indirect, primcount, stride); 1683 1684 /* If <stride> is zero, the array elements are treated as tightly packed. */ 1685 if (stride == 0) 1686 stride = sizeof(DrawArraysIndirectCommand); 1687 1688 /* From the ARB_draw_indirect spec: 1689 * 1690 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the 1691 * compatibility profile, this indicates that DrawArraysIndirect and 1692 * DrawElementsIndirect are to source their arguments directly from the 1693 * pointer passed as their <indirect> parameters." 1694 */ 1695 if (ctx->API == API_OPENGL_COMPAT && 1696 !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) { 1697 1698 if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride, 1699 "glMultiDrawArraysIndirect")) 1700 return; 1701 1702 const ubyte *ptr = (const ubyte *) indirect; 1703 for (unsigned i = 0; i < primcount; i++) { 1704 DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) ptr; 1705 _mesa_exec_DrawArraysInstancedBaseInstance(mode, cmd->first, 1706 cmd->count, cmd->primCount, 1707 cmd->baseInstance); 1708 1709 if (stride == 0) { 1710 ptr += sizeof(DrawArraysIndirectCommand); 1711 } else { 1712 ptr += stride; 1713 } 1714 } 1715 1716 return; 1717 } 1718 1719 FLUSH_FOR_DRAW(ctx); 1720 1721 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 1722 1723 if (_mesa_is_no_error_enabled(ctx)) { 1724 if (ctx->NewState) 1725 _mesa_update_state(ctx); 1726 } else { 1727 if (!_mesa_validate_MultiDrawArraysIndirect(ctx, mode, indirect, 1728 primcount, stride)) 1729 return; 1730 } 1731 1732 if (skip_validated_draw(ctx)) 1733 return; 1734 1735 _mesa_validated_multidrawarraysindirect(ctx, mode, indirect, 1736 primcount, stride); 1737} 1738 1739 1740static void GLAPIENTRY 1741_mesa_exec_MultiDrawElementsIndirect(GLenum mode, GLenum type, 1742 const GLvoid *indirect, 1743 GLsizei primcount, GLsizei stride) 1744{ 1745 GET_CURRENT_CONTEXT(ctx); 1746 1747 if (MESA_VERBOSE & VERBOSE_DRAW) 1748 _mesa_debug(ctx, "glMultiDrawElementsIndirect(%s, %s, %p, %i, %i)\n", 1749 _mesa_enum_to_string(mode), 1750 _mesa_enum_to_string(type), indirect, primcount, stride); 1751 1752 /* If <stride> is zero, the array elements are treated as tightly packed. */ 1753 if (stride == 0) 1754 stride = sizeof(DrawElementsIndirectCommand); 1755 1756 1757 /* From the ARB_draw_indirect spec: 1758 * 1759 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the 1760 * compatibility profile, this indicates that DrawArraysIndirect and 1761 * DrawElementsIndirect are to source their arguments directly from the 1762 * pointer passed as their <indirect> parameters." 1763 */ 1764 if (ctx->API == API_OPENGL_COMPAT && 1765 !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) { 1766 /* 1767 * Unlike regular DrawElementsInstancedBaseVertex commands, the indices 1768 * may not come from a client array and must come from an index buffer. 1769 * If no element array buffer is bound, an INVALID_OPERATION error is 1770 * generated. 1771 */ 1772 if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) { 1773 _mesa_error(ctx, GL_INVALID_OPERATION, 1774 "glMultiDrawElementsIndirect(no buffer bound " 1775 "to GL_ELEMENT_ARRAY_BUFFER)"); 1776 1777 return; 1778 } 1779 1780 if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride, 1781 "glMultiDrawArraysIndirect")) 1782 return; 1783 1784 const ubyte *ptr = (const ubyte *) indirect; 1785 for (unsigned i = 0; i < primcount; i++) { 1786 _mesa_exec_DrawElementsIndirect(mode, type, ptr); 1787 1788 if (stride == 0) { 1789 ptr += sizeof(DrawElementsIndirectCommand); 1790 } else { 1791 ptr += stride; 1792 } 1793 } 1794 1795 return; 1796 } 1797 1798 FLUSH_FOR_DRAW(ctx); 1799 1800 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 1801 1802 if (_mesa_is_no_error_enabled(ctx)) { 1803 if (ctx->NewState) 1804 _mesa_update_state(ctx); 1805 } else { 1806 if (!_mesa_validate_MultiDrawElementsIndirect(ctx, mode, type, indirect, 1807 primcount, stride)) 1808 return; 1809 } 1810 1811 if (skip_validated_draw(ctx)) 1812 return; 1813 1814 _mesa_validated_multidrawelementsindirect(ctx, mode, type, indirect, 1815 primcount, stride); 1816} 1817 1818 1819static void 1820_mesa_validated_multidrawarraysindirectcount(struct gl_context *ctx, 1821 GLenum mode, 1822 GLintptr indirect, 1823 GLintptr drawcount_offset, 1824 GLsizei maxdrawcount, 1825 GLsizei stride) 1826{ 1827 GLsizeiptr offset = indirect; 1828 1829 if (maxdrawcount == 0) 1830 return; 1831 1832 ctx->Driver.DrawIndirect(ctx, mode, 1833 ctx->DrawIndirectBuffer, offset, 1834 maxdrawcount, stride, 1835 ctx->ParameterBuffer, drawcount_offset, NULL); 1836 1837 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) 1838 _mesa_flush(ctx); 1839} 1840 1841 1842static void 1843_mesa_validated_multidrawelementsindirectcount(struct gl_context *ctx, 1844 GLenum mode, GLenum type, 1845 GLintptr indirect, 1846 GLintptr drawcount_offset, 1847 GLsizei maxdrawcount, 1848 GLsizei stride) 1849{ 1850 struct _mesa_index_buffer ib; 1851 GLsizeiptr offset = (GLsizeiptr) indirect; 1852 1853 if (maxdrawcount == 0) 1854 return; 1855 1856 /* NOTE: IndexBufferObj is guaranteed to be a VBO. */ 1857 1858 ib.count = 0; /* unknown */ 1859 ib.index_size = sizeof_ib_type(type); 1860 ib.obj = ctx->Array.VAO->IndexBufferObj; 1861 ib.ptr = NULL; 1862 1863 ctx->Driver.DrawIndirect(ctx, mode, 1864 ctx->DrawIndirectBuffer, offset, 1865 maxdrawcount, stride, 1866 ctx->ParameterBuffer, drawcount_offset, &ib); 1867 1868 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) 1869 _mesa_flush(ctx); 1870} 1871 1872 1873static void GLAPIENTRY 1874_mesa_exec_MultiDrawArraysIndirectCount(GLenum mode, GLintptr indirect, 1875 GLintptr drawcount_offset, 1876 GLsizei maxdrawcount, GLsizei stride) 1877{ 1878 GET_CURRENT_CONTEXT(ctx); 1879 1880 if (MESA_VERBOSE & VERBOSE_DRAW) 1881 _mesa_debug(ctx, "glMultiDrawArraysIndirectCountARB" 1882 "(%s, %lx, %lx, %i, %i)\n", 1883 _mesa_enum_to_string(mode), 1884 (unsigned long) indirect, (unsigned long) drawcount_offset, 1885 maxdrawcount, stride); 1886 1887 /* If <stride> is zero, the array elements are treated as tightly packed. */ 1888 if (stride == 0) 1889 stride = 4 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */ 1890 1891 FLUSH_FOR_DRAW(ctx); 1892 1893 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 1894 1895 if (_mesa_is_no_error_enabled(ctx)) { 1896 if (ctx->NewState) 1897 _mesa_update_state(ctx); 1898 } else { 1899 if (!_mesa_validate_MultiDrawArraysIndirectCount(ctx, mode, 1900 indirect, 1901 drawcount_offset, 1902 maxdrawcount, stride)) 1903 return; 1904 } 1905 1906 if (skip_validated_draw(ctx)) 1907 return; 1908 1909 _mesa_validated_multidrawarraysindirectcount(ctx, mode, indirect, 1910 drawcount_offset, 1911 maxdrawcount, stride); 1912} 1913 1914 1915static void GLAPIENTRY 1916_mesa_exec_MultiDrawElementsIndirectCount(GLenum mode, GLenum type, 1917 GLintptr indirect, 1918 GLintptr drawcount_offset, 1919 GLsizei maxdrawcount, GLsizei stride) 1920{ 1921 GET_CURRENT_CONTEXT(ctx); 1922 1923 if (MESA_VERBOSE & VERBOSE_DRAW) 1924 _mesa_debug(ctx, "glMultiDrawElementsIndirectCountARB" 1925 "(%s, %s, %lx, %lx, %i, %i)\n", 1926 _mesa_enum_to_string(mode), _mesa_enum_to_string(type), 1927 (unsigned long) indirect, (unsigned long) drawcount_offset, 1928 maxdrawcount, stride); 1929 1930 /* If <stride> is zero, the array elements are treated as tightly packed. */ 1931 if (stride == 0) 1932 stride = 5 * sizeof(GLuint); /* sizeof(DrawElementsIndirectCommand) */ 1933 1934 FLUSH_FOR_DRAW(ctx); 1935 1936 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx)); 1937 1938 if (_mesa_is_no_error_enabled(ctx)) { 1939 if (ctx->NewState) 1940 _mesa_update_state(ctx); 1941 } else { 1942 if (!_mesa_validate_MultiDrawElementsIndirectCount(ctx, mode, type, 1943 indirect, 1944 drawcount_offset, 1945 maxdrawcount, stride)) 1946 return; 1947 } 1948 1949 if (skip_validated_draw(ctx)) 1950 return; 1951 1952 _mesa_validated_multidrawelementsindirectcount(ctx, mode, type, indirect, 1953 drawcount_offset, maxdrawcount, 1954 stride); 1955} 1956 1957 1958/** 1959 * Initialize the dispatch table with the VBO functions for drawing. 1960 */ 1961void 1962_mesa_initialize_exec_dispatch(const struct gl_context *ctx, 1963 struct _glapi_table *exec) 1964{ 1965 SET_DrawArrays(exec, _mesa_DrawArrays); 1966 SET_DrawElements(exec, _mesa_DrawElements); 1967 1968 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { 1969 SET_DrawRangeElements(exec, _mesa_DrawRangeElements); 1970 } 1971 1972 SET_MultiDrawArrays(exec, _mesa_exec_MultiDrawArrays); 1973 SET_MultiDrawElementsEXT(exec, _mesa_MultiDrawElements); 1974 1975 if (ctx->API == API_OPENGL_COMPAT) { 1976 SET_Rectf(exec, _mesa_exec_Rectf); 1977 SET_EvalMesh1(exec, _mesa_exec_EvalMesh1); 1978 SET_EvalMesh2(exec, _mesa_exec_EvalMesh2); 1979 } 1980 1981 if (ctx->API != API_OPENGLES && 1982 ctx->Extensions.ARB_draw_elements_base_vertex) { 1983 SET_DrawElementsBaseVertex(exec, _mesa_DrawElementsBaseVertex); 1984 SET_MultiDrawElementsBaseVertex(exec, 1985 _mesa_MultiDrawElementsBaseVertex); 1986 1987 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { 1988 SET_DrawRangeElementsBaseVertex(exec, 1989 _mesa_DrawRangeElementsBaseVertex); 1990 SET_DrawElementsInstancedBaseVertex(exec, 1991 _mesa_exec_DrawElementsInstancedBaseVertex); 1992 } 1993 } 1994 1995 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { 1996 SET_DrawArraysInstancedBaseInstance(exec, 1997 _mesa_exec_DrawArraysInstancedBaseInstance); 1998 SET_DrawElementsInstancedBaseInstance(exec, 1999 _mesa_exec_DrawElementsInstancedBaseInstance); 2000 SET_DrawElementsInstancedBaseVertexBaseInstance(exec, 2001 _mesa_exec_DrawElementsInstancedBaseVertexBaseInstance); 2002 } 2003 2004 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) { 2005 SET_DrawArraysIndirect(exec, _mesa_exec_DrawArraysIndirect); 2006 SET_DrawElementsIndirect(exec, _mesa_exec_DrawElementsIndirect); 2007 } 2008 2009 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { 2010 SET_DrawArraysInstancedARB(exec, _mesa_DrawArraysInstanced); 2011 SET_DrawElementsInstancedARB(exec, _mesa_exec_DrawElementsInstanced); 2012 } 2013 2014 if (_mesa_is_desktop_gl(ctx)) { 2015 SET_DrawTransformFeedback(exec, _mesa_DrawTransformFeedback); 2016 SET_DrawTransformFeedbackStream(exec, 2017 _mesa_exec_DrawTransformFeedbackStream); 2018 SET_DrawTransformFeedbackInstanced(exec, 2019 _mesa_exec_DrawTransformFeedbackInstanced); 2020 SET_DrawTransformFeedbackStreamInstanced(exec, 2021 _mesa_exec_DrawTransformFeedbackStreamInstanced); 2022 SET_MultiDrawArraysIndirect(exec, _mesa_exec_MultiDrawArraysIndirect); 2023 SET_MultiDrawElementsIndirect(exec, _mesa_exec_MultiDrawElementsIndirect); 2024 SET_MultiDrawArraysIndirectCountARB(exec, 2025 _mesa_exec_MultiDrawArraysIndirectCount); 2026 SET_MultiDrawElementsIndirectCountARB(exec, 2027 _mesa_exec_MultiDrawElementsIndirectCount); 2028 } 2029} 2030 2031 2032 2033/* GL_IBM_multimode_draw_arrays */ 2034void GLAPIENTRY 2035_mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first, 2036 const GLsizei * count, 2037 GLsizei primcount, GLint modestride ) 2038{ 2039 GET_CURRENT_CONTEXT(ctx); 2040 GLint i; 2041 2042 FLUSH_VERTICES(ctx, 0); 2043 2044 for ( i = 0 ; i < primcount ; i++ ) { 2045 if ( count[i] > 0 ) { 2046 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); 2047 CALL_DrawArrays(ctx->CurrentServerDispatch, ( m, first[i], count[i] )); 2048 } 2049 } 2050} 2051 2052 2053/* GL_IBM_multimode_draw_arrays */ 2054void GLAPIENTRY 2055_mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count, 2056 GLenum type, const GLvoid * const * indices, 2057 GLsizei primcount, GLint modestride ) 2058{ 2059 GET_CURRENT_CONTEXT(ctx); 2060 GLint i; 2061 2062 FLUSH_VERTICES(ctx, 0); 2063 2064 /* XXX not sure about ARB_vertex_buffer_object handling here */ 2065 2066 for ( i = 0 ; i < primcount ; i++ ) { 2067 if ( count[i] > 0 ) { 2068 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); 2069 CALL_DrawElements(ctx->CurrentServerDispatch, ( m, count[i], type, 2070 indices[i] )); 2071 } 2072 } 2073} 2074 2075 2076/* 2077 * Helper function for _mesa_draw_indirect below that additionally takes a zero 2078 * initialized array of _mesa_prim scratch space memory as the last argument. 2079 */ 2080static void 2081draw_indirect(struct gl_context *ctx, GLuint mode, 2082 struct gl_buffer_object *indirect_data, 2083 GLsizeiptr indirect_offset, unsigned draw_count, 2084 unsigned stride, 2085 struct gl_buffer_object *indirect_draw_count_buffer, 2086 GLsizeiptr indirect_draw_count_offset, 2087 const struct _mesa_index_buffer *ib, 2088 struct _mesa_prim *prim) 2089{ 2090 prim[0].begin = 1; 2091 prim[draw_count - 1].end = 1; 2092 for (unsigned i = 0; i < draw_count; ++i, indirect_offset += stride) { 2093 prim[i].mode = mode; 2094 prim[i].indexed = !!ib; 2095 prim[i].indirect_offset = indirect_offset; 2096 prim[i].is_indirect = 1; 2097 prim[i].draw_id = i; 2098 } 2099 2100 /* This should always be true at this time */ 2101 assert(indirect_data == ctx->DrawIndirectBuffer); 2102 2103 ctx->Driver.Draw(ctx, prim, draw_count, ib, false, 0u, ~0u, 2104 NULL, 0, indirect_data); 2105} 2106 2107 2108/* 2109 * Function to be put into dd_function_table::DrawIndirect as fallback. 2110 * Calls into dd_function_table::Draw past adapting call arguments. 2111 * See dd_function_table::DrawIndirect for call argument documentation. 2112 */ 2113void 2114_mesa_draw_indirect(struct gl_context *ctx, GLuint mode, 2115 struct gl_buffer_object *indirect_data, 2116 GLsizeiptr indirect_offset, unsigned draw_count, 2117 unsigned stride, 2118 struct gl_buffer_object *indirect_draw_count_buffer, 2119 GLsizeiptr indirect_draw_count_offset, 2120 const struct _mesa_index_buffer *ib) 2121{ 2122 /* Use alloca for the prim space if we are somehow in bounds. */ 2123 if (draw_count*sizeof(struct _mesa_prim) < 1024) { 2124 struct _mesa_prim *space = alloca(draw_count*sizeof(struct _mesa_prim)); 2125 memset(space, 0, draw_count*sizeof(struct _mesa_prim)); 2126 2127 draw_indirect(ctx, mode, indirect_data, indirect_offset, draw_count, 2128 stride, indirect_draw_count_buffer, 2129 indirect_draw_count_offset, ib, space); 2130 } else { 2131 struct _mesa_prim *space = calloc(draw_count, sizeof(struct _mesa_prim)); 2132 if (space == NULL) { 2133 _mesa_error(ctx, GL_OUT_OF_MEMORY, "gl%sDraw%sIndirect%s", 2134 (draw_count > 1) ? "Multi" : "", 2135 ib ? "Elements" : "Arrays", 2136 indirect_data ? "CountARB" : ""); 2137 return; 2138 } 2139 2140 draw_indirect(ctx, mode, indirect_data, indirect_offset, draw_count, 2141 stride, indirect_draw_count_buffer, 2142 indirect_draw_count_offset, ib, space); 2143 2144 free(space); 2145 } 2146} 2147