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 "main/arrayobj.h" 31 #include "main/glheader.h" 32 #include "main/context.h" 33 #include "main/state.h" 34 #include "main/api_validate.h" 35 #include "main/dispatch.h" 36 #include "main/varray.h" 37 #include "main/bufferobj.h" 38 #include "main/enums.h" 39 #include "main/macros.h" 40 #include "main/transformfeedback.h" 41 42 #include "vbo_context.h" 43 44 45 /** 46 * Check that element 'j' of the array has reasonable data. 47 * Map VBO if needed. 48 * For debugging purposes; not normally used. 49 */ 50 static void 51 check_array_data(struct gl_context *ctx, struct gl_vertex_array_object *vao, 52 GLuint attrib, GLuint j) 53 { 54 const struct gl_array_attributes *array = &vao->VertexAttrib[attrib]; 55 if (array->Enabled) { 56 const struct gl_vertex_buffer_binding *binding = 57 &vao->BufferBinding[array->BufferBindingIndex]; 58 struct gl_buffer_object *bo = binding->BufferObj; 59 const void *data = array->Ptr; 60 if (_mesa_is_bufferobj(bo)) { 61 if (!bo->Mappings[MAP_INTERNAL].Pointer) { 62 /* need to map now */ 63 bo->Mappings[MAP_INTERNAL].Pointer = 64 ctx->Driver.MapBufferRange(ctx, 0, bo->Size, 65 GL_MAP_READ_BIT, bo, MAP_INTERNAL); 66 } 67 data = ADD_POINTERS(_mesa_vertex_attrib_address(array, binding), 68 bo->Mappings[MAP_INTERNAL].Pointer); 69 } 70 switch (array->Type) { 71 case GL_FLOAT: 72 { 73 GLfloat *f = (GLfloat *) ((GLubyte *) data + binding->Stride * j); 74 GLint k; 75 for (k = 0; k < array->Size; k++) { 76 if (IS_INF_OR_NAN(f[k]) || f[k] >= 1.0e20F || f[k] <= -1.0e10F) { 77 printf("Bad array data:\n"); 78 printf(" Element[%u].%u = %f\n", j, k, f[k]); 79 printf(" Array %u at %p\n", attrib, (void *) array); 80 printf(" Type 0x%x, Size %d, Stride %d\n", 81 array->Type, array->Size, binding->Stride); 82 printf(" Address/offset %p in Buffer Object %u\n", 83 array->Ptr, bo->Name); 84 f[k] = 1.0F; /* XXX replace the bad value! */ 85 } 86 /*assert(!IS_INF_OR_NAN(f[k])); */ 87 } 88 } 89 break; 90 default: 91 ; 92 } 93 } 94 } 95 96 97 /** 98 * Unmap the buffer object referenced by given array, if mapped. 99 */ 100 static void 101 unmap_array_buffer(struct gl_context *ctx, struct gl_vertex_array_object *vao, 102 GLuint attrib) 103 { 104 const struct gl_array_attributes *array = &vao->VertexAttrib[attrib]; 105 if (array->Enabled) { 106 const struct gl_vertex_buffer_binding *binding = 107 &vao->BufferBinding[array->BufferBindingIndex]; 108 struct gl_buffer_object *bo = binding->BufferObj; 109 if (_mesa_is_bufferobj(bo) && _mesa_bufferobj_mapped(bo, MAP_INTERNAL)) { 110 ctx->Driver.UnmapBuffer(ctx, bo, MAP_INTERNAL); 111 } 112 } 113 } 114 115 116 /** 117 * Examine the array's data for NaNs, etc. 118 * For debug purposes; not normally used. 119 */ 120 static void 121 check_draw_elements_data(struct gl_context *ctx, GLsizei count, 122 GLenum elemType, const void *elements, 123 GLint basevertex) 124 { 125 struct gl_vertex_array_object *vao = ctx->Array.VAO; 126 const void *elemMap; 127 GLint i; 128 GLuint k; 129 130 if (_mesa_is_bufferobj(vao->IndexBufferObj)) { 131 elemMap = ctx->Driver.MapBufferRange(ctx, 0, 132 vao->IndexBufferObj->Size, 133 GL_MAP_READ_BIT, 134 vao->IndexBufferObj, MAP_INTERNAL); 135 elements = ADD_POINTERS(elements, elemMap); 136 } 137 138 for (i = 0; i < count; i++) { 139 GLuint j; 140 141 /* j = element[i] */ 142 switch (elemType) { 143 case GL_UNSIGNED_BYTE: 144 j = ((const GLubyte *) elements)[i]; 145 break; 146 case GL_UNSIGNED_SHORT: 147 j = ((const GLushort *) elements)[i]; 148 break; 149 case GL_UNSIGNED_INT: 150 j = ((const GLuint *) elements)[i]; 151 break; 152 default: 153 assert(0); 154 } 155 156 /* check element j of each enabled array */ 157 for (k = 0; k < VERT_ATTRIB_MAX; k++) { 158 check_array_data(ctx, vao, k, j); 159 } 160 } 161 162 if (_mesa_is_bufferobj(vao->IndexBufferObj)) { 163 ctx->Driver.UnmapBuffer(ctx, vao->IndexBufferObj, MAP_INTERNAL); 164 } 165 166 for (k = 0; k < VERT_ATTRIB_MAX; k++) { 167 unmap_array_buffer(ctx, vao, k); 168 } 169 } 170 171 172 /** 173 * Check array data, looking for NaNs, etc. 174 */ 175 static void 176 check_draw_arrays_data(struct gl_context *ctx, GLint start, GLsizei count) 177 { 178 /* TO DO */ 179 } 180 181 182 /** 183 * Print info/data for glDrawArrays(), for debugging. 184 */ 185 static void 186 print_draw_arrays(struct gl_context *ctx, 187 GLenum mode, GLint start, GLsizei count) 188 { 189 const struct gl_vertex_array_object *vao = ctx->Array.VAO; 190 191 printf("vbo_exec_DrawArrays(mode 0x%x, start %d, count %d):\n", 192 mode, start, count); 193 194 unsigned i; 195 for (i = 0; i < VERT_ATTRIB_MAX; ++i) { 196 const struct gl_array_attributes *array = &vao->VertexAttrib[i]; 197 if (!array->Enabled) 198 continue; 199 200 const struct gl_vertex_buffer_binding *binding = 201 &vao->BufferBinding[array->BufferBindingIndex]; 202 struct gl_buffer_object *bufObj = binding->BufferObj; 203 204 printf("attr %s: size %d stride %d enabled %d " 205 "ptr %p Bufobj %u\n", 206 gl_vert_attrib_name((gl_vert_attrib) i), 207 array->Size, binding->Stride, array->Enabled, 208 array->Ptr, bufObj->Name); 209 210 if (_mesa_is_bufferobj(bufObj)) { 211 GLubyte *p = ctx->Driver.MapBufferRange(ctx, 0, bufObj->Size, 212 GL_MAP_READ_BIT, bufObj, 213 MAP_INTERNAL); 214 int offset = (int) (GLintptr) 215 _mesa_vertex_attrib_address(array, binding); 216 float *f = (float *) (p + offset); 217 int *k = (int *) f; 218 int i; 219 int n = (count * binding->Stride) / 4; 220 if (n > 32) 221 n = 32; 222 printf(" Data at offset %d:\n", offset); 223 for (i = 0; i < n; i++) { 224 printf(" float[%d] = 0x%08x %f\n", i, k[i], f[i]); 225 } 226 ctx->Driver.UnmapBuffer(ctx, bufObj, MAP_INTERNAL); 227 } 228 } 229 } 230 231 232 /** 233 * Set the vbo->exec->inputs[] pointers to point to the enabled 234 * vertex arrays. This depends on the current vertex program/shader 235 * being executed because of whether or not generic vertex arrays 236 * alias the conventional vertex arrays. 237 * For arrays that aren't enabled, we set the input[attrib] pointer 238 * to point at a zero-stride current value "array". 239 */ 240 static void 241 recalculate_input_bindings(struct gl_context *ctx) 242 { 243 struct vbo_context *vbo = vbo_context(ctx); 244 struct vbo_exec_context *exec = &vbo->exec; 245 const struct gl_array_attributes *array = ctx->Array.VAO->VertexAttrib; 246 struct gl_vertex_array *vertexAttrib = ctx->Array.VAO->_VertexAttrib; 247 const struct gl_vertex_array **inputs = &exec->array.inputs[0]; 248 GLbitfield64 const_inputs = 0x0; 249 GLuint i; 250 251 switch (get_program_mode(ctx)) { 252 case VP_NONE: 253 /* When no vertex program is active (or the vertex program is generated 254 * from fixed-function state). We put the material values into the 255 * generic slots. This is the only situation where material values 256 * are available as per-vertex attributes. 257 */ 258 for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) { 259 if (array[VERT_ATTRIB_FF(i)].Enabled) 260 inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)]; 261 else { 262 inputs[i] = &vbo->currval[VBO_ATTRIB_POS + i]; 263 const_inputs |= VERT_BIT(i); 264 } 265 } 266 267 for (i = 0; i < MAT_ATTRIB_MAX; i++) { 268 inputs[VERT_ATTRIB_GENERIC(i)] = 269 &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT + i]; 270 const_inputs |= VERT_BIT_GENERIC(i); 271 } 272 273 /* Could use just about anything, just to fill in the empty 274 * slots: 275 */ 276 for (i = MAT_ATTRIB_MAX; i < VERT_ATTRIB_GENERIC_MAX; i++) { 277 inputs[VERT_ATTRIB_GENERIC(i)] = 278 &vbo->currval[VBO_ATTRIB_GENERIC0 + i]; 279 const_inputs |= VERT_BIT_GENERIC(i); 280 } 281 break; 282 283 case VP_ARB: 284 /* There are no shaders in OpenGL ES 1.x, so this code path should be 285 * impossible to reach. The meta code is careful to not use shaders in 286 * ES1. 287 */ 288 assert(ctx->API != API_OPENGLES); 289 290 /* In the compatibility profile of desktop OpenGL, the generic[0] 291 * attribute array aliases and overrides the legacy position array. 292 * Otherwise, legacy attributes available in the legacy slots, 293 * generic attributes in the generic slots and materials are not 294 * available as per-vertex attributes. 295 * 296 * In all other APIs, only the generic attributes exist, and none of the 297 * slots are considered "magic." 298 */ 299 if (ctx->API == API_OPENGL_COMPAT) { 300 if (array[VERT_ATTRIB_GENERIC0].Enabled) 301 inputs[0] = &vertexAttrib[VERT_ATTRIB_GENERIC0]; 302 else if (array[VERT_ATTRIB_POS].Enabled) 303 inputs[0] = &vertexAttrib[VERT_ATTRIB_POS]; 304 else { 305 inputs[0] = &vbo->currval[VBO_ATTRIB_POS]; 306 const_inputs |= VERT_BIT_POS; 307 } 308 309 for (i = 1; i < VERT_ATTRIB_FF_MAX; i++) { 310 if (array[VERT_ATTRIB_FF(i)].Enabled) 311 inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)]; 312 else { 313 inputs[i] = &vbo->currval[VBO_ATTRIB_POS + i]; 314 const_inputs |= VERT_BIT_FF(i); 315 } 316 } 317 318 for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) { 319 if (array[VERT_ATTRIB_GENERIC(i)].Enabled) 320 inputs[VERT_ATTRIB_GENERIC(i)] = 321 &vertexAttrib[VERT_ATTRIB_GENERIC(i)]; 322 else { 323 inputs[VERT_ATTRIB_GENERIC(i)] = 324 &vbo->currval[VBO_ATTRIB_GENERIC0 + i]; 325 const_inputs |= VERT_BIT_GENERIC(i); 326 } 327 } 328 329 inputs[VERT_ATTRIB_GENERIC0] = inputs[0]; 330 } else { 331 /* Other parts of the code assume that inputs[0] through 332 * inputs[VERT_ATTRIB_FF_MAX] will be non-NULL. However, in OpenGL 333 * ES 2.0+ or OpenGL core profile, none of these arrays should ever 334 * be enabled. 335 */ 336 for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) { 337 assert(!array[VERT_ATTRIB_FF(i)].Enabled); 338 339 inputs[i] = &vbo->currval[VBO_ATTRIB_POS + i]; 340 const_inputs |= VERT_BIT_FF(i); 341 } 342 343 for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) { 344 if (array[VERT_ATTRIB_GENERIC(i)].Enabled) 345 inputs[VERT_ATTRIB_GENERIC(i)] = 346 &vertexAttrib[VERT_ATTRIB_GENERIC(i)]; 347 else { 348 inputs[VERT_ATTRIB_GENERIC(i)] = 349 &vbo->currval[VBO_ATTRIB_GENERIC0 + i]; 350 const_inputs |= VERT_BIT_GENERIC(i); 351 } 352 } 353 } 354 355 break; 356 } 357 358 _mesa_set_varying_vp_inputs(ctx, VERT_BIT_ALL & (~const_inputs)); 359 ctx->NewDriverState |= ctx->DriverFlags.NewArray; 360 } 361 362 363 /** 364 * Examine the enabled vertex arrays to set the exec->array.inputs[] values. 365 * These will point to the arrays to actually use for drawing. Some will 366 * be user-provided arrays, other will be zero-stride const-valued arrays. 367 * Note that this might set the _NEW_VARYING_VP_INPUTS dirty flag so state 368 * validation must be done after this call. 369 */ 370 void 371 vbo_bind_arrays(struct gl_context *ctx) 372 { 373 struct vbo_context *vbo = vbo_context(ctx); 374 struct vbo_exec_context *exec = &vbo->exec; 375 376 vbo_draw_method(vbo, DRAW_ARRAYS); 377 378 if (exec->array.recalculate_inputs) { 379 recalculate_input_bindings(ctx); 380 exec->array.recalculate_inputs = GL_FALSE; 381 382 /* Again... because we may have changed the bitmask of per-vertex varying 383 * attributes. If we regenerate the fixed-function vertex program now 384 * we may be able to prune down the number of vertex attributes which we 385 * need in the shader. 386 */ 387 if (ctx->NewState) { 388 /* Setting "validating" to TRUE prevents _mesa_update_state from 389 * invalidating what we just did. 390 */ 391 exec->validating = GL_TRUE; 392 _mesa_update_state(ctx); 393 exec->validating = GL_FALSE; 394 } 395 } 396 } 397 398 399 /** 400 * Helper function called by the other DrawArrays() functions below. 401 * This is where we handle primitive restart for drawing non-indexed 402 * arrays. If primitive restart is enabled, it typically means 403 * splitting one DrawArrays() into two. 404 */ 405 static void 406 vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, 407 GLsizei count, GLuint numInstances, GLuint baseInstance) 408 { 409 struct vbo_context *vbo = vbo_context(ctx); 410 struct _mesa_prim prim[2]; 411 412 vbo_bind_arrays(ctx); 413 414 /* init most fields to zero */ 415 memset(prim, 0, sizeof(prim)); 416 prim[0].begin = 1; 417 prim[0].end = 1; 418 prim[0].mode = mode; 419 prim[0].num_instances = numInstances; 420 prim[0].base_instance = baseInstance; 421 prim[0].is_indirect = 0; 422 423 /* Implement the primitive restart index */ 424 if (ctx->Array.PrimitiveRestart && 425 !ctx->Array.PrimitiveRestartFixedIndex && 426 ctx->Array.RestartIndex < count) { 427 GLuint primCount = 0; 428 429 if (ctx->Array.RestartIndex == start) { 430 /* special case: RestartIndex at beginning */ 431 if (count > 1) { 432 prim[0].start = start + 1; 433 prim[0].count = count - 1; 434 primCount = 1; 435 } 436 } 437 else if (ctx->Array.RestartIndex == start + count - 1) { 438 /* special case: RestartIndex at end */ 439 if (count > 1) { 440 prim[0].start = start; 441 prim[0].count = count - 1; 442 primCount = 1; 443 } 444 } 445 else { 446 /* general case: RestartIndex in middle, split into two prims */ 447 prim[0].start = start; 448 prim[0].count = ctx->Array.RestartIndex - start; 449 450 prim[1] = prim[0]; 451 prim[1].start = ctx->Array.RestartIndex + 1; 452 prim[1].count = count - prim[1].start; 453 454 primCount = 2; 455 } 456 457 if (primCount > 0) { 458 /* draw one or two prims */ 459 vbo->draw_prims(ctx, prim, primCount, NULL, 460 GL_TRUE, start, start + count - 1, NULL, 0, NULL); 461 } 462 } 463 else { 464 /* no prim restart */ 465 prim[0].start = start; 466 prim[0].count = count; 467 468 vbo->draw_prims(ctx, prim, 1, NULL, 469 GL_TRUE, start, start + count - 1, NULL, 0, NULL); 470 } 471 472 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 473 _mesa_flush(ctx); 474 } 475 } 476 477 478 /** 479 * Execute a glRectf() function. 480 */ 481 static void GLAPIENTRY 482 vbo_exec_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) 483 { 484 GET_CURRENT_CONTEXT(ctx); 485 ASSERT_OUTSIDE_BEGIN_END(ctx); 486 487 CALL_Begin(GET_DISPATCH(), (GL_QUADS)); 488 CALL_Vertex2f(GET_DISPATCH(), (x1, y1)); 489 CALL_Vertex2f(GET_DISPATCH(), (x2, y1)); 490 CALL_Vertex2f(GET_DISPATCH(), (x2, y2)); 491 CALL_Vertex2f(GET_DISPATCH(), (x1, y2)); 492 CALL_End(GET_DISPATCH(), ()); 493 } 494 495 496 static void GLAPIENTRY 497 vbo_exec_EvalMesh1(GLenum mode, GLint i1, GLint i2) 498 { 499 GET_CURRENT_CONTEXT(ctx); 500 GLint i; 501 GLfloat u, du; 502 GLenum prim; 503 504 switch (mode) { 505 case GL_POINT: 506 prim = GL_POINTS; 507 break; 508 case GL_LINE: 509 prim = GL_LINE_STRIP; 510 break; 511 default: 512 _mesa_error(ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)"); 513 return; 514 } 515 516 /* No effect if vertex maps disabled. 517 */ 518 if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3) 519 return; 520 521 du = ctx->Eval.MapGrid1du; 522 u = ctx->Eval.MapGrid1u1 + i1 * du; 523 524 CALL_Begin(GET_DISPATCH(), (prim)); 525 for (i = i1; i <= i2; i++, u += du) { 526 CALL_EvalCoord1f(GET_DISPATCH(), (u)); 527 } 528 CALL_End(GET_DISPATCH(), ()); 529 } 530 531 532 static void GLAPIENTRY 533 vbo_exec_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) 534 { 535 GET_CURRENT_CONTEXT(ctx); 536 GLfloat u, du, v, dv, v1, u1; 537 GLint i, j; 538 539 switch (mode) { 540 case GL_POINT: 541 case GL_LINE: 542 case GL_FILL: 543 break; 544 default: 545 _mesa_error(ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)"); 546 return; 547 } 548 549 /* No effect if vertex maps disabled. 550 */ 551 if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3) 552 return; 553 554 du = ctx->Eval.MapGrid2du; 555 dv = ctx->Eval.MapGrid2dv; 556 v1 = ctx->Eval.MapGrid2v1 + j1 * dv; 557 u1 = ctx->Eval.MapGrid2u1 + i1 * du; 558 559 switch (mode) { 560 case GL_POINT: 561 CALL_Begin(GET_DISPATCH(), (GL_POINTS)); 562 for (v = v1, j = j1; j <= j2; j++, v += dv) { 563 for (u = u1, i = i1; i <= i2; i++, u += du) { 564 CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); 565 } 566 } 567 CALL_End(GET_DISPATCH(), ()); 568 break; 569 case GL_LINE: 570 for (v = v1, j = j1; j <= j2; j++, v += dv) { 571 CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP)); 572 for (u = u1, i = i1; i <= i2; i++, u += du) { 573 CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); 574 } 575 CALL_End(GET_DISPATCH(), ()); 576 } 577 for (u = u1, i = i1; i <= i2; i++, u += du) { 578 CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP)); 579 for (v = v1, j = j1; j <= j2; j++, v += dv) { 580 CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); 581 } 582 CALL_End(GET_DISPATCH(), ()); 583 } 584 break; 585 case GL_FILL: 586 for (v = v1, j = j1; j < j2; j++, v += dv) { 587 CALL_Begin(GET_DISPATCH(), (GL_TRIANGLE_STRIP)); 588 for (u = u1, i = i1; i <= i2; i++, u += du) { 589 CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); 590 CALL_EvalCoord2f(GET_DISPATCH(), (u, v + dv)); 591 } 592 CALL_End(GET_DISPATCH(), ()); 593 } 594 break; 595 } 596 } 597 598 599 /** 600 * Called from glDrawArrays when in immediate mode (not display list mode). 601 */ 602 static void GLAPIENTRY 603 vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) 604 { 605 GET_CURRENT_CONTEXT(ctx); 606 607 if (MESA_VERBOSE & VERBOSE_DRAW) 608 _mesa_debug(ctx, "glDrawArrays(%s, %d, %d)\n", 609 _mesa_enum_to_string(mode), start, count); 610 611 if (!_mesa_validate_DrawArrays(ctx, mode, count)) 612 return; 613 614 if (0) 615 check_draw_arrays_data(ctx, start, count); 616 617 vbo_draw_arrays(ctx, mode, start, count, 1, 0); 618 619 if (0) 620 print_draw_arrays(ctx, mode, start, count); 621 } 622 623 624 /** 625 * Called from glDrawArraysInstanced when in immediate mode (not 626 * display list mode). 627 */ 628 static void GLAPIENTRY 629 vbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count, 630 GLsizei numInstances) 631 { 632 GET_CURRENT_CONTEXT(ctx); 633 634 if (MESA_VERBOSE & VERBOSE_DRAW) 635 _mesa_debug(ctx, "glDrawArraysInstanced(%s, %d, %d, %d)\n", 636 _mesa_enum_to_string(mode), start, count, numInstances); 637 638 if (!_mesa_validate_DrawArraysInstanced(ctx, mode, start, count, 639 numInstances)) 640 return; 641 642 if (0) 643 check_draw_arrays_data(ctx, start, count); 644 645 vbo_draw_arrays(ctx, mode, start, count, numInstances, 0); 646 647 if (0) 648 print_draw_arrays(ctx, mode, start, count); 649 } 650 651 652 /** 653 * Called from glDrawArraysInstancedBaseInstance when in immediate mode. 654 */ 655 static void GLAPIENTRY 656 vbo_exec_DrawArraysInstancedBaseInstance(GLenum mode, GLint first, 657 GLsizei count, GLsizei numInstances, 658 GLuint baseInstance) 659 { 660 GET_CURRENT_CONTEXT(ctx); 661 662 if (MESA_VERBOSE & VERBOSE_DRAW) 663 _mesa_debug(ctx, 664 "glDrawArraysInstancedBaseInstance(%s, %d, %d, %d, %d)\n", 665 _mesa_enum_to_string(mode), first, count, 666 numInstances, baseInstance); 667 668 if (!_mesa_validate_DrawArraysInstanced(ctx, mode, first, count, 669 numInstances)) 670 return; 671 672 if (0) 673 check_draw_arrays_data(ctx, first, count); 674 675 vbo_draw_arrays(ctx, mode, first, count, numInstances, baseInstance); 676 677 if (0) 678 print_draw_arrays(ctx, mode, first, count); 679 } 680 681 682 683 /** 684 * Map GL_ELEMENT_ARRAY_BUFFER and print contents. 685 * For debugging. 686 */ 687 #if 0 688 static void 689 dump_element_buffer(struct gl_context *ctx, GLenum type) 690 { 691 const GLvoid *map = 692 ctx->Driver.MapBufferRange(ctx, 0, 693 ctx->Array.VAO->IndexBufferObj->Size, 694 GL_MAP_READ_BIT, 695 ctx->Array.VAO->IndexBufferObj, 696 MAP_INTERNAL); 697 switch (type) { 698 case GL_UNSIGNED_BYTE: 699 { 700 const GLubyte *us = (const GLubyte *) map; 701 GLint i; 702 for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size; i++) { 703 printf("%02x ", us[i]); 704 if (i % 32 == 31) 705 printf("\n"); 706 } 707 printf("\n"); 708 } 709 break; 710 case GL_UNSIGNED_SHORT: 711 { 712 const GLushort *us = (const GLushort *) map; 713 GLint i; 714 for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size / 2; i++) { 715 printf("%04x ", us[i]); 716 if (i % 16 == 15) 717 printf("\n"); 718 } 719 printf("\n"); 720 } 721 break; 722 case GL_UNSIGNED_INT: 723 { 724 const GLuint *us = (const GLuint *) map; 725 GLint i; 726 for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size / 4; i++) { 727 printf("%08x ", us[i]); 728 if (i % 8 == 7) 729 printf("\n"); 730 } 731 printf("\n"); 732 } 733 break; 734 default: 735 ; 736 } 737 738 ctx->Driver.UnmapBuffer(ctx, ctx->Array.VAO->IndexBufferObj, MAP_INTERNAL); 739 } 740 #endif 741 742 743 /** 744 * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements. 745 * Do the rendering for a glDrawElements or glDrawRangeElements call after 746 * we've validated buffer bounds, etc. 747 */ 748 static void 749 vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, 750 GLboolean index_bounds_valid, 751 GLuint start, GLuint end, 752 GLsizei count, GLenum type, 753 const GLvoid * indices, 754 GLint basevertex, GLuint numInstances, 755 GLuint baseInstance) 756 { 757 struct vbo_context *vbo = vbo_context(ctx); 758 struct _mesa_index_buffer ib; 759 struct _mesa_prim prim[1]; 760 761 vbo_bind_arrays(ctx); 762 763 ib.count = count; 764 ib.type = type; 765 ib.obj = ctx->Array.VAO->IndexBufferObj; 766 ib.ptr = indices; 767 768 prim[0].begin = 1; 769 prim[0].end = 1; 770 prim[0].weak = 0; 771 prim[0].pad = 0; 772 prim[0].mode = mode; 773 prim[0].start = 0; 774 prim[0].count = count; 775 prim[0].indexed = 1; 776 prim[0].is_indirect = 0; 777 prim[0].basevertex = basevertex; 778 prim[0].num_instances = numInstances; 779 prim[0].base_instance = baseInstance; 780 prim[0].draw_id = 0; 781 782 /* Need to give special consideration to rendering a range of 783 * indices starting somewhere above zero. Typically the 784 * application is issuing multiple DrawRangeElements() to draw 785 * successive primitives layed out linearly in the vertex arrays. 786 * Unless the vertex arrays are all in a VBO (or locked as with 787 * CVA), the OpenGL semantics imply that we need to re-read or 788 * re-upload the vertex data on each draw call. 789 * 790 * In the case of hardware tnl, we want to avoid starting the 791 * upload at zero, as it will mean every draw call uploads an 792 * increasing amount of not-used vertex data. Worse - in the 793 * software tnl module, all those vertices might be transformed and 794 * lit but never rendered. 795 * 796 * If we just upload or transform the vertices in start..end, 797 * however, the indices will be incorrect. 798 * 799 * At this level, we don't know exactly what the requirements of 800 * the backend are going to be, though it will likely boil down to 801 * either: 802 * 803 * 1) Do nothing, everything is in a VBO and is processed once 804 * only. 805 * 806 * 2) Adjust the indices and vertex arrays so that start becomes 807 * zero. 808 * 809 * Rather than doing anything here, I'll provide a helper function 810 * for the latter case elsewhere. 811 */ 812 813 vbo->draw_prims(ctx, prim, 1, &ib, 814 index_bounds_valid, start, end, NULL, 0, NULL); 815 816 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 817 _mesa_flush(ctx); 818 } 819 } 820 821 822 /** 823 * Called by glDrawRangeElementsBaseVertex() in immediate mode. 824 */ 825 static void GLAPIENTRY 826 vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, 827 GLsizei count, GLenum type, 828 const GLvoid * indices, GLint basevertex) 829 { 830 static GLuint warnCount = 0; 831 GLboolean index_bounds_valid = GL_TRUE; 832 833 /* This is only useful to catch invalid values in the "end" parameter 834 * like ~0. 835 */ 836 GLuint max_element = 2 * 1000 * 1000 * 1000; /* just a big number */ 837 838 GET_CURRENT_CONTEXT(ctx); 839 840 if (MESA_VERBOSE & VERBOSE_DRAW) 841 _mesa_debug(ctx, 842 "glDrawRangeElementsBaseVertex(%s, %u, %u, %d, %s, %p, %d)\n", 843 _mesa_enum_to_string(mode), start, end, count, 844 _mesa_enum_to_string(type), indices, basevertex); 845 846 if (!_mesa_validate_DrawRangeElements(ctx, mode, start, end, count, 847 type, indices)) 848 return; 849 850 if ((int) end + basevertex < 0 || start + basevertex >= max_element) { 851 /* The application requested we draw using a range of indices that's 852 * outside the bounds of the current VBO. This is invalid and appears 853 * to give undefined results. The safest thing to do is to simply 854 * ignore the range, in case the application botched their range tracking 855 * but did provide valid indices. Also issue a warning indicating that 856 * the application is broken. 857 */ 858 if (warnCount++ < 10) { 859 _mesa_warning(ctx, "glDrawRangeElements(start %u, end %u, " 860 "basevertex %d, count %d, type 0x%x, indices=%p):\n" 861 "\trange is outside VBO bounds (max=%u); ignoring.\n" 862 "\tThis should be fixed in the application.", 863 start, end, basevertex, count, type, indices, 864 max_element - 1); 865 } 866 index_bounds_valid = GL_FALSE; 867 } 868 869 /* NOTE: It's important that 'end' is a reasonable value. 870 * in _tnl_draw_prims(), we use end to determine how many vertices 871 * to transform. If it's too large, we can unnecessarily split prims 872 * or we can read/write out of memory in several different places! 873 */ 874 875 /* Catch/fix some potential user errors */ 876 if (type == GL_UNSIGNED_BYTE) { 877 start = MIN2(start, 0xff); 878 end = MIN2(end, 0xff); 879 } 880 else if (type == GL_UNSIGNED_SHORT) { 881 start = MIN2(start, 0xffff); 882 end = MIN2(end, 0xffff); 883 } 884 885 if (0) { 886 printf("glDraw[Range]Elements{,BaseVertex}" 887 "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, " 888 "base %d\n", 889 start, end, type, count, 890 ctx->Array.VAO->IndexBufferObj->Name, basevertex); 891 } 892 893 if ((int) start + basevertex < 0 || end + basevertex >= max_element) 894 index_bounds_valid = GL_FALSE; 895 896 #if 0 897 check_draw_elements_data(ctx, count, type, indices, basevertex); 898 #else 899 (void) check_draw_elements_data; 900 #endif 901 902 vbo_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end, 903 count, type, indices, basevertex, 1, 0); 904 } 905 906 907 /** 908 * Called by glDrawRangeElements() in immediate mode. 909 */ 910 static void GLAPIENTRY 911 vbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end, 912 GLsizei count, GLenum type, const GLvoid * indices) 913 { 914 if (MESA_VERBOSE & VERBOSE_DRAW) { 915 GET_CURRENT_CONTEXT(ctx); 916 _mesa_debug(ctx, 917 "glDrawRangeElements(%s, %u, %u, %d, %s, %p)\n", 918 _mesa_enum_to_string(mode), start, end, count, 919 _mesa_enum_to_string(type), indices); 920 } 921 922 vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type, 923 indices, 0); 924 } 925 926 927 /** 928 * Called by glDrawElements() in immediate mode. 929 */ 930 static void GLAPIENTRY 931 vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, 932 const GLvoid * indices) 933 { 934 GET_CURRENT_CONTEXT(ctx); 935 936 if (MESA_VERBOSE & VERBOSE_DRAW) 937 _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n", 938 _mesa_enum_to_string(mode), count, 939 _mesa_enum_to_string(type), indices); 940 941 if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices)) 942 return; 943 944 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, 945 count, type, indices, 0, 1, 0); 946 } 947 948 949 /** 950 * Called by glDrawElementsBaseVertex() in immediate mode. 951 */ 952 static void GLAPIENTRY 953 vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, 954 const GLvoid * indices, GLint basevertex) 955 { 956 GET_CURRENT_CONTEXT(ctx); 957 958 if (MESA_VERBOSE & VERBOSE_DRAW) 959 _mesa_debug(ctx, "glDrawElementsBaseVertex(%s, %d, %s, %p, %d)\n", 960 _mesa_enum_to_string(mode), count, 961 _mesa_enum_to_string(type), indices, basevertex); 962 963 if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices)) 964 return; 965 966 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, 967 count, type, indices, basevertex, 1, 0); 968 } 969 970 971 /** 972 * Called by glDrawElementsInstanced() in immediate mode. 973 */ 974 static void GLAPIENTRY 975 vbo_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, 976 const GLvoid * indices, GLsizei numInstances) 977 { 978 GET_CURRENT_CONTEXT(ctx); 979 980 if (MESA_VERBOSE & VERBOSE_DRAW) 981 _mesa_debug(ctx, "glDrawElementsInstanced(%s, %d, %s, %p, %d)\n", 982 _mesa_enum_to_string(mode), count, 983 _mesa_enum_to_string(type), indices, numInstances); 984 985 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, 986 numInstances)) 987 return; 988 989 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, 990 count, type, indices, 0, numInstances, 0); 991 } 992 993 994 /** 995 * Called by glDrawElementsInstancedBaseVertex() in immediate mode. 996 */ 997 static void GLAPIENTRY 998 vbo_exec_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, 999 GLenum type, const GLvoid * indices, 1000 GLsizei numInstances, 1001 GLint basevertex) 1002 { 1003 GET_CURRENT_CONTEXT(ctx); 1004 1005 if (MESA_VERBOSE & VERBOSE_DRAW) 1006 _mesa_debug(ctx, 1007 "glDrawElementsInstancedBaseVertex(%s, %d, %s, %p, %d; %d)\n", 1008 _mesa_enum_to_string(mode), count, 1009 _mesa_enum_to_string(type), indices, 1010 numInstances, basevertex); 1011 1012 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, 1013 numInstances)) 1014 return; 1015 1016 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, 1017 count, type, indices, 1018 basevertex, numInstances, 0); 1019 } 1020 1021 1022 /** 1023 * Called by glDrawElementsInstancedBaseInstance() in immediate mode. 1024 */ 1025 static void GLAPIENTRY 1026 vbo_exec_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, 1027 GLenum type, 1028 const GLvoid *indices, 1029 GLsizei numInstances, 1030 GLuint baseInstance) 1031 { 1032 GET_CURRENT_CONTEXT(ctx); 1033 1034 if (MESA_VERBOSE & VERBOSE_DRAW) 1035 _mesa_debug(ctx, 1036 "glDrawElementsInstancedBaseInstance" 1037 "(%s, %d, %s, %p, %d, %d)\n", 1038 _mesa_enum_to_string(mode), count, 1039 _mesa_enum_to_string(type), indices, 1040 numInstances, baseInstance); 1041 1042 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, 1043 numInstances)) 1044 return; 1045 1046 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, 1047 count, type, indices, 0, numInstances, 1048 baseInstance); 1049 } 1050 1051 1052 /** 1053 * Called by glDrawElementsInstancedBaseVertexBaseInstance() in immediate mode. 1054 */ 1055 static void GLAPIENTRY 1056 vbo_exec_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, 1057 GLsizei count, 1058 GLenum type, 1059 const GLvoid *indices, 1060 GLsizei numInstances, 1061 GLint basevertex, 1062 GLuint baseInstance) 1063 { 1064 GET_CURRENT_CONTEXT(ctx); 1065 1066 if (MESA_VERBOSE & VERBOSE_DRAW) 1067 _mesa_debug(ctx, 1068 "glDrawElementsInstancedBaseVertexBaseInstance" 1069 "(%s, %d, %s, %p, %d, %d, %d)\n", 1070 _mesa_enum_to_string(mode), count, 1071 _mesa_enum_to_string(type), indices, 1072 numInstances, basevertex, baseInstance); 1073 1074 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, 1075 numInstances)) 1076 return; 1077 1078 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, 1079 count, type, indices, basevertex, 1080 numInstances, baseInstance); 1081 } 1082 1083 1084 /** 1085 * Inner support for both _mesa_MultiDrawElements() and 1086 * _mesa_MultiDrawRangeElements(). 1087 * This does the actual rendering after we've checked array indexes, etc. 1088 */ 1089 static void 1090 vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, 1091 const GLsizei *count, GLenum type, 1092 const GLvoid * const *indices, 1093 GLsizei primcount, const GLint *basevertex) 1094 { 1095 struct vbo_context *vbo = vbo_context(ctx); 1096 struct _mesa_index_buffer ib; 1097 struct _mesa_prim *prim; 1098 unsigned int index_type_size = vbo_sizeof_ib_type(type); 1099 uintptr_t min_index_ptr, max_index_ptr; 1100 GLboolean fallback = GL_FALSE; 1101 int i; 1102 1103 if (primcount == 0) 1104 return; 1105 1106 prim = calloc(primcount, sizeof(*prim)); 1107 if (prim == NULL) { 1108 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements"); 1109 return; 1110 } 1111 1112 vbo_bind_arrays(ctx); 1113 1114 min_index_ptr = (uintptr_t) indices[0]; 1115 max_index_ptr = 0; 1116 for (i = 0; i < primcount; i++) { 1117 min_index_ptr = MIN2(min_index_ptr, (uintptr_t) indices[i]); 1118 max_index_ptr = MAX2(max_index_ptr, (uintptr_t) indices[i] + 1119 index_type_size * count[i]); 1120 } 1121 1122 /* Check if we can handle this thing as a bunch of index offsets from the 1123 * same index pointer. If we can't, then we have to fall back to doing 1124 * a draw_prims per primitive. 1125 * Check that the difference between each prim's indexes is a multiple of 1126 * the index/element size. 1127 */ 1128 if (index_type_size != 1) { 1129 for (i = 0; i < primcount; i++) { 1130 if ((((uintptr_t) indices[i] - min_index_ptr) % index_type_size) != 1131 0) { 1132 fallback = GL_TRUE; 1133 break; 1134 } 1135 } 1136 } 1137 1138 /* Draw primitives individually if one count is zero, so we can easily skip 1139 * that primitive. 1140 */ 1141 for (i = 0; i < primcount; i++) { 1142 if (count[i] == 0) { 1143 fallback = GL_TRUE; 1144 break; 1145 } 1146 } 1147 1148 /* If the index buffer isn't in a VBO, then treating the application's 1149 * subranges of the index buffer as one large index buffer may lead to 1150 * us reading unmapped memory. 1151 */ 1152 if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) 1153 fallback = GL_TRUE; 1154 1155 if (!fallback) { 1156 ib.count = (max_index_ptr - min_index_ptr) / index_type_size; 1157 ib.type = type; 1158 ib.obj = ctx->Array.VAO->IndexBufferObj; 1159 ib.ptr = (void *) min_index_ptr; 1160 1161 for (i = 0; i < primcount; i++) { 1162 prim[i].begin = (i == 0); 1163 prim[i].end = (i == primcount - 1); 1164 prim[i].weak = 0; 1165 prim[i].pad = 0; 1166 prim[i].mode = mode; 1167 prim[i].start = 1168 ((uintptr_t) indices[i] - min_index_ptr) / index_type_size; 1169 prim[i].count = count[i]; 1170 prim[i].indexed = 1; 1171 prim[i].num_instances = 1; 1172 prim[i].base_instance = 0; 1173 prim[i].draw_id = i; 1174 prim[i].is_indirect = 0; 1175 if (basevertex != NULL) 1176 prim[i].basevertex = basevertex[i]; 1177 else 1178 prim[i].basevertex = 0; 1179 } 1180 1181 vbo->draw_prims(ctx, prim, primcount, &ib, 1182 false, ~0, ~0, NULL, 0, NULL); 1183 } 1184 else { 1185 /* render one prim at a time */ 1186 for (i = 0; i < primcount; i++) { 1187 if (count[i] == 0) 1188 continue; 1189 ib.count = count[i]; 1190 ib.type = type; 1191 ib.obj = ctx->Array.VAO->IndexBufferObj; 1192 ib.ptr = indices[i]; 1193 1194 prim[0].begin = 1; 1195 prim[0].end = 1; 1196 prim[0].weak = 0; 1197 prim[0].pad = 0; 1198 prim[0].mode = mode; 1199 prim[0].start = 0; 1200 prim[0].count = count[i]; 1201 prim[0].indexed = 1; 1202 prim[0].num_instances = 1; 1203 prim[0].base_instance = 0; 1204 prim[0].draw_id = i; 1205 prim[0].is_indirect = 0; 1206 if (basevertex != NULL) 1207 prim[0].basevertex = basevertex[i]; 1208 else 1209 prim[0].basevertex = 0; 1210 1211 vbo->draw_prims(ctx, prim, 1, &ib, false, ~0, ~0, NULL, 0, NULL); 1212 } 1213 } 1214 1215 free(prim); 1216 1217 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 1218 _mesa_flush(ctx); 1219 } 1220 } 1221 1222 1223 static void GLAPIENTRY 1224 vbo_exec_MultiDrawElements(GLenum mode, 1225 const GLsizei *count, GLenum type, 1226 const GLvoid * const *indices, GLsizei primcount) 1227 { 1228 GET_CURRENT_CONTEXT(ctx); 1229 1230 if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices, 1231 primcount)) 1232 return; 1233 1234 vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount, 1235 NULL); 1236 } 1237 1238 1239 static void GLAPIENTRY 1240 vbo_exec_MultiDrawElementsBaseVertex(GLenum mode, 1241 const GLsizei *count, GLenum type, 1242 const GLvoid * const *indices, 1243 GLsizei primcount, 1244 const GLsizei *basevertex) 1245 { 1246 GET_CURRENT_CONTEXT(ctx); 1247 1248 if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices, 1249 primcount)) 1250 return; 1251 1252 vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount, 1253 basevertex); 1254 } 1255 1256 1257 static void 1258 vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode, 1259 struct gl_transform_feedback_object *obj, 1260 GLuint stream, GLuint numInstances) 1261 { 1262 struct vbo_context *vbo = vbo_context(ctx); 1263 struct _mesa_prim prim[2]; 1264 1265 if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream, 1266 numInstances)) { 1267 return; 1268 } 1269 1270 if (ctx->Driver.GetTransformFeedbackVertexCount && 1271 (ctx->Const.AlwaysUseGetTransformFeedbackVertexCount || 1272 !_mesa_all_varyings_in_vbos(ctx->Array.VAO))) { 1273 GLsizei n = 1274 ctx->Driver.GetTransformFeedbackVertexCount(ctx, obj, stream); 1275 vbo_draw_arrays(ctx, mode, 0, n, numInstances, 0); 1276 return; 1277 } 1278 1279 vbo_bind_arrays(ctx); 1280 1281 /* init most fields to zero */ 1282 memset(prim, 0, sizeof(prim)); 1283 prim[0].begin = 1; 1284 prim[0].end = 1; 1285 prim[0].mode = mode; 1286 prim[0].num_instances = numInstances; 1287 prim[0].base_instance = 0; 1288 prim[0].is_indirect = 0; 1289 1290 /* Maybe we should do some primitive splitting for primitive restart 1291 * (like in DrawArrays), but we have no way to know how many vertices 1292 * will be rendered. */ 1293 1294 vbo->draw_prims(ctx, prim, 1, NULL, GL_FALSE, ~0, ~0, obj, stream, NULL); 1295 1296 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 1297 _mesa_flush(ctx); 1298 } 1299 } 1300 1301 1302 /** 1303 * Like DrawArrays, but take the count from a transform feedback object. 1304 * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc. 1305 * \param name the transform feedback object 1306 * User still has to setup of the vertex attribute info with 1307 * glVertexPointer, glColorPointer, etc. 1308 * Part of GL_ARB_transform_feedback2. 1309 */ 1310 static void GLAPIENTRY 1311 vbo_exec_DrawTransformFeedback(GLenum mode, GLuint name) 1312 { 1313 GET_CURRENT_CONTEXT(ctx); 1314 struct gl_transform_feedback_object *obj = 1315 _mesa_lookup_transform_feedback_object(ctx, name); 1316 1317 if (MESA_VERBOSE & VERBOSE_DRAW) 1318 _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n", 1319 _mesa_enum_to_string(mode), name); 1320 1321 vbo_draw_transform_feedback(ctx, mode, obj, 0, 1); 1322 } 1323 1324 1325 static void GLAPIENTRY 1326 vbo_exec_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream) 1327 { 1328 GET_CURRENT_CONTEXT(ctx); 1329 struct gl_transform_feedback_object *obj = 1330 _mesa_lookup_transform_feedback_object(ctx, name); 1331 1332 if (MESA_VERBOSE & VERBOSE_DRAW) 1333 _mesa_debug(ctx, "glDrawTransformFeedbackStream(%s, %u, %u)\n", 1334 _mesa_enum_to_string(mode), name, stream); 1335 1336 vbo_draw_transform_feedback(ctx, mode, obj, stream, 1); 1337 } 1338 1339 1340 static void GLAPIENTRY 1341 vbo_exec_DrawTransformFeedbackInstanced(GLenum mode, GLuint name, 1342 GLsizei primcount) 1343 { 1344 GET_CURRENT_CONTEXT(ctx); 1345 struct gl_transform_feedback_object *obj = 1346 _mesa_lookup_transform_feedback_object(ctx, name); 1347 1348 if (MESA_VERBOSE & VERBOSE_DRAW) 1349 _mesa_debug(ctx, "glDrawTransformFeedbackInstanced(%s, %d)\n", 1350 _mesa_enum_to_string(mode), name); 1351 1352 vbo_draw_transform_feedback(ctx, mode, obj, 0, primcount); 1353 } 1354 1355 1356 static void GLAPIENTRY 1357 vbo_exec_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name, 1358 GLuint stream, 1359 GLsizei primcount) 1360 { 1361 GET_CURRENT_CONTEXT(ctx); 1362 struct gl_transform_feedback_object *obj = 1363 _mesa_lookup_transform_feedback_object(ctx, name); 1364 1365 if (MESA_VERBOSE & VERBOSE_DRAW) 1366 _mesa_debug(ctx, "glDrawTransformFeedbackStreamInstanced" 1367 "(%s, %u, %u, %i)\n", 1368 _mesa_enum_to_string(mode), name, stream, primcount); 1369 1370 vbo_draw_transform_feedback(ctx, mode, obj, stream, primcount); 1371 } 1372 1373 1374 static void 1375 vbo_validated_drawarraysindirect(struct gl_context *ctx, 1376 GLenum mode, const GLvoid *indirect) 1377 { 1378 struct vbo_context *vbo = vbo_context(ctx); 1379 1380 vbo_bind_arrays(ctx); 1381 1382 vbo->draw_indirect_prims(ctx, mode, 1383 ctx->DrawIndirectBuffer, (GLsizeiptr) indirect, 1384 1 /* draw_count */ , 16 /* stride */ , 1385 NULL, 0, NULL); 1386 1387 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) 1388 _mesa_flush(ctx); 1389 } 1390 1391 1392 static void 1393 vbo_validated_multidrawarraysindirect(struct gl_context *ctx, 1394 GLenum mode, 1395 const GLvoid *indirect, 1396 GLsizei primcount, GLsizei stride) 1397 { 1398 struct vbo_context *vbo = vbo_context(ctx); 1399 GLsizeiptr offset = (GLsizeiptr) indirect; 1400 1401 if (primcount == 0) 1402 return; 1403 1404 vbo_bind_arrays(ctx); 1405 1406 vbo->draw_indirect_prims(ctx, mode, ctx->DrawIndirectBuffer, offset, 1407 primcount, stride, NULL, 0, NULL); 1408 1409 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) 1410 _mesa_flush(ctx); 1411 } 1412 1413 1414 static void 1415 vbo_validated_drawelementsindirect(struct gl_context *ctx, 1416 GLenum mode, GLenum type, 1417 const GLvoid *indirect) 1418 { 1419 struct vbo_context *vbo = vbo_context(ctx); 1420 struct _mesa_index_buffer ib; 1421 1422 vbo_bind_arrays(ctx); 1423 1424 ib.count = 0; /* unknown */ 1425 ib.type = type; 1426 ib.obj = ctx->Array.VAO->IndexBufferObj; 1427 ib.ptr = NULL; 1428 1429 vbo->draw_indirect_prims(ctx, mode, 1430 ctx->DrawIndirectBuffer, (GLsizeiptr) indirect, 1431 1 /* draw_count */ , 20 /* stride */ , 1432 NULL, 0, &ib); 1433 1434 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) 1435 _mesa_flush(ctx); 1436 } 1437 1438 1439 static void 1440 vbo_validated_multidrawelementsindirect(struct gl_context *ctx, 1441 GLenum mode, GLenum type, 1442 const GLvoid *indirect, 1443 GLsizei primcount, GLsizei stride) 1444 { 1445 struct vbo_context *vbo = vbo_context(ctx); 1446 struct _mesa_index_buffer ib; 1447 GLsizeiptr offset = (GLsizeiptr) indirect; 1448 1449 if (primcount == 0) 1450 return; 1451 1452 vbo_bind_arrays(ctx); 1453 1454 /* NOTE: IndexBufferObj is guaranteed to be a VBO. */ 1455 1456 ib.count = 0; /* unknown */ 1457 ib.type = type; 1458 ib.obj = ctx->Array.VAO->IndexBufferObj; 1459 ib.ptr = NULL; 1460 1461 vbo->draw_indirect_prims(ctx, mode, 1462 ctx->DrawIndirectBuffer, offset, 1463 primcount, stride, NULL, 0, &ib); 1464 1465 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) 1466 _mesa_flush(ctx); 1467 } 1468 1469 1470 /** 1471 * Like [Multi]DrawArrays/Elements, but they take most arguments from 1472 * a buffer object. 1473 */ 1474 static void GLAPIENTRY 1475 vbo_exec_DrawArraysIndirect(GLenum mode, const GLvoid *indirect) 1476 { 1477 GET_CURRENT_CONTEXT(ctx); 1478 1479 if (MESA_VERBOSE & VERBOSE_DRAW) 1480 _mesa_debug(ctx, "glDrawArraysIndirect(%s, %p)\n", 1481 _mesa_enum_to_string(mode), indirect); 1482 1483 if (!_mesa_validate_DrawArraysIndirect(ctx, mode, indirect)) 1484 return; 1485 1486 vbo_validated_drawarraysindirect(ctx, mode, indirect); 1487 } 1488 1489 1490 static void GLAPIENTRY 1491 vbo_exec_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect) 1492 { 1493 GET_CURRENT_CONTEXT(ctx); 1494 1495 if (MESA_VERBOSE & VERBOSE_DRAW) 1496 _mesa_debug(ctx, "glDrawElementsIndirect(%s, %s, %p)\n", 1497 _mesa_enum_to_string(mode), 1498 _mesa_enum_to_string(type), indirect); 1499 1500 if (!_mesa_validate_DrawElementsIndirect(ctx, mode, type, indirect)) 1501 return; 1502 1503 vbo_validated_drawelementsindirect(ctx, mode, type, indirect); 1504 } 1505 1506 1507 static void GLAPIENTRY 1508 vbo_exec_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect, 1509 GLsizei primcount, GLsizei stride) 1510 { 1511 GET_CURRENT_CONTEXT(ctx); 1512 1513 if (MESA_VERBOSE & VERBOSE_DRAW) 1514 _mesa_debug(ctx, "glMultiDrawArraysIndirect(%s, %p, %i, %i)\n", 1515 _mesa_enum_to_string(mode), indirect, primcount, stride); 1516 1517 /* If <stride> is zero, the array elements are treated as tightly packed. */ 1518 if (stride == 0) 1519 stride = 4 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */ 1520 1521 if (!_mesa_validate_MultiDrawArraysIndirect(ctx, mode, indirect, 1522 primcount, stride)) 1523 return; 1524 1525 vbo_validated_multidrawarraysindirect(ctx, mode, indirect, 1526 primcount, stride); 1527 } 1528 1529 1530 static void GLAPIENTRY 1531 vbo_exec_MultiDrawElementsIndirect(GLenum mode, GLenum type, 1532 const GLvoid *indirect, 1533 GLsizei primcount, GLsizei stride) 1534 { 1535 GET_CURRENT_CONTEXT(ctx); 1536 1537 if (MESA_VERBOSE & VERBOSE_DRAW) 1538 _mesa_debug(ctx, "glMultiDrawElementsIndirect(%s, %s, %p, %i, %i)\n", 1539 _mesa_enum_to_string(mode), 1540 _mesa_enum_to_string(type), indirect, primcount, stride); 1541 1542 /* If <stride> is zero, the array elements are treated as tightly packed. */ 1543 if (stride == 0) 1544 stride = 5 * sizeof(GLuint); /* sizeof(DrawElementsIndirectCommand) */ 1545 1546 if (!_mesa_validate_MultiDrawElementsIndirect(ctx, mode, type, indirect, 1547 primcount, stride)) 1548 return; 1549 1550 vbo_validated_multidrawelementsindirect(ctx, mode, type, indirect, 1551 primcount, stride); 1552 } 1553 1554 1555 static void 1556 vbo_validated_multidrawarraysindirectcount(struct gl_context *ctx, 1557 GLenum mode, 1558 GLintptr indirect, 1559 GLintptr drawcount, 1560 GLsizei maxdrawcount, 1561 GLsizei stride) 1562 { 1563 struct vbo_context *vbo = vbo_context(ctx); 1564 GLsizeiptr offset = indirect; 1565 1566 if (maxdrawcount == 0) 1567 return; 1568 1569 vbo_bind_arrays(ctx); 1570 1571 vbo->draw_indirect_prims(ctx, mode, 1572 ctx->DrawIndirectBuffer, offset, 1573 maxdrawcount, stride, 1574 ctx->ParameterBuffer, drawcount, NULL); 1575 1576 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) 1577 _mesa_flush(ctx); 1578 } 1579 1580 1581 static void 1582 vbo_validated_multidrawelementsindirectcount(struct gl_context *ctx, 1583 GLenum mode, GLenum type, 1584 GLintptr indirect, 1585 GLintptr drawcount, 1586 GLsizei maxdrawcount, 1587 GLsizei stride) 1588 { 1589 struct vbo_context *vbo = vbo_context(ctx); 1590 struct _mesa_index_buffer ib; 1591 GLsizeiptr offset = (GLsizeiptr) indirect; 1592 1593 if (maxdrawcount == 0) 1594 return; 1595 1596 vbo_bind_arrays(ctx); 1597 1598 /* NOTE: IndexBufferObj is guaranteed to be a VBO. */ 1599 1600 ib.count = 0; /* unknown */ 1601 ib.type = type; 1602 ib.obj = ctx->Array.VAO->IndexBufferObj; 1603 ib.ptr = NULL; 1604 1605 vbo->draw_indirect_prims(ctx, mode, 1606 ctx->DrawIndirectBuffer, offset, 1607 maxdrawcount, stride, 1608 ctx->ParameterBuffer, drawcount, &ib); 1609 1610 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) 1611 _mesa_flush(ctx); 1612 } 1613 1614 1615 static void GLAPIENTRY 1616 vbo_exec_MultiDrawArraysIndirectCount(GLenum mode, GLintptr indirect, 1617 GLintptr drawcount, 1618 GLsizei maxdrawcount, GLsizei stride) 1619 { 1620 GET_CURRENT_CONTEXT(ctx); 1621 1622 if (MESA_VERBOSE & VERBOSE_DRAW) 1623 _mesa_debug(ctx, "glMultiDrawArraysIndirectCountARB" 1624 "(%s, %lx, %lx, %i, %i)\n", 1625 _mesa_enum_to_string(mode), 1626 (unsigned long) indirect, (unsigned long) drawcount, 1627 maxdrawcount, stride); 1628 1629 /* If <stride> is zero, the array elements are treated as tightly packed. */ 1630 if (stride == 0) 1631 stride = 4 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */ 1632 1633 if (!_mesa_validate_MultiDrawArraysIndirectCount(ctx, mode, 1634 indirect, drawcount, 1635 maxdrawcount, stride)) 1636 return; 1637 1638 vbo_validated_multidrawarraysindirectcount(ctx, mode, indirect, drawcount, 1639 maxdrawcount, stride); 1640 } 1641 1642 1643 static void GLAPIENTRY 1644 vbo_exec_MultiDrawElementsIndirectCount(GLenum mode, GLenum type, 1645 GLintptr indirect, GLintptr drawcount, 1646 GLsizei maxdrawcount, GLsizei stride) 1647 { 1648 GET_CURRENT_CONTEXT(ctx); 1649 1650 if (MESA_VERBOSE & VERBOSE_DRAW) 1651 _mesa_debug(ctx, "glMultiDrawElementsIndirectCountARB" 1652 "(%s, %s, %lx, %lx, %i, %i)\n", 1653 _mesa_enum_to_string(mode), _mesa_enum_to_string(type), 1654 (unsigned long) indirect, (unsigned long) drawcount, 1655 maxdrawcount, stride); 1656 1657 /* If <stride> is zero, the array elements are treated as tightly packed. */ 1658 if (stride == 0) 1659 stride = 5 * sizeof(GLuint); /* sizeof(DrawElementsIndirectCommand) */ 1660 1661 if (!_mesa_validate_MultiDrawElementsIndirectCount(ctx, mode, type, 1662 indirect, drawcount, 1663 maxdrawcount, stride)) 1664 return; 1665 1666 vbo_validated_multidrawelementsindirectcount(ctx, mode, type, indirect, 1667 drawcount, maxdrawcount, 1668 stride); 1669 } 1670 1671 1672 /** 1673 * Initialize the dispatch table with the VBO functions for drawing. 1674 */ 1675 void 1676 vbo_initialize_exec_dispatch(const struct gl_context *ctx, 1677 struct _glapi_table *exec) 1678 { 1679 SET_DrawArrays(exec, vbo_exec_DrawArrays); 1680 SET_DrawElements(exec, vbo_exec_DrawElements); 1681 1682 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { 1683 SET_DrawRangeElements(exec, vbo_exec_DrawRangeElements); 1684 } 1685 1686 SET_MultiDrawElementsEXT(exec, vbo_exec_MultiDrawElements); 1687 1688 if (ctx->API == API_OPENGL_COMPAT) { 1689 SET_Rectf(exec, vbo_exec_Rectf); 1690 SET_EvalMesh1(exec, vbo_exec_EvalMesh1); 1691 SET_EvalMesh2(exec, vbo_exec_EvalMesh2); 1692 } 1693 1694 if (ctx->API != API_OPENGLES && 1695 ctx->Extensions.ARB_draw_elements_base_vertex) { 1696 SET_DrawElementsBaseVertex(exec, vbo_exec_DrawElementsBaseVertex); 1697 SET_MultiDrawElementsBaseVertex(exec, 1698 vbo_exec_MultiDrawElementsBaseVertex); 1699 1700 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { 1701 SET_DrawRangeElementsBaseVertex(exec, 1702 vbo_exec_DrawRangeElementsBaseVertex); 1703 SET_DrawElementsInstancedBaseVertex(exec, 1704 vbo_exec_DrawElementsInstancedBaseVertex); 1705 } 1706 } 1707 1708 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { 1709 SET_DrawArraysInstancedBaseInstance(exec, 1710 vbo_exec_DrawArraysInstancedBaseInstance); 1711 SET_DrawElementsInstancedBaseInstance(exec, 1712 vbo_exec_DrawElementsInstancedBaseInstance); 1713 SET_DrawElementsInstancedBaseVertexBaseInstance(exec, 1714 vbo_exec_DrawElementsInstancedBaseVertexBaseInstance); 1715 } 1716 1717 if (ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) { 1718 SET_DrawArraysIndirect(exec, vbo_exec_DrawArraysIndirect); 1719 SET_DrawElementsIndirect(exec, vbo_exec_DrawElementsIndirect); 1720 } 1721 1722 if (ctx->API == API_OPENGL_CORE) { 1723 SET_MultiDrawArraysIndirect(exec, vbo_exec_MultiDrawArraysIndirect); 1724 SET_MultiDrawElementsIndirect(exec, vbo_exec_MultiDrawElementsIndirect); 1725 SET_MultiDrawArraysIndirectCountARB(exec, 1726 vbo_exec_MultiDrawArraysIndirectCount); 1727 SET_MultiDrawElementsIndirectCountARB(exec, 1728 vbo_exec_MultiDrawElementsIndirectCount); 1729 } 1730 1731 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { 1732 SET_DrawArraysInstancedARB(exec, vbo_exec_DrawArraysInstanced); 1733 SET_DrawElementsInstancedARB(exec, vbo_exec_DrawElementsInstanced); 1734 } 1735 1736 if (_mesa_is_desktop_gl(ctx)) { 1737 SET_DrawTransformFeedback(exec, vbo_exec_DrawTransformFeedback); 1738 SET_DrawTransformFeedbackStream(exec, 1739 vbo_exec_DrawTransformFeedbackStream); 1740 SET_DrawTransformFeedbackInstanced(exec, 1741 vbo_exec_DrawTransformFeedbackInstanced); 1742 SET_DrawTransformFeedbackStreamInstanced(exec, 1743 vbo_exec_DrawTransformFeedbackStreamInstanced); 1744 } 1745 } 1746 1747 1748 1749 /** 1750 * The following functions are only used for OpenGL ES 1/2 support. 1751 * And some aren't even supported (yet) in ES 1/2. 1752 */ 1753 1754 1755 void GLAPIENTRY 1756 _mesa_DrawArrays(GLenum mode, GLint first, GLsizei count) 1757 { 1758 vbo_exec_DrawArrays(mode, first, count); 1759 } 1760 1761 1762 void GLAPIENTRY 1763 _mesa_DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, 1764 GLsizei primcount) 1765 { 1766 vbo_exec_DrawArraysInstanced(mode, first, count, primcount); 1767 } 1768 1769 1770 void GLAPIENTRY 1771 _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, 1772 const GLvoid *indices) 1773 { 1774 vbo_exec_DrawElements(mode, count, type, indices); 1775 } 1776 1777 1778 void GLAPIENTRY 1779 _mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, 1780 const GLvoid *indices, GLint basevertex) 1781 { 1782 vbo_exec_DrawElementsBaseVertex(mode, count, type, indices, basevertex); 1783 } 1784 1785 1786 void GLAPIENTRY 1787 _mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, 1788 GLenum type, const GLvoid * indices) 1789 { 1790 vbo_exec_DrawRangeElements(mode, start, end, count, type, indices); 1791 } 1792 1793 1794 void GLAPIENTRY 1795 _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, 1796 GLsizei count, GLenum type, 1797 const GLvoid *indices, GLint basevertex) 1798 { 1799 vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type, 1800 indices, basevertex); 1801 } 1802 1803 1804 void GLAPIENTRY 1805 _mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type, 1806 const GLvoid ** indices, GLsizei primcount) 1807 { 1808 vbo_exec_MultiDrawElements(mode, count, type, indices, primcount); 1809 } 1810 1811 1812 void GLAPIENTRY 1813 _mesa_MultiDrawElementsBaseVertex(GLenum mode, 1814 const GLsizei *count, GLenum type, 1815 const GLvoid **indices, GLsizei primcount, 1816 const GLint *basevertex) 1817 { 1818 vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices, 1819 primcount, basevertex); 1820 } 1821 1822 1823 void GLAPIENTRY 1824 _mesa_DrawTransformFeedback(GLenum mode, GLuint name) 1825 { 1826 vbo_exec_DrawTransformFeedback(mode, name); 1827 } 1828