1/************************************************************************** 2 * 3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 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 TUNGSTEN GRAPHICS 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 "main/glheader.h" 30#include "main/context.h" 31#include "main/state.h" 32#include "main/api_validate.h" 33#include "main/varray.h" 34#include "main/bufferobj.h" 35#include "main/enums.h" 36#include "main/macros.h" 37#include "main/transformfeedback.h" 38 39#include "vbo_context.h" 40 41 42/** 43 * All vertex buffers should be in an unmapped state when we're about 44 * to draw. This debug function checks that. 45 */ 46static void 47check_buffers_are_unmapped(const struct gl_client_array **inputs) 48{ 49#ifdef DEBUG 50 GLuint i; 51 52 for (i = 0; i < VERT_ATTRIB_MAX; i++) { 53 if (inputs[i]) { 54 struct gl_buffer_object *obj = inputs[i]->BufferObj; 55 assert(!_mesa_bufferobj_mapped(obj)); 56 (void) obj; 57 } 58 } 59#endif 60} 61 62 63/** 64 * A debug function that may be called from other parts of Mesa as 65 * needed during debugging. 66 */ 67void 68vbo_check_buffers_are_unmapped(struct gl_context *ctx) 69{ 70 struct vbo_context *vbo = vbo_context(ctx); 71 struct vbo_exec_context *exec = &vbo->exec; 72 /* check the current vertex arrays */ 73 check_buffers_are_unmapped(exec->array.inputs); 74 /* check the current glBegin/glVertex/glEnd-style VBO */ 75 assert(!_mesa_bufferobj_mapped(exec->vtx.bufferobj)); 76} 77 78 79 80/** 81 * Compute min and max elements by scanning the index buffer for 82 * glDraw[Range]Elements() calls. 83 * If primitive restart is enabled, we need to ignore restart 84 * indexes when computing min/max. 85 */ 86static void 87vbo_get_minmax_index(struct gl_context *ctx, 88 const struct _mesa_prim *prim, 89 const struct _mesa_index_buffer *ib, 90 GLuint *min_index, GLuint *max_index, 91 const GLuint count) 92{ 93 const GLboolean restart = ctx->Array.PrimitiveRestart; 94 const GLuint restartIndex = ctx->Array.RestartIndex; 95 const int index_size = vbo_sizeof_ib_type(ib->type); 96 const char *indices; 97 GLuint i; 98 99 indices = (char *) ib->ptr + prim->start * index_size; 100 if (_mesa_is_bufferobj(ib->obj)) { 101 GLsizeiptr size = MIN2(count * index_size, ib->obj->Size); 102 indices = ctx->Driver.MapBufferRange(ctx, (GLintptr) indices, size, 103 GL_MAP_READ_BIT, ib->obj); 104 } 105 106 switch (ib->type) { 107 case GL_UNSIGNED_INT: { 108 const GLuint *ui_indices = (const GLuint *)indices; 109 GLuint max_ui = 0; 110 GLuint min_ui = ~0U; 111 if (restart) { 112 for (i = 0; i < count; i++) { 113 if (ui_indices[i] != restartIndex) { 114 if (ui_indices[i] > max_ui) max_ui = ui_indices[i]; 115 if (ui_indices[i] < min_ui) min_ui = ui_indices[i]; 116 } 117 } 118 } 119 else { 120 for (i = 0; i < count; i++) { 121 if (ui_indices[i] > max_ui) max_ui = ui_indices[i]; 122 if (ui_indices[i] < min_ui) min_ui = ui_indices[i]; 123 } 124 } 125 *min_index = min_ui; 126 *max_index = max_ui; 127 break; 128 } 129 case GL_UNSIGNED_SHORT: { 130 const GLushort *us_indices = (const GLushort *)indices; 131 GLuint max_us = 0; 132 GLuint min_us = ~0U; 133 if (restart) { 134 for (i = 0; i < count; i++) { 135 if (us_indices[i] != restartIndex) { 136 if (us_indices[i] > max_us) max_us = us_indices[i]; 137 if (us_indices[i] < min_us) min_us = us_indices[i]; 138 } 139 } 140 } 141 else { 142 for (i = 0; i < count; i++) { 143 if (us_indices[i] > max_us) max_us = us_indices[i]; 144 if (us_indices[i] < min_us) min_us = us_indices[i]; 145 } 146 } 147 *min_index = min_us; 148 *max_index = max_us; 149 break; 150 } 151 case GL_UNSIGNED_BYTE: { 152 const GLubyte *ub_indices = (const GLubyte *)indices; 153 GLuint max_ub = 0; 154 GLuint min_ub = ~0U; 155 if (restart) { 156 for (i = 0; i < count; i++) { 157 if (ub_indices[i] != restartIndex) { 158 if (ub_indices[i] > max_ub) max_ub = ub_indices[i]; 159 if (ub_indices[i] < min_ub) min_ub = ub_indices[i]; 160 } 161 } 162 } 163 else { 164 for (i = 0; i < count; i++) { 165 if (ub_indices[i] > max_ub) max_ub = ub_indices[i]; 166 if (ub_indices[i] < min_ub) min_ub = ub_indices[i]; 167 } 168 } 169 *min_index = min_ub; 170 *max_index = max_ub; 171 break; 172 } 173 default: 174 assert(0); 175 break; 176 } 177 178 if (_mesa_is_bufferobj(ib->obj)) { 179 ctx->Driver.UnmapBuffer(ctx, ib->obj); 180 } 181} 182 183/** 184 * Compute min and max elements for nr_prims 185 */ 186void 187vbo_get_minmax_indices(struct gl_context *ctx, 188 const struct _mesa_prim *prims, 189 const struct _mesa_index_buffer *ib, 190 GLuint *min_index, 191 GLuint *max_index, 192 GLuint nr_prims) 193{ 194 GLuint tmp_min, tmp_max; 195 GLuint i; 196 GLuint count; 197 198 *min_index = ~0; 199 *max_index = 0; 200 201 for (i = 0; i < nr_prims; i++) { 202 const struct _mesa_prim *start_prim; 203 204 start_prim = &prims[i]; 205 count = start_prim->count; 206 /* Do combination if possible to reduce map/unmap count */ 207 while ((i + 1 < nr_prims) && 208 (prims[i].start + prims[i].count == prims[i+1].start)) { 209 count += prims[i+1].count; 210 i++; 211 } 212 vbo_get_minmax_index(ctx, start_prim, ib, &tmp_min, &tmp_max, count); 213 *min_index = MIN2(*min_index, tmp_min); 214 *max_index = MAX2(*max_index, tmp_max); 215 } 216} 217 218 219/** 220 * Check that element 'j' of the array has reasonable data. 221 * Map VBO if needed. 222 * For debugging purposes; not normally used. 223 */ 224static void 225check_array_data(struct gl_context *ctx, struct gl_client_array *array, 226 GLuint attrib, GLuint j) 227{ 228 if (array->Enabled) { 229 const void *data = array->Ptr; 230 if (_mesa_is_bufferobj(array->BufferObj)) { 231 if (!array->BufferObj->Pointer) { 232 /* need to map now */ 233 array->BufferObj->Pointer = 234 ctx->Driver.MapBufferRange(ctx, 0, array->BufferObj->Size, 235 GL_MAP_READ_BIT, array->BufferObj); 236 } 237 data = ADD_POINTERS(data, array->BufferObj->Pointer); 238 } 239 switch (array->Type) { 240 case GL_FLOAT: 241 { 242 GLfloat *f = (GLfloat *) ((GLubyte *) data + array->StrideB * j); 243 GLint k; 244 for (k = 0; k < array->Size; k++) { 245 if (IS_INF_OR_NAN(f[k]) || 246 f[k] >= 1.0e20 || f[k] <= -1.0e10) { 247 printf("Bad array data:\n"); 248 printf(" Element[%u].%u = %f\n", j, k, f[k]); 249 printf(" Array %u at %p\n", attrib, (void* ) array); 250 printf(" Type 0x%x, Size %d, Stride %d\n", 251 array->Type, array->Size, array->Stride); 252 printf(" Address/offset %p in Buffer Object %u\n", 253 array->Ptr, array->BufferObj->Name); 254 f[k] = 1.0; /* XXX replace the bad value! */ 255 } 256 /*assert(!IS_INF_OR_NAN(f[k]));*/ 257 } 258 } 259 break; 260 default: 261 ; 262 } 263 } 264} 265 266 267/** 268 * Unmap the buffer object referenced by given array, if mapped. 269 */ 270static void 271unmap_array_buffer(struct gl_context *ctx, struct gl_client_array *array) 272{ 273 if (array->Enabled && 274 _mesa_is_bufferobj(array->BufferObj) && 275 _mesa_bufferobj_mapped(array->BufferObj)) { 276 ctx->Driver.UnmapBuffer(ctx, array->BufferObj); 277 } 278} 279 280 281/** 282 * Examine the array's data for NaNs, etc. 283 * For debug purposes; not normally used. 284 */ 285static void 286check_draw_elements_data(struct gl_context *ctx, GLsizei count, GLenum elemType, 287 const void *elements, GLint basevertex) 288{ 289 struct gl_array_object *arrayObj = ctx->Array.ArrayObj; 290 const void *elemMap; 291 GLint i, k; 292 293 if (_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj)) { 294 elemMap = ctx->Driver.MapBufferRange(ctx, 0, 295 ctx->Array.ArrayObj->ElementArrayBufferObj->Size, 296 GL_MAP_READ_BIT, 297 ctx->Array.ArrayObj->ElementArrayBufferObj); 298 elements = ADD_POINTERS(elements, elemMap); 299 } 300 301 for (i = 0; i < count; i++) { 302 GLuint j; 303 304 /* j = element[i] */ 305 switch (elemType) { 306 case GL_UNSIGNED_BYTE: 307 j = ((const GLubyte *) elements)[i]; 308 break; 309 case GL_UNSIGNED_SHORT: 310 j = ((const GLushort *) elements)[i]; 311 break; 312 case GL_UNSIGNED_INT: 313 j = ((const GLuint *) elements)[i]; 314 break; 315 default: 316 assert(0); 317 } 318 319 /* check element j of each enabled array */ 320 for (k = 0; k < Elements(arrayObj->VertexAttrib); k++) { 321 check_array_data(ctx, &arrayObj->VertexAttrib[k], k, j); 322 } 323 } 324 325 if (_mesa_is_bufferobj(arrayObj->ElementArrayBufferObj)) { 326 ctx->Driver.UnmapBuffer(ctx, ctx->Array.ArrayObj->ElementArrayBufferObj); 327 } 328 329 for (k = 0; k < Elements(arrayObj->VertexAttrib); k++) { 330 unmap_array_buffer(ctx, &arrayObj->VertexAttrib[k]); 331 } 332} 333 334 335/** 336 * Check array data, looking for NaNs, etc. 337 */ 338static void 339check_draw_arrays_data(struct gl_context *ctx, GLint start, GLsizei count) 340{ 341 /* TO DO */ 342} 343 344 345/** 346 * Print info/data for glDrawArrays(), for debugging. 347 */ 348static void 349print_draw_arrays(struct gl_context *ctx, 350 GLenum mode, GLint start, GLsizei count) 351{ 352 struct vbo_context *vbo = vbo_context(ctx); 353 struct vbo_exec_context *exec = &vbo->exec; 354 struct gl_array_object *arrayObj = ctx->Array.ArrayObj; 355 int i; 356 357 printf("vbo_exec_DrawArrays(mode 0x%x, start %d, count %d):\n", 358 mode, start, count); 359 360 for (i = 0; i < 32; i++) { 361 struct gl_buffer_object *bufObj = exec->array.inputs[i]->BufferObj; 362 GLuint bufName = bufObj->Name; 363 GLint stride = exec->array.inputs[i]->Stride; 364 printf("attr %2d: size %d stride %d enabled %d " 365 "ptr %p Bufobj %u\n", 366 i, 367 exec->array.inputs[i]->Size, 368 stride, 369 /*exec->array.inputs[i]->Enabled,*/ 370 arrayObj->VertexAttrib[VERT_ATTRIB_FF(i)].Enabled, 371 exec->array.inputs[i]->Ptr, 372 bufName); 373 374 if (bufName) { 375 GLubyte *p = ctx->Driver.MapBufferRange(ctx, 0, bufObj->Size, 376 GL_MAP_READ_BIT, bufObj); 377 int offset = (int) (GLintptr) exec->array.inputs[i]->Ptr; 378 float *f = (float *) (p + offset); 379 int *k = (int *) f; 380 int i; 381 int n = (count * stride) / 4; 382 if (n > 32) 383 n = 32; 384 printf(" Data at offset %d:\n", offset); 385 for (i = 0; i < n; i++) { 386 printf(" float[%d] = 0x%08x %f\n", i, k[i], f[i]); 387 } 388 ctx->Driver.UnmapBuffer(ctx, bufObj); 389 } 390 } 391} 392 393 394/** 395 * Set the vbo->exec->inputs[] pointers to point to the enabled 396 * vertex arrays. This depends on the current vertex program/shader 397 * being executed because of whether or not generic vertex arrays 398 * alias the conventional vertex arrays. 399 * For arrays that aren't enabled, we set the input[attrib] pointer 400 * to point at a zero-stride current value "array". 401 */ 402static void 403recalculate_input_bindings(struct gl_context *ctx) 404{ 405 struct vbo_context *vbo = vbo_context(ctx); 406 struct vbo_exec_context *exec = &vbo->exec; 407 struct gl_client_array *vertexAttrib = ctx->Array.ArrayObj->VertexAttrib; 408 const struct gl_client_array **inputs = &exec->array.inputs[0]; 409 GLbitfield64 const_inputs = 0x0; 410 GLuint i; 411 412 switch (get_program_mode(ctx)) { 413 case VP_NONE: 414 /* When no vertex program is active (or the vertex program is generated 415 * from fixed-function state). We put the material values into the 416 * generic slots. This is the only situation where material values 417 * are available as per-vertex attributes. 418 */ 419 for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) { 420 if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled) 421 inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)]; 422 else { 423 inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i]; 424 const_inputs |= VERT_BIT(i); 425 } 426 } 427 428 for (i = 0; i < MAT_ATTRIB_MAX; i++) { 429 inputs[VERT_ATTRIB_GENERIC(i)] = 430 &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT+i]; 431 const_inputs |= VERT_BIT_GENERIC(i); 432 } 433 434 /* Could use just about anything, just to fill in the empty 435 * slots: 436 */ 437 for (i = MAT_ATTRIB_MAX; i < VERT_ATTRIB_GENERIC_MAX; i++) { 438 inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i]; 439 const_inputs |= VERT_BIT_GENERIC(i); 440 } 441 break; 442 443 case VP_NV: 444 /* NV_vertex_program - attribute arrays alias and override 445 * conventional, legacy arrays. No materials, and the generic 446 * slots are vacant. 447 */ 448 for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) { 449 if (i < VERT_ATTRIB_GENERIC_MAX 450 && vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled) 451 inputs[i] = &vertexAttrib[VERT_ATTRIB_GENERIC(i)]; 452 else if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled) 453 inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)]; 454 else { 455 inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i]; 456 const_inputs |= VERT_BIT_FF(i); 457 } 458 } 459 460 /* Could use just about anything, just to fill in the empty 461 * slots: 462 */ 463 for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) { 464 inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i]; 465 const_inputs |= VERT_BIT_GENERIC(i); 466 } 467 break; 468 469 case VP_ARB: 470 /* GL_ARB_vertex_program or GLSL vertex shader - Only the generic[0] 471 * attribute array aliases and overrides the legacy position array. 472 * 473 * Otherwise, legacy attributes available in the legacy slots, 474 * generic attributes in the generic slots and materials are not 475 * available as per-vertex attributes. 476 */ 477 if (vertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) 478 inputs[0] = &vertexAttrib[VERT_ATTRIB_GENERIC0]; 479 else if (vertexAttrib[VERT_ATTRIB_POS].Enabled) 480 inputs[0] = &vertexAttrib[VERT_ATTRIB_POS]; 481 else { 482 inputs[0] = &vbo->currval[VBO_ATTRIB_POS]; 483 const_inputs |= VERT_BIT_POS; 484 } 485 486 for (i = 1; i < VERT_ATTRIB_FF_MAX; i++) { 487 if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled) 488 inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)]; 489 else { 490 inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i]; 491 const_inputs |= VERT_BIT_FF(i); 492 } 493 } 494 495 for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) { 496 if (vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled) 497 inputs[VERT_ATTRIB_GENERIC(i)] = &vertexAttrib[VERT_ATTRIB_GENERIC(i)]; 498 else { 499 inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i]; 500 const_inputs |= VERT_BIT_GENERIC(i); 501 } 502 } 503 504 inputs[VERT_ATTRIB_GENERIC0] = inputs[0]; 505 break; 506 } 507 508 _mesa_set_varying_vp_inputs( ctx, VERT_BIT_ALL & (~const_inputs) ); 509 ctx->NewDriverState |= ctx->DriverFlags.NewArray; 510} 511 512 513/** 514 * Examine the enabled vertex arrays to set the exec->array.inputs[] values. 515 * These will point to the arrays to actually use for drawing. Some will 516 * be user-provided arrays, other will be zero-stride const-valued arrays. 517 * Note that this might set the _NEW_VARYING_VP_INPUTS dirty flag so state 518 * validation must be done after this call. 519 */ 520void 521vbo_bind_arrays(struct gl_context *ctx) 522{ 523 struct vbo_context *vbo = vbo_context(ctx); 524 struct vbo_exec_context *exec = &vbo->exec; 525 526 vbo_draw_method(vbo, DRAW_ARRAYS); 527 528 if (exec->array.recalculate_inputs) { 529 recalculate_input_bindings(ctx); 530 531 /* Again... because we may have changed the bitmask of per-vertex varying 532 * attributes. If we regenerate the fixed-function vertex program now 533 * we may be able to prune down the number of vertex attributes which we 534 * need in the shader. 535 */ 536 if (ctx->NewState) { 537 _mesa_update_state(ctx); 538 } 539 540 exec->array.recalculate_inputs = GL_FALSE; 541 } 542} 543 544 545/** 546 * Handle a draw case that potentially has primitive restart enabled. 547 * 548 * If primitive restart is enabled, and PrimitiveRestartInSoftware is 549 * set, then vbo_sw_primitive_restart is used to handle the primitive 550 * restart case in software. 551 */ 552static void 553vbo_handle_primitive_restart(struct gl_context *ctx, 554 const struct _mesa_prim *prim, 555 GLuint nr_prims, 556 const struct _mesa_index_buffer *ib, 557 GLboolean index_bounds_valid, 558 GLuint min_index, 559 GLuint max_index) 560{ 561 struct vbo_context *vbo = vbo_context(ctx); 562 563 if ((ib != NULL) && 564 ctx->Const.PrimitiveRestartInSoftware && 565 ctx->Array.PrimitiveRestart) { 566 /* Handle primitive restart in software */ 567 vbo_sw_primitive_restart(ctx, prim, nr_prims, ib); 568 } else { 569 /* Call driver directly for draw_prims */ 570 vbo->draw_prims(ctx, prim, nr_prims, ib, 571 index_bounds_valid, min_index, max_index, NULL); 572 } 573} 574 575 576/** 577 * Helper function called by the other DrawArrays() functions below. 578 * This is where we handle primitive restart for drawing non-indexed 579 * arrays. If primitive restart is enabled, it typically means 580 * splitting one DrawArrays() into two. 581 */ 582static void 583vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, 584 GLsizei count, GLuint numInstances, GLuint baseInstance) 585{ 586 struct vbo_context *vbo = vbo_context(ctx); 587 struct vbo_exec_context *exec = &vbo->exec; 588 struct _mesa_prim prim[2]; 589 590 vbo_bind_arrays(ctx); 591 592 /* init most fields to zero */ 593 memset(prim, 0, sizeof(prim)); 594 prim[0].begin = 1; 595 prim[0].end = 1; 596 prim[0].mode = mode; 597 prim[0].num_instances = numInstances; 598 prim[0].base_instance = baseInstance; 599 600 /* Implement the primitive restart index */ 601 if (ctx->Array.PrimitiveRestart && ctx->Array.RestartIndex < count) { 602 GLuint primCount = 0; 603 604 if (ctx->Array.RestartIndex == start) { 605 /* special case: RestartIndex at beginning */ 606 if (count > 1) { 607 prim[0].start = start + 1; 608 prim[0].count = count - 1; 609 primCount = 1; 610 } 611 } 612 else if (ctx->Array.RestartIndex == start + count - 1) { 613 /* special case: RestartIndex at end */ 614 if (count > 1) { 615 prim[0].start = start; 616 prim[0].count = count - 1; 617 primCount = 1; 618 } 619 } 620 else { 621 /* general case: RestartIndex in middle, split into two prims */ 622 prim[0].start = start; 623 prim[0].count = ctx->Array.RestartIndex - start; 624 625 prim[1] = prim[0]; 626 prim[1].start = ctx->Array.RestartIndex + 1; 627 prim[1].count = count - prim[1].start; 628 629 primCount = 2; 630 } 631 632 if (primCount > 0) { 633 /* draw one or two prims */ 634 check_buffers_are_unmapped(exec->array.inputs); 635 vbo->draw_prims(ctx, prim, primCount, NULL, 636 GL_TRUE, start, start + count - 1, NULL); 637 } 638 } 639 else { 640 /* no prim restart */ 641 prim[0].start = start; 642 prim[0].count = count; 643 644 check_buffers_are_unmapped(exec->array.inputs); 645 vbo->draw_prims(ctx, prim, 1, NULL, 646 GL_TRUE, start, start + count - 1, 647 NULL); 648 } 649 650 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 651 _mesa_flush(ctx); 652 } 653} 654 655 656 657/** 658 * Called from glDrawArrays when in immediate mode (not display list mode). 659 */ 660static void GLAPIENTRY 661vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) 662{ 663 GET_CURRENT_CONTEXT(ctx); 664 665 if (MESA_VERBOSE & VERBOSE_DRAW) 666 _mesa_debug(ctx, "glDrawArrays(%s, %d, %d)\n", 667 _mesa_lookup_enum_by_nr(mode), start, count); 668 669 if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) 670 return; 671 672 if (0) 673 check_draw_arrays_data(ctx, start, count); 674 675 vbo_draw_arrays(ctx, mode, start, count, 1, 0); 676 677 if (0) 678 print_draw_arrays(ctx, mode, start, count); 679} 680 681 682/** 683 * Called from glDrawArraysInstanced when in immediate mode (not 684 * display list mode). 685 */ 686static void GLAPIENTRY 687vbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count, 688 GLsizei numInstances) 689{ 690 GET_CURRENT_CONTEXT(ctx); 691 692 if (MESA_VERBOSE & VERBOSE_DRAW) 693 _mesa_debug(ctx, "glDrawArraysInstanced(%s, %d, %d, %d)\n", 694 _mesa_lookup_enum_by_nr(mode), start, count, numInstances); 695 696 if (!_mesa_validate_DrawArraysInstanced(ctx, mode, start, count, numInstances)) 697 return; 698 699 if (0) 700 check_draw_arrays_data(ctx, start, count); 701 702 vbo_draw_arrays(ctx, mode, start, count, numInstances, 0); 703 704 if (0) 705 print_draw_arrays(ctx, mode, start, count); 706} 707 708 709/** 710 * Called from glDrawArraysInstancedBaseInstance when in immediate mode. 711 */ 712static void GLAPIENTRY 713vbo_exec_DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, 714 GLsizei numInstances, GLuint baseInstance) 715{ 716 GET_CURRENT_CONTEXT(ctx); 717 718 if (MESA_VERBOSE & VERBOSE_DRAW) 719 _mesa_debug(ctx, "glDrawArraysInstancedBaseInstance(%s, %d, %d, %d, %d)\n", 720 _mesa_lookup_enum_by_nr(mode), first, count, 721 numInstances, baseInstance); 722 723 if (!_mesa_validate_DrawArraysInstanced(ctx, mode, first, count, 724 numInstances)) 725 return; 726 727 if (0) 728 check_draw_arrays_data(ctx, first, count); 729 730 vbo_draw_arrays(ctx, mode, first, count, numInstances, baseInstance); 731 732 if (0) 733 print_draw_arrays(ctx, mode, first, count); 734} 735 736 737 738/** 739 * Map GL_ELEMENT_ARRAY_BUFFER and print contents. 740 * For debugging. 741 */ 742#if 0 743static void 744dump_element_buffer(struct gl_context *ctx, GLenum type) 745{ 746 const GLvoid *map = 747 ctx->Driver.MapBufferRange(ctx, 0, 748 ctx->Array.ArrayObj->ElementArrayBufferObj->Size, 749 GL_MAP_READ_BIT, 750 ctx->Array.ArrayObj->ElementArrayBufferObj); 751 switch (type) { 752 case GL_UNSIGNED_BYTE: 753 { 754 const GLubyte *us = (const GLubyte *) map; 755 GLint i; 756 for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size; i++) { 757 printf("%02x ", us[i]); 758 if (i % 32 == 31) 759 printf("\n"); 760 } 761 printf("\n"); 762 } 763 break; 764 case GL_UNSIGNED_SHORT: 765 { 766 const GLushort *us = (const GLushort *) map; 767 GLint i; 768 for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size / 2; i++) { 769 printf("%04x ", us[i]); 770 if (i % 16 == 15) 771 printf("\n"); 772 } 773 printf("\n"); 774 } 775 break; 776 case GL_UNSIGNED_INT: 777 { 778 const GLuint *us = (const GLuint *) map; 779 GLint i; 780 for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size / 4; i++) { 781 printf("%08x ", us[i]); 782 if (i % 8 == 7) 783 printf("\n"); 784 } 785 printf("\n"); 786 } 787 break; 788 default: 789 ; 790 } 791 792 ctx->Driver.UnmapBuffer(ctx, ctx->Array.ArrayObj->ElementArrayBufferObj); 793} 794#endif 795 796 797/** 798 * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements. 799 * Do the rendering for a glDrawElements or glDrawRangeElements call after 800 * we've validated buffer bounds, etc. 801 */ 802static void 803vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, 804 GLboolean index_bounds_valid, 805 GLuint start, GLuint end, 806 GLsizei count, GLenum type, 807 const GLvoid *indices, 808 GLint basevertex, GLint numInstances, 809 GLuint baseInstance) 810{ 811 struct vbo_context *vbo = vbo_context(ctx); 812 struct vbo_exec_context *exec = &vbo->exec; 813 struct _mesa_index_buffer ib; 814 struct _mesa_prim prim[1]; 815 816 vbo_bind_arrays(ctx); 817 818 ib.count = count; 819 ib.type = type; 820 ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj; 821 ib.ptr = indices; 822 823 prim[0].begin = 1; 824 prim[0].end = 1; 825 prim[0].weak = 0; 826 prim[0].pad = 0; 827 prim[0].mode = mode; 828 prim[0].start = 0; 829 prim[0].count = count; 830 prim[0].indexed = 1; 831 prim[0].basevertex = basevertex; 832 prim[0].num_instances = numInstances; 833 prim[0].base_instance = baseInstance; 834 835 /* Need to give special consideration to rendering a range of 836 * indices starting somewhere above zero. Typically the 837 * application is issuing multiple DrawRangeElements() to draw 838 * successive primitives layed out linearly in the vertex arrays. 839 * Unless the vertex arrays are all in a VBO (or locked as with 840 * CVA), the OpenGL semantics imply that we need to re-read or 841 * re-upload the vertex data on each draw call. 842 * 843 * In the case of hardware tnl, we want to avoid starting the 844 * upload at zero, as it will mean every draw call uploads an 845 * increasing amount of not-used vertex data. Worse - in the 846 * software tnl module, all those vertices might be transformed and 847 * lit but never rendered. 848 * 849 * If we just upload or transform the vertices in start..end, 850 * however, the indices will be incorrect. 851 * 852 * At this level, we don't know exactly what the requirements of 853 * the backend are going to be, though it will likely boil down to 854 * either: 855 * 856 * 1) Do nothing, everything is in a VBO and is processed once 857 * only. 858 * 859 * 2) Adjust the indices and vertex arrays so that start becomes 860 * zero. 861 * 862 * Rather than doing anything here, I'll provide a helper function 863 * for the latter case elsewhere. 864 */ 865 866 check_buffers_are_unmapped(exec->array.inputs); 867 vbo_handle_primitive_restart(ctx, prim, 1, &ib, 868 index_bounds_valid, start, end); 869 870 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 871 _mesa_flush(ctx); 872 } 873} 874 875 876/** 877 * Called by glDrawRangeElementsBaseVertex() in immediate mode. 878 */ 879static void GLAPIENTRY 880vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, 881 GLuint start, GLuint end, 882 GLsizei count, GLenum type, 883 const GLvoid *indices, 884 GLint basevertex) 885{ 886 static GLuint warnCount = 0; 887 GLboolean index_bounds_valid = GL_TRUE; 888 GET_CURRENT_CONTEXT(ctx); 889 890 if (MESA_VERBOSE & VERBOSE_DRAW) 891 _mesa_debug(ctx, 892 "glDrawRangeElementsBaseVertex(%s, %u, %u, %d, %s, %p, %d)\n", 893 _mesa_lookup_enum_by_nr(mode), start, end, count, 894 _mesa_lookup_enum_by_nr(type), indices, basevertex); 895 896 if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count, 897 type, indices, basevertex )) 898 return; 899 900 if ((int) end + basevertex < 0 || 901 start + basevertex >= ctx->Array.ArrayObj->_MaxElement) { 902 /* The application requested we draw using a range of indices that's 903 * outside the bounds of the current VBO. This is invalid and appears 904 * to give undefined results. The safest thing to do is to simply 905 * ignore the range, in case the application botched their range tracking 906 * but did provide valid indices. Also issue a warning indicating that 907 * the application is broken. 908 */ 909 if (warnCount++ < 10) { 910 _mesa_warning(ctx, "glDrawRangeElements(start %u, end %u, " 911 "basevertex %d, count %d, type 0x%x, indices=%p):\n" 912 "\trange is outside VBO bounds (max=%u); ignoring.\n" 913 "\tThis should be fixed in the application.", 914 start, end, basevertex, count, type, indices, 915 ctx->Array.ArrayObj->_MaxElement - 1); 916 } 917 index_bounds_valid = GL_FALSE; 918 } 919 920 /* NOTE: It's important that 'end' is a reasonable value. 921 * in _tnl_draw_prims(), we use end to determine how many vertices 922 * to transform. If it's too large, we can unnecessarily split prims 923 * or we can read/write out of memory in several different places! 924 */ 925 926 /* Catch/fix some potential user errors */ 927 if (type == GL_UNSIGNED_BYTE) { 928 start = MIN2(start, 0xff); 929 end = MIN2(end, 0xff); 930 } 931 else if (type == GL_UNSIGNED_SHORT) { 932 start = MIN2(start, 0xffff); 933 end = MIN2(end, 0xffff); 934 } 935 936 if (0) { 937 printf("glDraw[Range]Elements{,BaseVertex}" 938 "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, " 939 "base %d\n", 940 start, end, type, count, 941 ctx->Array.ArrayObj->ElementArrayBufferObj->Name, 942 basevertex); 943 } 944 945 if ((int) start + basevertex < 0 || 946 end + basevertex >= ctx->Array.ArrayObj->_MaxElement) 947 index_bounds_valid = GL_FALSE; 948 949#if 0 950 check_draw_elements_data(ctx, count, type, indices); 951#else 952 (void) check_draw_elements_data; 953#endif 954 955 vbo_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end, 956 count, type, indices, basevertex, 1, 0); 957} 958 959 960/** 961 * Called by glDrawRangeElements() in immediate mode. 962 */ 963static void GLAPIENTRY 964vbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end, 965 GLsizei count, GLenum type, const GLvoid *indices) 966{ 967 if (MESA_VERBOSE & VERBOSE_DRAW) { 968 GET_CURRENT_CONTEXT(ctx); 969 _mesa_debug(ctx, 970 "glDrawRangeElements(%s, %u, %u, %d, %s, %p)\n", 971 _mesa_lookup_enum_by_nr(mode), start, end, count, 972 _mesa_lookup_enum_by_nr(type), indices); 973 } 974 975 vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type, 976 indices, 0); 977} 978 979 980/** 981 * Called by glDrawElements() in immediate mode. 982 */ 983static void GLAPIENTRY 984vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, 985 const GLvoid *indices) 986{ 987 GET_CURRENT_CONTEXT(ctx); 988 989 if (MESA_VERBOSE & VERBOSE_DRAW) 990 _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n", 991 _mesa_lookup_enum_by_nr(mode), count, 992 _mesa_lookup_enum_by_nr(type), indices); 993 994 if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 )) 995 return; 996 997 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, 998 count, type, indices, 0, 1, 0); 999} 1000 1001 1002/** 1003 * Called by glDrawElementsBaseVertex() in immediate mode. 1004 */ 1005static void GLAPIENTRY 1006vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, 1007 const GLvoid *indices, GLint basevertex) 1008{ 1009 GET_CURRENT_CONTEXT(ctx); 1010 1011 if (MESA_VERBOSE & VERBOSE_DRAW) 1012 _mesa_debug(ctx, "glDrawElementsBaseVertex(%s, %d, %s, %p, %d)\n", 1013 _mesa_lookup_enum_by_nr(mode), count, 1014 _mesa_lookup_enum_by_nr(type), indices, basevertex); 1015 1016 if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 1017 basevertex )) 1018 return; 1019 1020 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, 1021 count, type, indices, basevertex, 1, 0); 1022} 1023 1024 1025/** 1026 * Called by glDrawElementsInstanced() in immediate mode. 1027 */ 1028static void GLAPIENTRY 1029vbo_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, 1030 const GLvoid *indices, GLsizei numInstances) 1031{ 1032 GET_CURRENT_CONTEXT(ctx); 1033 1034 if (MESA_VERBOSE & VERBOSE_DRAW) 1035 _mesa_debug(ctx, "glDrawElementsInstanced(%s, %d, %s, %p, %d)\n", 1036 _mesa_lookup_enum_by_nr(mode), count, 1037 _mesa_lookup_enum_by_nr(type), indices, numInstances); 1038 1039 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, 1040 numInstances, 0)) 1041 return; 1042 1043 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, 1044 count, type, indices, 0, numInstances, 0); 1045} 1046 1047 1048/** 1049 * Called by glDrawElementsInstancedBaseVertex() in immediate mode. 1050 */ 1051static void GLAPIENTRY 1052vbo_exec_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, 1053 const GLvoid *indices, GLsizei numInstances, 1054 GLint basevertex) 1055{ 1056 GET_CURRENT_CONTEXT(ctx); 1057 1058 if (MESA_VERBOSE & VERBOSE_DRAW) 1059 _mesa_debug(ctx, "glDrawElementsInstancedBaseVertex(%s, %d, %s, %p, %d; %d)\n", 1060 _mesa_lookup_enum_by_nr(mode), count, 1061 _mesa_lookup_enum_by_nr(type), indices, 1062 numInstances, basevertex); 1063 1064 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, 1065 numInstances, basevertex)) 1066 return; 1067 1068 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, 1069 count, type, indices, basevertex, numInstances, 0); 1070} 1071 1072 1073/** 1074 * Called by glDrawElementsInstancedBaseInstance() in immediate mode. 1075 */ 1076static void GLAPIENTRY 1077vbo_exec_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, 1078 const GLvoid *indices, GLsizei numInstances, 1079 GLuint baseInstance) 1080{ 1081 GET_CURRENT_CONTEXT(ctx); 1082 1083 if (MESA_VERBOSE & VERBOSE_DRAW) 1084 _mesa_debug(ctx, "glDrawElementsInstancedBaseInstance(%s, %d, %s, %p, %d, %d)\n", 1085 _mesa_lookup_enum_by_nr(mode), count, 1086 _mesa_lookup_enum_by_nr(type), indices, 1087 numInstances, baseInstance); 1088 1089 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, 1090 numInstances, 0)) 1091 return; 1092 1093 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, 1094 count, type, indices, 0, numInstances, 1095 baseInstance); 1096} 1097 1098 1099/** 1100 * Called by glDrawElementsInstancedBaseVertexBaseInstance() in immediate mode. 1101 */ 1102static void GLAPIENTRY 1103vbo_exec_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, 1104 const GLvoid *indices, GLsizei numInstances, 1105 GLint basevertex, GLuint baseInstance) 1106{ 1107 GET_CURRENT_CONTEXT(ctx); 1108 1109 if (MESA_VERBOSE & VERBOSE_DRAW) 1110 _mesa_debug(ctx, "glDrawElementsInstancedBaseVertexBaseInstance(%s, %d, %s, %p, %d, %d, %d)\n", 1111 _mesa_lookup_enum_by_nr(mode), count, 1112 _mesa_lookup_enum_by_nr(type), indices, 1113 numInstances, basevertex, baseInstance); 1114 1115 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, 1116 numInstances, basevertex)) 1117 return; 1118 1119 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, 1120 count, type, indices, basevertex, numInstances, 1121 baseInstance); 1122} 1123 1124 1125/** 1126 * Inner support for both _mesa_MultiDrawElements() and 1127 * _mesa_MultiDrawRangeElements(). 1128 * This does the actual rendering after we've checked array indexes, etc. 1129 */ 1130static void 1131vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, 1132 const GLsizei *count, GLenum type, 1133 const GLvoid * const *indices, 1134 GLsizei primcount, 1135 const GLint *basevertex) 1136{ 1137 struct vbo_context *vbo = vbo_context(ctx); 1138 struct vbo_exec_context *exec = &vbo->exec; 1139 struct _mesa_index_buffer ib; 1140 struct _mesa_prim *prim; 1141 unsigned int index_type_size = vbo_sizeof_ib_type(type); 1142 uintptr_t min_index_ptr, max_index_ptr; 1143 GLboolean fallback = GL_FALSE; 1144 int i; 1145 1146 if (primcount == 0) 1147 return; 1148 1149 prim = calloc(1, primcount * sizeof(*prim)); 1150 if (prim == NULL) { 1151 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements"); 1152 return; 1153 } 1154 1155 vbo_bind_arrays(ctx); 1156 1157 min_index_ptr = (uintptr_t)indices[0]; 1158 max_index_ptr = 0; 1159 for (i = 0; i < primcount; i++) { 1160 min_index_ptr = MIN2(min_index_ptr, (uintptr_t)indices[i]); 1161 max_index_ptr = MAX2(max_index_ptr, (uintptr_t)indices[i] + 1162 index_type_size * count[i]); 1163 } 1164 1165 /* Check if we can handle this thing as a bunch of index offsets from the 1166 * same index pointer. If we can't, then we have to fall back to doing 1167 * a draw_prims per primitive. 1168 * Check that the difference between each prim's indexes is a multiple of 1169 * the index/element size. 1170 */ 1171 if (index_type_size != 1) { 1172 for (i = 0; i < primcount; i++) { 1173 if ((((uintptr_t)indices[i] - min_index_ptr) % index_type_size) != 0) { 1174 fallback = GL_TRUE; 1175 break; 1176 } 1177 } 1178 } 1179 1180 /* If the index buffer isn't in a VBO, then treating the application's 1181 * subranges of the index buffer as one large index buffer may lead to 1182 * us reading unmapped memory. 1183 */ 1184 if (!_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj)) 1185 fallback = GL_TRUE; 1186 1187 if (!fallback) { 1188 ib.count = (max_index_ptr - min_index_ptr) / index_type_size; 1189 ib.type = type; 1190 ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj; 1191 ib.ptr = (void *)min_index_ptr; 1192 1193 for (i = 0; i < primcount; i++) { 1194 prim[i].begin = (i == 0); 1195 prim[i].end = (i == primcount - 1); 1196 prim[i].weak = 0; 1197 prim[i].pad = 0; 1198 prim[i].mode = mode; 1199 prim[i].start = ((uintptr_t)indices[i] - min_index_ptr) / index_type_size; 1200 prim[i].count = count[i]; 1201 prim[i].indexed = 1; 1202 prim[i].num_instances = 1; 1203 prim[i].base_instance = 0; 1204 if (basevertex != NULL) 1205 prim[i].basevertex = basevertex[i]; 1206 else 1207 prim[i].basevertex = 0; 1208 } 1209 1210 check_buffers_are_unmapped(exec->array.inputs); 1211 vbo_handle_primitive_restart(ctx, prim, primcount, &ib, 1212 GL_FALSE, ~0, ~0); 1213 } else { 1214 /* render one prim at a time */ 1215 for (i = 0; i < primcount; i++) { 1216 ib.count = count[i]; 1217 ib.type = type; 1218 ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj; 1219 ib.ptr = indices[i]; 1220 1221 prim[0].begin = 1; 1222 prim[0].end = 1; 1223 prim[0].weak = 0; 1224 prim[0].pad = 0; 1225 prim[0].mode = mode; 1226 prim[0].start = 0; 1227 prim[0].count = count[i]; 1228 prim[0].indexed = 1; 1229 prim[0].num_instances = 1; 1230 prim[0].base_instance = 0; 1231 if (basevertex != NULL) 1232 prim[0].basevertex = basevertex[i]; 1233 else 1234 prim[0].basevertex = 0; 1235 1236 check_buffers_are_unmapped(exec->array.inputs); 1237 vbo_handle_primitive_restart(ctx, prim, 1, &ib, 1238 GL_FALSE, ~0, ~0); 1239 } 1240 } 1241 1242 free(prim); 1243 1244 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 1245 _mesa_flush(ctx); 1246 } 1247} 1248 1249 1250static void GLAPIENTRY 1251vbo_exec_MultiDrawElements(GLenum mode, 1252 const GLsizei *count, GLenum type, 1253 const GLvoid **indices, 1254 GLsizei primcount) 1255{ 1256 GET_CURRENT_CONTEXT(ctx); 1257 1258 if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices, 1259 primcount, NULL)) 1260 return; 1261 1262 vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount, 1263 NULL); 1264} 1265 1266 1267static void GLAPIENTRY 1268vbo_exec_MultiDrawElementsBaseVertex(GLenum mode, 1269 const GLsizei *count, GLenum type, 1270 const GLvoid * const *indices, 1271 GLsizei primcount, 1272 const GLsizei *basevertex) 1273{ 1274 GET_CURRENT_CONTEXT(ctx); 1275 1276 if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices, 1277 primcount, basevertex)) 1278 return; 1279 1280 vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount, 1281 basevertex); 1282} 1283 1284#if FEATURE_EXT_transform_feedback 1285 1286static void 1287vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode, 1288 struct gl_transform_feedback_object *obj, 1289 GLuint stream, GLuint numInstances) 1290{ 1291 struct vbo_context *vbo = vbo_context(ctx); 1292 struct vbo_exec_context *exec = &vbo->exec; 1293 struct _mesa_prim prim[2]; 1294 1295 if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream, 1296 numInstances)) { 1297 return; 1298 } 1299 1300 vbo_bind_arrays(ctx); 1301 1302 /* init most fields to zero */ 1303 memset(prim, 0, sizeof(prim)); 1304 prim[0].begin = 1; 1305 prim[0].end = 1; 1306 prim[0].mode = mode; 1307 prim[0].num_instances = numInstances; 1308 prim[0].base_instance = 0; 1309 1310 /* Maybe we should do some primitive splitting for primitive restart 1311 * (like in DrawArrays), but we have no way to know how many vertices 1312 * will be rendered. */ 1313 1314 check_buffers_are_unmapped(exec->array.inputs); 1315 vbo->draw_prims(ctx, prim, 1, NULL, 1316 GL_TRUE, 0, 0, obj); 1317 1318 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 1319 _mesa_flush(ctx); 1320 } 1321} 1322 1323/** 1324 * Like DrawArrays, but take the count from a transform feedback object. 1325 * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc. 1326 * \param name the transform feedback object 1327 * User still has to setup of the vertex attribute info with 1328 * glVertexPointer, glColorPointer, etc. 1329 * Part of GL_ARB_transform_feedback2. 1330 */ 1331static void GLAPIENTRY 1332vbo_exec_DrawTransformFeedback(GLenum mode, GLuint name) 1333{ 1334 GET_CURRENT_CONTEXT(ctx); 1335 struct gl_transform_feedback_object *obj = 1336 _mesa_lookup_transform_feedback_object(ctx, name); 1337 1338 if (MESA_VERBOSE & VERBOSE_DRAW) 1339 _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n", 1340 _mesa_lookup_enum_by_nr(mode), name); 1341 1342 vbo_draw_transform_feedback(ctx, mode, obj, 0, 1); 1343} 1344 1345static void GLAPIENTRY 1346vbo_exec_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream) 1347{ 1348 GET_CURRENT_CONTEXT(ctx); 1349 struct gl_transform_feedback_object *obj = 1350 _mesa_lookup_transform_feedback_object(ctx, name); 1351 1352 if (MESA_VERBOSE & VERBOSE_DRAW) 1353 _mesa_debug(ctx, "glDrawTransformFeedbackStream(%s, %u, %u)\n", 1354 _mesa_lookup_enum_by_nr(mode), name, stream); 1355 1356 vbo_draw_transform_feedback(ctx, mode, obj, stream, 1); 1357} 1358 1359static void GLAPIENTRY 1360vbo_exec_DrawTransformFeedbackInstanced(GLenum mode, GLuint name, 1361 GLsizei primcount) 1362{ 1363 GET_CURRENT_CONTEXT(ctx); 1364 struct gl_transform_feedback_object *obj = 1365 _mesa_lookup_transform_feedback_object(ctx, name); 1366 1367 if (MESA_VERBOSE & VERBOSE_DRAW) 1368 _mesa_debug(ctx, "glDrawTransformFeedbackInstanced(%s, %d)\n", 1369 _mesa_lookup_enum_by_nr(mode), name); 1370 1371 vbo_draw_transform_feedback(ctx, mode, obj, 0, primcount); 1372} 1373 1374static void GLAPIENTRY 1375vbo_exec_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name, 1376 GLuint stream, GLsizei primcount) 1377{ 1378 GET_CURRENT_CONTEXT(ctx); 1379 struct gl_transform_feedback_object *obj = 1380 _mesa_lookup_transform_feedback_object(ctx, name); 1381 1382 if (MESA_VERBOSE & VERBOSE_DRAW) 1383 _mesa_debug(ctx, "glDrawTransformFeedbackStreamInstanced" 1384 "(%s, %u, %u, %i)\n", 1385 _mesa_lookup_enum_by_nr(mode), name, stream, primcount); 1386 1387 vbo_draw_transform_feedback(ctx, mode, obj, stream, primcount); 1388} 1389 1390#endif 1391 1392/** 1393 * Plug in the immediate-mode vertex array drawing commands into the 1394 * givven vbo_exec_context object. 1395 */ 1396void 1397vbo_exec_array_init( struct vbo_exec_context *exec ) 1398{ 1399 exec->vtxfmt.DrawArrays = vbo_exec_DrawArrays; 1400 exec->vtxfmt.DrawElements = vbo_exec_DrawElements; 1401 exec->vtxfmt.DrawRangeElements = vbo_exec_DrawRangeElements; 1402 exec->vtxfmt.MultiDrawElementsEXT = vbo_exec_MultiDrawElements; 1403 exec->vtxfmt.DrawElementsBaseVertex = vbo_exec_DrawElementsBaseVertex; 1404 exec->vtxfmt.DrawRangeElementsBaseVertex = vbo_exec_DrawRangeElementsBaseVertex; 1405 exec->vtxfmt.MultiDrawElementsBaseVertex = vbo_exec_MultiDrawElementsBaseVertex; 1406 exec->vtxfmt.DrawArraysInstanced = vbo_exec_DrawArraysInstanced; 1407 exec->vtxfmt.DrawArraysInstancedBaseInstance = vbo_exec_DrawArraysInstancedBaseInstance; 1408 exec->vtxfmt.DrawElementsInstanced = vbo_exec_DrawElementsInstanced; 1409 exec->vtxfmt.DrawElementsInstancedBaseInstance = vbo_exec_DrawElementsInstancedBaseInstance; 1410 exec->vtxfmt.DrawElementsInstancedBaseVertex = vbo_exec_DrawElementsInstancedBaseVertex; 1411 exec->vtxfmt.DrawElementsInstancedBaseVertexBaseInstance = vbo_exec_DrawElementsInstancedBaseVertexBaseInstance; 1412#if FEATURE_EXT_transform_feedback 1413 exec->vtxfmt.DrawTransformFeedback = vbo_exec_DrawTransformFeedback; 1414 exec->vtxfmt.DrawTransformFeedbackStream = 1415 vbo_exec_DrawTransformFeedbackStream; 1416 exec->vtxfmt.DrawTransformFeedbackInstanced = 1417 vbo_exec_DrawTransformFeedbackInstanced; 1418 exec->vtxfmt.DrawTransformFeedbackStreamInstanced = 1419 vbo_exec_DrawTransformFeedbackStreamInstanced; 1420#endif 1421} 1422 1423 1424void 1425vbo_exec_array_destroy( struct vbo_exec_context *exec ) 1426{ 1427 /* nothing to do */ 1428} 1429 1430 1431 1432/** 1433 * The following functions are only used for OpenGL ES 1/2 support. 1434 * And some aren't even supported (yet) in ES 1/2. 1435 */ 1436 1437 1438void GLAPIENTRY 1439_mesa_DrawArrays(GLenum mode, GLint first, GLsizei count) 1440{ 1441 vbo_exec_DrawArrays(mode, first, count); 1442} 1443 1444 1445void GLAPIENTRY 1446_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, 1447 const GLvoid *indices) 1448{ 1449 vbo_exec_DrawElements(mode, count, type, indices); 1450} 1451 1452 1453void GLAPIENTRY 1454_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, 1455 const GLvoid *indices, GLint basevertex) 1456{ 1457 vbo_exec_DrawElementsBaseVertex(mode, count, type, indices, basevertex); 1458} 1459 1460 1461void GLAPIENTRY 1462_mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, 1463 GLenum type, const GLvoid *indices) 1464{ 1465 vbo_exec_DrawRangeElements(mode, start, end, count, type, indices); 1466} 1467 1468 1469void GLAPIENTRY 1470_mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, 1471 GLsizei count, GLenum type, 1472 const GLvoid *indices, GLint basevertex) 1473{ 1474 vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type, 1475 indices, basevertex); 1476} 1477 1478 1479void GLAPIENTRY 1480_mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type, 1481 const GLvoid **indices, GLsizei primcount) 1482{ 1483 vbo_exec_MultiDrawElements(mode, count, type, indices, primcount); 1484} 1485 1486 1487void GLAPIENTRY 1488_mesa_MultiDrawElementsBaseVertex(GLenum mode, 1489 const GLsizei *count, GLenum type, 1490 const GLvoid **indices, GLsizei primcount, 1491 const GLint *basevertex) 1492{ 1493 vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices, 1494 primcount, basevertex); 1495} 1496 1497#if FEATURE_EXT_transform_feedback 1498 1499void GLAPIENTRY 1500_mesa_DrawTransformFeedback(GLenum mode, GLuint name) 1501{ 1502 vbo_exec_DrawTransformFeedback(mode, name); 1503} 1504 1505#endif 1506