1/************************************************************************** 2 * 3 * Copyright 2003 VMware, Inc. 4 * Copyright 2009 VMware, Inc. 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation the rights to use, copy, modify, merge, publish, 11 * distribute, sub license, and/or sell copies of the Software, and to 12 * permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the 16 * next paragraph) shall be included in all copies or substantial portions 17 * of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * 27 **************************************************************************/ 28 29#include <stdio.h> 30#include "arrayobj.h" 31#include "glheader.h" 32#include "c99_alloca.h" 33#include "context.h" 34#include "state.h" 35#include "draw.h" 36#include "draw_validate.h" 37#include "dispatch.h" 38#include "varray.h" 39#include "bufferobj.h" 40#include "enums.h" 41#include "macros.h" 42#include "transformfeedback.h" 43#include "pipe/p_state.h" 44#include "api_exec_decl.h" 45 46#include "state_tracker/st_context.h" 47#include "state_tracker/st_draw.h" 48 49typedef struct { 50 GLuint count; 51 GLuint primCount; 52 GLuint first; 53 GLuint baseInstance; 54} DrawArraysIndirectCommand; 55 56typedef struct { 57 GLuint count; 58 GLuint primCount; 59 GLuint firstIndex; 60 GLint baseVertex; 61 GLuint baseInstance; 62} DrawElementsIndirectCommand; 63 64 65/** 66 * Want to figure out which fragment program inputs are actually 67 * constant/current values from ctx->Current. These should be 68 * referenced as a tracked state variable rather than a fragment 69 * program input, to save the overhead of putting a constant value in 70 * every submitted vertex, transferring it to hardware, interpolating 71 * it across the triangle, etc... 72 * 73 * When there is a VP bound, just use vp->outputs. But when we're 74 * generating vp from fixed function state, basically want to 75 * calculate: 76 * 77 * vp_out_2_fp_in( vp_in_2_vp_out( varying_inputs ) | 78 * potential_vp_outputs ) 79 * 80 * Where potential_vp_outputs is calculated by looking at enabled 81 * texgen, etc. 82 * 83 * The generated fragment program should then only declare inputs that 84 * may vary or otherwise differ from the ctx->Current values. 85 * Otherwise, the fp should track them as state values instead. 86 */ 87void 88_mesa_set_varying_vp_inputs(struct gl_context *ctx, GLbitfield varying_inputs) 89{ 90 if (ctx->VertexProgram._VPModeOptimizesConstantAttribs && 91 ctx->VertexProgram._VaryingInputs != varying_inputs) { 92 ctx->VertexProgram._VaryingInputs = varying_inputs; 93 ctx->NewState |= _NEW_FF_VERT_PROGRAM | _NEW_FF_FRAG_PROGRAM; 94 } 95} 96 97 98/** 99 * Set the _DrawVAO and the net enabled arrays. 100 * The vao->_Enabled bitmask is transformed due to position/generic0 101 * as stored in vao->_AttributeMapMode. Then the filter bitmask is applied 102 * to filter out arrays unwanted for the currently executed draw operation. 103 * For example, the generic attributes are masked out form the _DrawVAO's 104 * enabled arrays when a fixed function array draw is executed. 105 */ 106void 107_mesa_set_draw_vao(struct gl_context *ctx, struct gl_vertex_array_object *vao, 108 GLbitfield filter) 109{ 110 struct gl_vertex_array_object **ptr = &ctx->Array._DrawVAO; 111 bool new_vertex_buffers = false, new_vertex_elements = false; 112 113 if (*ptr != vao) { 114 _mesa_reference_vao_(ctx, ptr, vao); 115 new_vertex_buffers = true; 116 new_vertex_elements = true; 117 } 118 119 if (vao->NewVertexBuffers || vao->NewVertexElements) { 120 _mesa_update_vao_derived_arrays(ctx, vao); 121 new_vertex_buffers |= vao->NewVertexBuffers; 122 new_vertex_elements |= vao->NewVertexElements; 123 vao->NewVertexBuffers = false; 124 vao->NewVertexElements = false; 125 } 126 127 assert(vao->_EnabledWithMapMode == 128 _mesa_vao_enable_to_vp_inputs(vao->_AttributeMapMode, vao->Enabled)); 129 130 /* Filter out unwanted arrays. */ 131 const GLbitfield enabled = filter & vao->_EnabledWithMapMode; 132 if (ctx->Array._DrawVAOEnabledAttribs != enabled) { 133 ctx->Array._DrawVAOEnabledAttribs = enabled; 134 new_vertex_buffers = true; 135 new_vertex_elements = true; 136 } 137 138 if (new_vertex_buffers || new_vertex_elements) { 139 ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS; 140 ctx->Array.NewVertexElements |= new_vertex_elements; 141 } 142 143 _mesa_set_varying_vp_inputs(ctx, enabled); 144} 145 146 147/** 148 * Is 'mode' a valid value for glBegin(), glDrawArrays(), glDrawElements(), 149 * etc? Also, do additional checking related to transformation feedback. 150 * Note: this function cannot be called during glNewList(GL_COMPILE) because 151 * this code depends on current transform feedback state. 152 * Also, do additional checking related to tessellation shaders. 153 */ 154static GLenum 155valid_prim_mode_custom(struct gl_context *ctx, GLenum mode, 156 GLbitfield valid_prim_mask) 157{ 158#if DEBUG 159 unsigned mask = ctx->ValidPrimMask; 160 unsigned mask_indexed = ctx->ValidPrimMaskIndexed; 161 bool drawpix_valid = ctx->DrawPixValid; 162 _mesa_update_valid_to_render_state(ctx); 163 assert(mask == ctx->ValidPrimMask && 164 mask_indexed == ctx->ValidPrimMaskIndexed && 165 drawpix_valid == ctx->DrawPixValid); 166#endif 167 168 /* All primitive type enums are less than 32, so we can use the shift. */ 169 if (mode >= 32 || !((1u << mode) & valid_prim_mask)) { 170 /* If the primitive type is not in SupportedPrimMask, set GL_INVALID_ENUM, 171 * else set DrawGLError (e.g. GL_INVALID_OPERATION). 172 */ 173 return mode >= 32 || !((1u << mode) & ctx->SupportedPrimMask) ? 174 GL_INVALID_ENUM : ctx->DrawGLError; 175 } 176 177 return GL_NO_ERROR; 178} 179 180GLenum 181_mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode) 182{ 183 return valid_prim_mode_custom(ctx, mode, ctx->ValidPrimMask); 184} 185 186static GLenum 187valid_prim_mode_indexed(struct gl_context *ctx, GLenum mode) 188{ 189 return valid_prim_mode_custom(ctx, mode, ctx->ValidPrimMaskIndexed); 190} 191 192/** 193 * Verify that the element type is valid. 194 * 195 * Generates \c GL_INVALID_ENUM and returns \c false if it is not. 196 */ 197static GLenum 198valid_elements_type(struct gl_context *ctx, GLenum type) 199{ 200 /* GL_UNSIGNED_BYTE = 0x1401 201 * GL_UNSIGNED_SHORT = 0x1403 202 * GL_UNSIGNED_INT = 0x1405 203 * 204 * The trick is that bit 1 and bit 2 mean USHORT and UINT, respectively. 205 * After clearing those two bits (with ~6), we should get UBYTE. 206 * Both bits can't be set, because the enum would be greater than UINT. 207 */ 208 if (!(type <= GL_UNSIGNED_INT && (type & ~6) == GL_UNSIGNED_BYTE)) 209 return GL_INVALID_ENUM; 210 211 return GL_NO_ERROR; 212} 213 214static inline bool 215indices_aligned(unsigned index_size_shift, const GLvoid *indices) 216{ 217 /* Require that indices are aligned to the element size. GL doesn't specify 218 * an error for this, but the ES 3.0 spec says: 219 * 220 * "Clients must align data elements consistently with the requirements 221 * of the client platform, with an additional base-level requirement 222 * that an offset within a buffer to a datum comprising N basic machine 223 * units be a multiple of N" 224 * 225 * This is only required by index buffers, not user indices. 226 */ 227 return ((uintptr_t)indices & ((1 << index_size_shift) - 1)) == 0; 228} 229 230static GLenum 231validate_DrawElements_common(struct gl_context *ctx, GLenum mode, 232 GLsizei count, GLsizei numInstances, GLenum type) 233{ 234 if (count < 0 || numInstances < 0) 235 return GL_INVALID_VALUE; 236 237 GLenum error = valid_prim_mode_indexed(ctx, mode); 238 if (error) 239 return error; 240 241 return valid_elements_type(ctx, type); 242} 243 244/** 245 * Error checking for glDrawElements(). Includes parameter checking 246 * and VBO bounds checking. 247 * \return GL_TRUE if OK to render, GL_FALSE if error found 248 */ 249static GLboolean 250_mesa_validate_DrawElements(struct gl_context *ctx, 251 GLenum mode, GLsizei count, GLenum type) 252{ 253 GLenum error = validate_DrawElements_common(ctx, mode, count, 1, type); 254 if (error) 255 _mesa_error(ctx, error, "glDrawElements"); 256 257 return !error; 258} 259 260 261/** 262 * Error checking for glMultiDrawElements(). Includes parameter checking 263 * and VBO bounds checking. 264 * \return GL_TRUE if OK to render, GL_FALSE if error found 265 */ 266static GLboolean 267_mesa_validate_MultiDrawElements(struct gl_context *ctx, 268 GLenum mode, const GLsizei *count, 269 GLenum type, const GLvoid * const *indices, 270 GLsizei primcount) 271{ 272 GLenum error; 273 274 /* 275 * Section 2.3.1 (Errors) of the OpenGL 4.5 (Core Profile) spec says: 276 * 277 * "If a negative number is provided where an argument of type sizei or 278 * sizeiptr is specified, an INVALID_VALUE error is generated." 279 * 280 * and in the same section: 281 * 282 * "In other cases, there are no side effects unless otherwise noted; 283 * the command which generates the error is ignored so that it has no 284 * effect on GL state or framebuffer contents." 285 * 286 * Hence, check both primcount and all the count[i]. 287 */ 288 if (primcount < 0) { 289 error = GL_INVALID_VALUE; 290 } else { 291 error = valid_prim_mode_indexed(ctx, mode); 292 293 if (!error) { 294 error = valid_elements_type(ctx, type); 295 296 if (!error) { 297 for (int i = 0; i < primcount; i++) { 298 if (count[i] < 0) { 299 error = GL_INVALID_VALUE; 300 break; 301 } 302 } 303 } 304 } 305 } 306 307 if (error) 308 _mesa_error(ctx, error, "glMultiDrawElements"); 309 310 /* Not using a VBO for indices, so avoid NULL pointer derefs later. 311 */ 312 if (!ctx->Array.VAO->IndexBufferObj) { 313 for (int i = 0; i < primcount; i++) { 314 if (!indices[i]) 315 return GL_FALSE; 316 } 317 } 318 319 return !error; 320} 321 322 323/** 324 * Error checking for glDrawRangeElements(). Includes parameter checking 325 * and VBO bounds checking. 326 * \return GL_TRUE if OK to render, GL_FALSE if error found 327 */ 328static GLboolean 329_mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode, 330 GLuint start, GLuint end, 331 GLsizei count, GLenum type) 332{ 333 GLenum error; 334 335 if (end < start) { 336 error = GL_INVALID_VALUE; 337 } else { 338 error = validate_DrawElements_common(ctx, mode, count, 1, type); 339 } 340 341 if (error) 342 _mesa_error(ctx, error, "glDrawRangeElements"); 343 344 return !error; 345} 346 347 348static bool 349need_xfb_remaining_prims_check(const struct gl_context *ctx) 350{ 351 /* From the GLES3 specification, section 2.14.2 (Transform Feedback 352 * Primitive Capture): 353 * 354 * The error INVALID_OPERATION is generated by DrawArrays and 355 * DrawArraysInstanced if recording the vertices of a primitive to the 356 * buffer objects being used for transform feedback purposes would result 357 * in either exceeding the limits of any buffer object’s size, or in 358 * exceeding the end position offset + size − 1, as set by 359 * BindBufferRange. 360 * 361 * This is in contrast to the behaviour of desktop GL, where the extra 362 * primitives are silently dropped from the transform feedback buffer. 363 * 364 * This text is removed in ES 3.2, presumably because it's not really 365 * implementable with geometry and tessellation shaders. In fact, 366 * the OES_geometry_shader spec says: 367 * 368 * "(13) Does this extension change how transform feedback operates 369 * compared to unextended OpenGL ES 3.0 or 3.1? 370 * 371 * RESOLVED: Yes. Because dynamic geometry amplification in a geometry 372 * shader can make it difficult if not impossible to predict the amount 373 * of geometry that may be generated in advance of executing the shader, 374 * the draw-time error for transform feedback buffer overflow conditions 375 * is removed and replaced with the GL behavior (primitives are not 376 * written and the corresponding counter is not updated)..." 377 */ 378 return _mesa_is_gles3(ctx) && _mesa_is_xfb_active_and_unpaused(ctx) && 379 !_mesa_has_OES_geometry_shader(ctx) && 380 !_mesa_has_OES_tessellation_shader(ctx); 381} 382 383 384/** 385 * Figure out the number of transform feedback primitives that will be output 386 * considering the drawing mode, number of vertices, and instance count, 387 * assuming that no geometry shading is done and primitive restart is not 388 * used. 389 * 390 * This is used by driver back-ends in implementing the PRIMITIVES_GENERATED 391 * and TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN queries. It is also used to 392 * pre-validate draw calls in GLES3 (where draw calls only succeed if there is 393 * enough room in the transform feedback buffer for the result). 394 */ 395static size_t 396count_tessellated_primitives(GLenum mode, GLuint count, GLuint num_instances) 397{ 398 size_t num_primitives; 399 switch (mode) { 400 case GL_POINTS: 401 num_primitives = count; 402 break; 403 case GL_LINE_STRIP: 404 num_primitives = count >= 2 ? count - 1 : 0; 405 break; 406 case GL_LINE_LOOP: 407 num_primitives = count >= 2 ? count : 0; 408 break; 409 case GL_LINES: 410 num_primitives = count / 2; 411 break; 412 case GL_TRIANGLE_STRIP: 413 case GL_TRIANGLE_FAN: 414 case GL_POLYGON: 415 num_primitives = count >= 3 ? count - 2 : 0; 416 break; 417 case GL_TRIANGLES: 418 num_primitives = count / 3; 419 break; 420 case GL_QUAD_STRIP: 421 num_primitives = count >= 4 ? ((count / 2) - 1) * 2 : 0; 422 break; 423 case GL_QUADS: 424 num_primitives = (count / 4) * 2; 425 break; 426 case GL_LINES_ADJACENCY: 427 num_primitives = count / 4; 428 break; 429 case GL_LINE_STRIP_ADJACENCY: 430 num_primitives = count >= 4 ? count - 3 : 0; 431 break; 432 case GL_TRIANGLES_ADJACENCY: 433 num_primitives = count / 6; 434 break; 435 case GL_TRIANGLE_STRIP_ADJACENCY: 436 num_primitives = count >= 6 ? (count - 4) / 2 : 0; 437 break; 438 default: 439 assert(!"Unexpected primitive type in count_tessellated_primitives"); 440 num_primitives = 0; 441 break; 442 } 443 return num_primitives * num_instances; 444} 445 446 447static GLenum 448validate_draw_arrays(struct gl_context *ctx, 449 GLenum mode, GLsizei count, GLsizei numInstances) 450{ 451 if (count < 0 || numInstances < 0) 452 return GL_INVALID_VALUE; 453 454 GLenum error = _mesa_valid_prim_mode(ctx, mode); 455 if (error) 456 return error; 457 458 if (need_xfb_remaining_prims_check(ctx)) { 459 struct gl_transform_feedback_object *xfb_obj 460 = ctx->TransformFeedback.CurrentObject; 461 size_t prim_count = count_tessellated_primitives(mode, count, numInstances); 462 if (xfb_obj->GlesRemainingPrims < prim_count) 463 return GL_INVALID_OPERATION; 464 465 xfb_obj->GlesRemainingPrims -= prim_count; 466 } 467 468 return GL_NO_ERROR; 469} 470 471/** 472 * Called from the tnl module to error check the function parameters and 473 * verify that we really can draw something. 474 * \return GL_TRUE if OK to render, GL_FALSE if error found 475 */ 476static GLboolean 477_mesa_validate_DrawArrays(struct gl_context *ctx, GLenum mode, GLsizei count) 478{ 479 GLenum error = validate_draw_arrays(ctx, mode, count, 1); 480 481 if (error) 482 _mesa_error(ctx, error, "glDrawArrays"); 483 484 return !error; 485} 486 487 488static GLboolean 489_mesa_validate_DrawArraysInstanced(struct gl_context *ctx, GLenum mode, GLint first, 490 GLsizei count, GLsizei numInstances) 491{ 492 GLenum error; 493 494 if (first < 0) { 495 error = GL_INVALID_VALUE; 496 } else { 497 error = validate_draw_arrays(ctx, mode, count, numInstances); 498 } 499 500 if (error) 501 _mesa_error(ctx, error, "glDrawArraysInstanced"); 502 503 return !error; 504} 505 506 507/** 508 * Called to error check the function parameters. 509 * 510 * Note that glMultiDrawArrays is not part of GLES, so there's limited scope 511 * for sharing code with the validation of glDrawArrays. 512 */ 513static bool 514_mesa_validate_MultiDrawArrays(struct gl_context *ctx, GLenum mode, 515 const GLsizei *count, GLsizei primcount) 516{ 517 GLenum error; 518 519 if (primcount < 0) { 520 error = GL_INVALID_VALUE; 521 } else { 522 error = _mesa_valid_prim_mode(ctx, mode); 523 524 if (!error) { 525 for (int i = 0; i < primcount; ++i) { 526 if (count[i] < 0) { 527 error = GL_INVALID_VALUE; 528 break; 529 } 530 } 531 532 if (!error) { 533 if (need_xfb_remaining_prims_check(ctx)) { 534 struct gl_transform_feedback_object *xfb_obj 535 = ctx->TransformFeedback.CurrentObject; 536 size_t xfb_prim_count = 0; 537 538 for (int i = 0; i < primcount; ++i) { 539 xfb_prim_count += 540 count_tessellated_primitives(mode, count[i], 1); 541 } 542 543 if (xfb_obj->GlesRemainingPrims < xfb_prim_count) { 544 error = GL_INVALID_OPERATION; 545 } else { 546 xfb_obj->GlesRemainingPrims -= xfb_prim_count; 547 } 548 } 549 } 550 } 551 } 552 553 if (error) 554 _mesa_error(ctx, error, "glMultiDrawArrays"); 555 556 return !error; 557} 558 559 560static GLboolean 561_mesa_validate_DrawElementsInstanced(struct gl_context *ctx, 562 GLenum mode, GLsizei count, GLenum type, 563 GLsizei numInstances) 564{ 565 GLenum error = 566 validate_DrawElements_common(ctx, mode, count, numInstances, type); 567 568 if (error) 569 _mesa_error(ctx, error, "glDrawElementsInstanced"); 570 571 return !error; 572} 573 574 575static GLboolean 576_mesa_validate_DrawTransformFeedback(struct gl_context *ctx, 577 GLenum mode, 578 struct gl_transform_feedback_object *obj, 579 GLuint stream, 580 GLsizei numInstances) 581{ 582 GLenum error; 583 584 /* From the GL 4.5 specification, page 429: 585 * "An INVALID_VALUE error is generated if id is not the name of a 586 * transform feedback object." 587 */ 588 if (!obj || !obj->EverBound || stream >= ctx->Const.MaxVertexStreams || 589 numInstances < 0) { 590 error = GL_INVALID_VALUE; 591 } else { 592 error = _mesa_valid_prim_mode(ctx, mode); 593 594 if (!error) { 595 if (!obj->EndedAnytime) 596 error = GL_INVALID_OPERATION; 597 } 598 } 599 600 if (error) 601 _mesa_error(ctx, error, "glDrawTransformFeedback*"); 602 603 return !error; 604} 605 606static GLenum 607valid_draw_indirect(struct gl_context *ctx, 608 GLenum mode, const GLvoid *indirect, 609 GLsizei size) 610{ 611 const uint64_t end = (uint64_t) (uintptr_t) indirect + size; 612 613 /* OpenGL ES 3.1 spec. section 10.5: 614 * 615 * "DrawArraysIndirect requires that all data sourced for the 616 * command, including the DrawArraysIndirectCommand 617 * structure, be in buffer objects, and may not be called when 618 * the default vertex array object is bound." 619 */ 620 if (ctx->API != API_OPENGL_COMPAT && 621 ctx->Array.VAO == ctx->Array.DefaultVAO) 622 return GL_INVALID_OPERATION; 623 624 /* From OpenGL ES 3.1 spec. section 10.5: 625 * "An INVALID_OPERATION error is generated if zero is bound to 626 * VERTEX_ARRAY_BINDING, DRAW_INDIRECT_BUFFER or to any enabled 627 * vertex array." 628 * 629 * Here we check that for each enabled vertex array we have a vertex 630 * buffer bound. 631 */ 632 if (_mesa_is_gles31(ctx) && 633 ctx->Array.VAO->Enabled & ~ctx->Array.VAO->VertexAttribBufferMask) 634 return GL_INVALID_OPERATION; 635 636 GLenum error = _mesa_valid_prim_mode(ctx, mode); 637 if (error) 638 return error; 639 640 /* OpenGL ES 3.1 specification, section 10.5: 641 * 642 * "An INVALID_OPERATION error is generated if 643 * transform feedback is active and not paused." 644 * 645 * The OES_geometry_shader spec says: 646 * 647 * On p. 250 in the errors section for the DrawArraysIndirect command, 648 * and on p. 254 in the errors section for the DrawElementsIndirect 649 * command, delete the errors which state: 650 * 651 * "An INVALID_OPERATION error is generated if transform feedback is 652 * active and not paused." 653 * 654 * (thus allowing transform feedback to work with indirect draw commands). 655 */ 656 if (_mesa_is_gles31(ctx) && !ctx->Extensions.OES_geometry_shader && 657 _mesa_is_xfb_active_and_unpaused(ctx)) 658 return GL_INVALID_OPERATION; 659 660 /* From OpenGL version 4.4. section 10.5 661 * and OpenGL ES 3.1, section 10.6: 662 * 663 * "An INVALID_VALUE error is generated if indirect is not a 664 * multiple of the size, in basic machine units, of uint." 665 */ 666 if ((GLsizeiptr)indirect & (sizeof(GLuint) - 1)) 667 return GL_INVALID_VALUE; 668 669 if (!ctx->DrawIndirectBuffer) 670 return GL_INVALID_OPERATION; 671 672 if (_mesa_check_disallowed_mapping(ctx->DrawIndirectBuffer)) 673 return GL_INVALID_OPERATION; 674 675 /* From the ARB_draw_indirect specification: 676 * "An INVALID_OPERATION error is generated if the commands source data 677 * beyond the end of the buffer object [...]" 678 */ 679 if (ctx->DrawIndirectBuffer->Size < end) 680 return GL_INVALID_OPERATION; 681 682 return GL_NO_ERROR; 683} 684 685static inline GLenum 686valid_draw_indirect_elements(struct gl_context *ctx, 687 GLenum mode, GLenum type, const GLvoid *indirect, 688 GLsizeiptr size) 689{ 690 GLenum error = valid_elements_type(ctx, type); 691 if (error) 692 return error; 693 694 /* 695 * Unlike regular DrawElementsInstancedBaseVertex commands, the indices 696 * may not come from a client array and must come from an index buffer. 697 * If no element array buffer is bound, an INVALID_OPERATION error is 698 * generated. 699 */ 700 if (!ctx->Array.VAO->IndexBufferObj) 701 return GL_INVALID_OPERATION; 702 703 return valid_draw_indirect(ctx, mode, indirect, size); 704} 705 706static GLboolean 707_mesa_valid_draw_indirect_multi(struct gl_context *ctx, 708 GLsizei primcount, GLsizei stride, 709 const char *name) 710{ 711 712 /* From the ARB_multi_draw_indirect specification: 713 * "INVALID_VALUE is generated by MultiDrawArraysIndirect or 714 * MultiDrawElementsIndirect if <primcount> is negative." 715 * 716 * "<primcount> must be positive, otherwise an INVALID_VALUE error will 717 * be generated." 718 */ 719 if (primcount < 0) { 720 _mesa_error(ctx, GL_INVALID_VALUE, "%s(primcount < 0)", name); 721 return GL_FALSE; 722 } 723 724 725 /* From the ARB_multi_draw_indirect specification: 726 * "<stride> must be a multiple of four, otherwise an INVALID_VALUE 727 * error is generated." 728 */ 729 if (stride % 4) { 730 _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride %% 4)", name); 731 return GL_FALSE; 732 } 733 734 return GL_TRUE; 735} 736 737static GLboolean 738_mesa_validate_DrawArraysIndirect(struct gl_context *ctx, 739 GLenum mode, 740 const GLvoid *indirect) 741{ 742 const unsigned drawArraysNumParams = 4; 743 GLenum error = 744 valid_draw_indirect(ctx, mode, indirect, 745 drawArraysNumParams * sizeof(GLuint)); 746 747 if (error) 748 _mesa_error(ctx, error, "glDrawArraysIndirect"); 749 750 return !error; 751} 752 753static GLboolean 754_mesa_validate_DrawElementsIndirect(struct gl_context *ctx, 755 GLenum mode, GLenum type, 756 const GLvoid *indirect) 757{ 758 const unsigned drawElementsNumParams = 5; 759 GLenum error = valid_draw_indirect_elements(ctx, mode, type, indirect, 760 drawElementsNumParams * 761 sizeof(GLuint)); 762 if (error) 763 _mesa_error(ctx, error, "glDrawElementsIndirect"); 764 765 return !error; 766} 767 768static GLboolean 769_mesa_validate_MultiDrawArraysIndirect(struct gl_context *ctx, 770 GLenum mode, 771 const GLvoid *indirect, 772 GLsizei primcount, GLsizei stride) 773{ 774 GLsizeiptr size = 0; 775 const unsigned drawArraysNumParams = 4; 776 777 /* caller has converted stride==0 to drawArraysNumParams * sizeof(GLuint) */ 778 assert(stride != 0); 779 780 if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride, 781 "glMultiDrawArraysIndirect")) 782 return GL_FALSE; 783 784 /* number of bytes of the indirect buffer which will be read */ 785 size = primcount 786 ? (primcount - 1) * stride + drawArraysNumParams * sizeof(GLuint) 787 : 0; 788 789 GLenum error = valid_draw_indirect(ctx, mode, indirect, size); 790 if (error) 791 _mesa_error(ctx, error, "glMultiDrawArraysIndirect"); 792 793 return !error; 794} 795 796static GLboolean 797_mesa_validate_MultiDrawElementsIndirect(struct gl_context *ctx, 798 GLenum mode, GLenum type, 799 const GLvoid *indirect, 800 GLsizei primcount, GLsizei stride) 801{ 802 GLsizeiptr size = 0; 803 const unsigned drawElementsNumParams = 5; 804 805 /* caller has converted stride==0 to drawElementsNumParams * sizeof(GLuint) */ 806 assert(stride != 0); 807 808 if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride, 809 "glMultiDrawElementsIndirect")) 810 return GL_FALSE; 811 812 /* number of bytes of the indirect buffer which will be read */ 813 size = primcount 814 ? (primcount - 1) * stride + drawElementsNumParams * sizeof(GLuint) 815 : 0; 816 817 GLenum error = valid_draw_indirect_elements(ctx, mode, type, indirect, 818 size); 819 if (error) 820 _mesa_error(ctx, error, "glMultiDrawElementsIndirect"); 821 822 return !error; 823} 824 825static GLenum 826valid_draw_indirect_parameters(struct gl_context *ctx, 827 GLintptr drawcount) 828{ 829 /* From the ARB_indirect_parameters specification: 830 * "INVALID_VALUE is generated by MultiDrawArraysIndirectCountARB or 831 * MultiDrawElementsIndirectCountARB if <drawcount> is not a multiple of 832 * four." 833 */ 834 if (drawcount & 3) 835 return GL_INVALID_VALUE; 836 837 /* From the ARB_indirect_parameters specification: 838 * "INVALID_OPERATION is generated by MultiDrawArraysIndirectCountARB or 839 * MultiDrawElementsIndirectCountARB if no buffer is bound to the 840 * PARAMETER_BUFFER_ARB binding point." 841 */ 842 if (!ctx->ParameterBuffer) 843 return GL_INVALID_OPERATION; 844 845 if (_mesa_check_disallowed_mapping(ctx->ParameterBuffer)) 846 return GL_INVALID_OPERATION; 847 848 /* From the ARB_indirect_parameters specification: 849 * "INVALID_OPERATION is generated by MultiDrawArraysIndirectCountARB or 850 * MultiDrawElementsIndirectCountARB if reading a <sizei> typed value 851 * from the buffer bound to the PARAMETER_BUFFER_ARB target at the offset 852 * specified by <drawcount> would result in an out-of-bounds access." 853 */ 854 if (ctx->ParameterBuffer->Size < drawcount + sizeof(GLsizei)) 855 return GL_INVALID_OPERATION; 856 857 return GL_NO_ERROR; 858} 859 860static GLboolean 861_mesa_validate_MultiDrawArraysIndirectCount(struct gl_context *ctx, 862 GLenum mode, 863 GLintptr indirect, 864 GLintptr drawcount, 865 GLsizei maxdrawcount, 866 GLsizei stride) 867{ 868 GLsizeiptr size = 0; 869 const unsigned drawArraysNumParams = 4; 870 871 /* caller has converted stride==0 to drawArraysNumParams * sizeof(GLuint) */ 872 assert(stride != 0); 873 874 if (!_mesa_valid_draw_indirect_multi(ctx, maxdrawcount, stride, 875 "glMultiDrawArraysIndirectCountARB")) 876 return GL_FALSE; 877 878 /* number of bytes of the indirect buffer which will be read */ 879 size = maxdrawcount 880 ? (maxdrawcount - 1) * stride + drawArraysNumParams * sizeof(GLuint) 881 : 0; 882 883 GLenum error = valid_draw_indirect(ctx, mode, (void *)indirect, size); 884 if (!error) 885 error = valid_draw_indirect_parameters(ctx, drawcount); 886 887 if (error) 888 _mesa_error(ctx, error, "glMultiDrawArraysIndirectCountARB"); 889 890 return !error; 891} 892 893static GLboolean 894_mesa_validate_MultiDrawElementsIndirectCount(struct gl_context *ctx, 895 GLenum mode, GLenum type, 896 GLintptr indirect, 897 GLintptr drawcount, 898 GLsizei maxdrawcount, 899 GLsizei stride) 900{ 901 GLsizeiptr size = 0; 902 const unsigned drawElementsNumParams = 5; 903 904 /* caller has converted stride==0 to drawElementsNumParams * sizeof(GLuint) */ 905 assert(stride != 0); 906 907 if (!_mesa_valid_draw_indirect_multi(ctx, maxdrawcount, stride, 908 "glMultiDrawElementsIndirectCountARB")) 909 return GL_FALSE; 910 911 /* number of bytes of the indirect buffer which will be read */ 912 size = maxdrawcount 913 ? (maxdrawcount - 1) * stride + drawElementsNumParams * sizeof(GLuint) 914 : 0; 915 916 GLenum error = valid_draw_indirect_elements(ctx, mode, type, 917 (void *)indirect, size); 918 if (!error) 919 error = valid_draw_indirect_parameters(ctx, drawcount); 920 921 if (error) 922 _mesa_error(ctx, error, "glMultiDrawElementsIndirectCountARB"); 923 924 return !error; 925} 926 927 928#define MAX_ALLOCA_PRIMS(prim) (50000 / sizeof(*prim)) 929 930/* Use calloc for large allocations and alloca for small allocations. */ 931/* We have to use a macro because alloca is local within the function. */ 932#define ALLOC_PRIMS(prim, primcount, func) do { \ 933 if (unlikely(primcount > MAX_ALLOCA_PRIMS(prim))) { \ 934 prim = calloc(primcount, sizeof(*prim)); \ 935 if (!prim) { \ 936 _mesa_error(ctx, GL_OUT_OF_MEMORY, func); \ 937 return; \ 938 } \ 939 } else { \ 940 prim = alloca(primcount * sizeof(*prim)); \ 941 } \ 942} while (0) 943 944#define FREE_PRIMS(prim, primcount) do { \ 945 if (primcount > MAX_ALLOCA_PRIMS(prim)) \ 946 free(prim); \ 947} while (0) 948 949 950/** 951 * Called via Driver.DrawGallium. This is a fallback invoking Driver.Draw. 952 */ 953void 954_mesa_draw_gallium_fallback(struct gl_context *ctx, 955 struct pipe_draw_info *info, 956 unsigned drawid_offset, 957 const struct pipe_draw_start_count_bias *draws, 958 unsigned num_draws) 959{ 960 struct _mesa_index_buffer ib; 961 unsigned index_size = info->index_size; 962 unsigned min_index = 0, max_index = ~0u; 963 bool index_bounds_valid = false; 964 965 if (!info->instance_count) 966 return; 967 968 if (index_size) { 969 if (info->index_bounds_valid) { 970 min_index = info->min_index; 971 max_index = info->max_index; 972 index_bounds_valid = true; 973 } 974 } else { 975 /* The index_bounds_valid field and min/max_index are not used for 976 * non-indexed draw calls (they are undefined), but classic drivers 977 * need the index bounds. They will be computed manually. 978 */ 979 index_bounds_valid = true; 980 } 981 982 ib.index_size_shift = util_logbase2(index_size); 983 984 /* Single draw or a fallback for user indices. */ 985 if (num_draws == 1) { 986 if (!draws[0].count) 987 return; 988 989 if (index_size) { 990 ib.count = draws[0].count; 991 992 if (info->has_user_indices) { 993 ib.obj = NULL; 994 ib.ptr = (const char*)info->index.user; 995 } else { 996 ib.obj = info->index.gl_bo; 997 ib.ptr = NULL; 998 } 999 } 1000 1001 struct _mesa_prim prim; 1002 prim.mode = info->mode; 1003 prim.begin = 1; 1004 prim.end = 1; 1005 prim.start = draws[0].start; 1006 prim.count = draws[0].count; 1007 prim.basevertex = index_size ? draws[0].index_bias : 0; 1008 prim.draw_id = drawid_offset; 1009 1010 if (!index_size) { 1011 min_index = draws[0].start; 1012 max_index = draws[0].start + draws[0].count - 1; 1013 } 1014 1015 st_feedback_draw_vbo(ctx, &prim, 1, index_size ? &ib : NULL, 1016 index_bounds_valid, info->primitive_restart, 1017 info->restart_index, min_index, max_index, 1018 info->instance_count, info->start_instance); 1019 return; 1020 } 1021 1022 struct _mesa_prim *prim; 1023 unsigned max_count = 0; 1024 unsigned num_prims = 0; 1025 1026 ALLOC_PRIMS(prim, num_draws, "DrawGallium"); 1027 1028 min_index = ~0u; 1029 max_index = 0; 1030 1031 for (unsigned i = 0; i < num_draws; i++) { 1032 if (!draws[i].count) 1033 continue; 1034 1035 prim[num_prims].mode = info->mode; 1036 prim[num_prims].begin = 1; 1037 prim[num_prims].end = 1; 1038 prim[num_prims].start = draws[i].start; 1039 prim[num_prims].count = draws[i].count; 1040 prim[num_prims].basevertex = info->index_size ? draws[i].index_bias : 0; 1041 prim[num_prims].draw_id = drawid_offset + (info->increment_draw_id ? i : 0); 1042 1043 if (!index_size) { 1044 min_index = MIN2(min_index, draws[i].start); 1045 max_index = MAX2(max_index, draws[i].start + draws[i].count - 1); 1046 } 1047 1048 max_count = MAX2(max_count, prim[num_prims].count); 1049 num_prims++; 1050 } 1051 1052 if (info->index_size) { 1053 ib.count = max_count; 1054 ib.index_size_shift = util_logbase2(index_size); 1055 1056 if (info->has_user_indices) { 1057 ib.obj = NULL; 1058 ib.ptr = (const char*)info->index.user; 1059 } else { 1060 ib.obj = info->index.gl_bo; 1061 ib.ptr = NULL; 1062 } 1063 } 1064 1065 if (num_prims) 1066 st_feedback_draw_vbo(ctx, prim, num_prims, index_size ? &ib : NULL, 1067 index_bounds_valid, info->primitive_restart, 1068 info->restart_index, min_index, max_index, 1069 info->instance_count, info->start_instance); 1070 FREE_PRIMS(prim, num_draws); 1071} 1072 1073 1074/** 1075 * Called via Driver.DrawGallium. This is a fallback invoking Driver.Draw. 1076 */ 1077void 1078_mesa_draw_gallium_multimode_fallback(struct gl_context *ctx, 1079 struct pipe_draw_info *info, 1080 const struct pipe_draw_start_count_bias *draws, 1081 const unsigned char *mode, 1082 unsigned num_draws) 1083{ 1084 unsigned i, first; 1085 1086 /* Find consecutive draws where mode doesn't vary. */ 1087 for (i = 0, first = 0; i <= num_draws; i++) { 1088 if (i == num_draws || mode[i] != mode[first]) { 1089 info->mode = mode[first]; 1090 ctx->Driver.DrawGallium(ctx, info, 0, &draws[first], i - first); 1091 first = i; 1092 } 1093 } 1094} 1095 1096/** 1097 * Check that element 'j' of the array has reasonable data. 1098 * Map VBO if needed. 1099 * For debugging purposes; not normally used. 1100 */ 1101static void 1102check_array_data(struct gl_context *ctx, struct gl_vertex_array_object *vao, 1103 GLuint attrib, GLuint j) 1104{ 1105 const struct gl_array_attributes *array = &vao->VertexAttrib[attrib]; 1106 if (vao->Enabled & VERT_BIT(attrib)) { 1107 const struct gl_vertex_buffer_binding *binding = 1108 &vao->BufferBinding[array->BufferBindingIndex]; 1109 struct gl_buffer_object *bo = binding->BufferObj; 1110 const void *data = array->Ptr; 1111 if (bo) { 1112 data = ADD_POINTERS(_mesa_vertex_attrib_address(array, binding), 1113 bo->Mappings[MAP_INTERNAL].Pointer); 1114 } 1115 switch (array->Format.Type) { 1116 case GL_FLOAT: 1117 { 1118 GLfloat *f = (GLfloat *) ((GLubyte *) data + binding->Stride * j); 1119 GLint k; 1120 for (k = 0; k < array->Format.Size; k++) { 1121 if (util_is_inf_or_nan(f[k]) || f[k] >= 1.0e20F || f[k] <= -1.0e10F) { 1122 printf("Bad array data:\n"); 1123 printf(" Element[%u].%u = %f\n", j, k, f[k]); 1124 printf(" Array %u at %p\n", attrib, (void *) array); 1125 printf(" Type 0x%x, Size %d, Stride %d\n", 1126 array->Format.Type, array->Format.Size, 1127 binding->Stride); 1128 printf(" Address/offset %p in Buffer Object %u\n", 1129 array->Ptr, bo ? bo->Name : 0); 1130 f[k] = 1.0F; /* XXX replace the bad value! */ 1131 } 1132 /*assert(!util_is_inf_or_nan(f[k])); */ 1133 } 1134 } 1135 break; 1136 default: 1137 ; 1138 } 1139 } 1140} 1141 1142 1143static inline unsigned 1144get_index_size_shift(GLenum type) 1145{ 1146 /* The type is already validated, so use a fast conversion. 1147 * 1148 * GL_UNSIGNED_BYTE - GL_UNSIGNED_BYTE = 0 1149 * GL_UNSIGNED_SHORT - GL_UNSIGNED_BYTE = 2 1150 * GL_UNSIGNED_INT - GL_UNSIGNED_BYTE = 4 1151 * 1152 * Divide by 2 to get 0,1,2. 1153 */ 1154 return (type - GL_UNSIGNED_BYTE) >> 1; 1155} 1156 1157/** 1158 * Examine the array's data for NaNs, etc. 1159 * For debug purposes; not normally used. 1160 */ 1161static void 1162check_draw_elements_data(struct gl_context *ctx, GLsizei count, 1163 GLenum elemType, const void *elements, 1164 GLint basevertex) 1165{ 1166 struct gl_vertex_array_object *vao = ctx->Array.VAO; 1167 GLint i; 1168 GLuint k; 1169 1170 _mesa_vao_map(ctx, vao, GL_MAP_READ_BIT); 1171 1172 if (vao->IndexBufferObj) 1173 elements = 1174 ADD_POINTERS(vao->IndexBufferObj->Mappings[MAP_INTERNAL].Pointer, elements); 1175 1176 for (i = 0; i < count; i++) { 1177 GLuint j; 1178 1179 /* j = element[i] */ 1180 switch (elemType) { 1181 case GL_UNSIGNED_BYTE: 1182 j = ((const GLubyte *) elements)[i]; 1183 break; 1184 case GL_UNSIGNED_SHORT: 1185 j = ((const GLushort *) elements)[i]; 1186 break; 1187 case GL_UNSIGNED_INT: 1188 j = ((const GLuint *) elements)[i]; 1189 break; 1190 default: 1191 unreachable("Unexpected index buffer type"); 1192 } 1193 1194 /* check element j of each enabled array */ 1195 for (k = 0; k < VERT_ATTRIB_MAX; k++) { 1196 check_array_data(ctx, vao, k, j); 1197 } 1198 } 1199 1200 _mesa_vao_unmap(ctx, vao); 1201} 1202 1203 1204/** 1205 * Check array data, looking for NaNs, etc. 1206 */ 1207static void 1208check_draw_arrays_data(struct gl_context *ctx, GLint start, GLsizei count) 1209{ 1210 /* TO DO */ 1211} 1212 1213 1214/** 1215 * Print info/data for glDrawArrays(), for debugging. 1216 */ 1217static void 1218print_draw_arrays(struct gl_context *ctx, 1219 GLenum mode, GLint start, GLsizei count) 1220{ 1221 struct gl_vertex_array_object *vao = ctx->Array.VAO; 1222 1223 printf("_mesa_DrawArrays(mode 0x%x, start %d, count %d):\n", 1224 mode, start, count); 1225 1226 _mesa_vao_map_arrays(ctx, vao, GL_MAP_READ_BIT); 1227 1228 GLbitfield mask = vao->Enabled; 1229 while (mask) { 1230 const gl_vert_attrib i = u_bit_scan(&mask); 1231 const struct gl_array_attributes *array = &vao->VertexAttrib[i]; 1232 1233 const struct gl_vertex_buffer_binding *binding = 1234 &vao->BufferBinding[array->BufferBindingIndex]; 1235 struct gl_buffer_object *bufObj = binding->BufferObj; 1236 1237 printf("attr %s: size %d stride %d " 1238 "ptr %p Bufobj %u\n", 1239 gl_vert_attrib_name((gl_vert_attrib) i), 1240 array->Format.Size, binding->Stride, 1241 array->Ptr, bufObj ? bufObj->Name : 0); 1242 1243 if (bufObj) { 1244 GLubyte *p = bufObj->Mappings[MAP_INTERNAL].Pointer; 1245 int offset = (int) (GLintptr) 1246 _mesa_vertex_attrib_address(array, binding); 1247 1248 unsigned multiplier; 1249 switch (array->Format.Type) { 1250 case GL_DOUBLE: 1251 case GL_INT64_ARB: 1252 case GL_UNSIGNED_INT64_ARB: 1253 multiplier = 2; 1254 break; 1255 default: 1256 multiplier = 1; 1257 } 1258 1259 float *f = (float *) (p + offset); 1260 int *k = (int *) f; 1261 int i = 0; 1262 int n = (count - 1) * (binding->Stride / (4 * multiplier)) 1263 + array->Format.Size; 1264 if (n > 32) 1265 n = 32; 1266 printf(" Data at offset %d:\n", offset); 1267 do { 1268 if (multiplier == 2) 1269 printf(" double[%d] = 0x%016llx %lf\n", i, 1270 ((unsigned long long *) k)[i], ((double *) f)[i]); 1271 else 1272 printf(" float[%d] = 0x%08x %f\n", i, k[i], f[i]); 1273 i++; 1274 } while (i < n); 1275 } 1276 } 1277 1278 _mesa_vao_unmap_arrays(ctx, vao); 1279} 1280 1281 1282/** 1283 * Helper function called by the other DrawArrays() functions below. 1284 * This is where we handle primitive restart for drawing non-indexed 1285 * arrays. If primitive restart is enabled, it typically means 1286 * splitting one DrawArrays() into two. 1287 */ 1288static void 1289_mesa_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, 1290 GLsizei count, GLuint numInstances, GLuint baseInstance) 1291{ 1292 /* Viewperf has many draws with count=0. Discarding them is faster than 1293 * processing them. 1294 */ 1295 if (!count || !numInstances) 1296 return; 1297 1298 /* OpenGL 4.5 says that primitive restart is ignored with non-indexed 1299 * draws. 1300 */ 1301 struct pipe_draw_info info; 1302 struct pipe_draw_start_count_bias draw; 1303 1304 info.mode = mode; 1305 info.index_size = 0; 1306 /* Packed section begin. */ 1307 info.primitive_restart = false; 1308 info.has_user_indices = false; 1309 info.index_bounds_valid = true; 1310 info.increment_draw_id = false; 1311 info.was_line_loop = false; 1312 info.take_index_buffer_ownership = false; 1313 info.index_bias_varies = false; 1314 /* Packed section end. */ 1315 info.start_instance = baseInstance; 1316 info.instance_count = numInstances; 1317 info.view_mask = 0; 1318 info.min_index = start; 1319 info.max_index = start + count - 1; 1320 1321 draw.start = start; 1322 draw.count = count; 1323 1324 ctx->Driver.DrawGallium(ctx, &info, 0, &draw, 1); 1325 1326 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 1327 _mesa_flush(ctx); 1328 } 1329} 1330 1331 1332/** 1333 * Execute a glRectf() function. 1334 */ 1335void GLAPIENTRY 1336_mesa_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) 1337{ 1338 GET_CURRENT_CONTEXT(ctx); 1339 ASSERT_OUTSIDE_BEGIN_END(ctx); 1340 1341 CALL_Begin(ctx->CurrentServerDispatch, (GL_QUADS)); 1342 /* Begin can change CurrentServerDispatch. */ 1343 struct _glapi_table *dispatch = ctx->CurrentServerDispatch; 1344 CALL_Vertex2f(dispatch, (x1, y1)); 1345 CALL_Vertex2f(dispatch, (x2, y1)); 1346 CALL_Vertex2f(dispatch, (x2, y2)); 1347 CALL_Vertex2f(dispatch, (x1, y2)); 1348 CALL_End(dispatch, ()); 1349} 1350 1351 1352void GLAPIENTRY 1353_mesa_Rectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) 1354{ 1355 _mesa_Rectf((GLfloat) x1, (GLfloat) y1, (GLfloat) x2, (GLfloat) y2); 1356} 1357 1358void GLAPIENTRY 1359_mesa_Rectdv(const GLdouble *v1, const GLdouble *v2) 1360{ 1361 _mesa_Rectf((GLfloat) v1[0], (GLfloat) v1[1], (GLfloat) v2[0], (GLfloat) v2[1]); 1362} 1363 1364void GLAPIENTRY 1365_mesa_Rectfv(const GLfloat *v1, const GLfloat *v2) 1366{ 1367 _mesa_Rectf(v1[0], v1[1], v2[0], v2[1]); 1368} 1369 1370void GLAPIENTRY 1371_mesa_Recti(GLint x1, GLint y1, GLint x2, GLint y2) 1372{ 1373 _mesa_Rectf((GLfloat) x1, (GLfloat) y1, (GLfloat) x2, (GLfloat) y2); 1374} 1375 1376void GLAPIENTRY 1377_mesa_Rectiv(const GLint *v1, const GLint *v2) 1378{ 1379 _mesa_Rectf((GLfloat) v1[0], (GLfloat) v1[1], (GLfloat) v2[0], (GLfloat) v2[1]); 1380} 1381 1382void GLAPIENTRY 1383_mesa_Rects(GLshort x1, GLshort y1, GLshort x2, GLshort y2) 1384{ 1385 _mesa_Rectf((GLfloat) x1, (GLfloat) y1, (GLfloat) x2, (GLfloat) y2); 1386} 1387 1388void GLAPIENTRY 1389_mesa_Rectsv(const GLshort *v1, const GLshort *v2) 1390{ 1391 _mesa_Rectf((GLfloat) v1[0], (GLfloat) v1[1], (GLfloat) v2[0], (GLfloat) v2[1]); 1392} 1393 1394 1395void GLAPIENTRY 1396_mesa_EvalMesh1(GLenum mode, GLint i1, GLint i2) 1397{ 1398 GET_CURRENT_CONTEXT(ctx); 1399 GLint i; 1400 GLfloat u, du; 1401 GLenum prim; 1402 1403 switch (mode) { 1404 case GL_POINT: 1405 prim = GL_POINTS; 1406 break; 1407 case GL_LINE: 1408 prim = GL_LINE_STRIP; 1409 break; 1410 default: 1411 _mesa_error(ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)"); 1412 return; 1413 } 1414 1415 /* No effect if vertex maps disabled. 1416 */ 1417 if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3) 1418 return; 1419 1420 du = ctx->Eval.MapGrid1du; 1421 u = ctx->Eval.MapGrid1u1 + i1 * du; 1422 1423 1424 CALL_Begin(ctx->CurrentServerDispatch, (prim)); 1425 /* Begin can change CurrentServerDispatch. */ 1426 struct _glapi_table *dispatch = ctx->CurrentServerDispatch; 1427 for (i = i1; i <= i2; i++, u += du) { 1428 CALL_EvalCoord1f(dispatch, (u)); 1429 } 1430 CALL_End(dispatch, ()); 1431} 1432 1433 1434void GLAPIENTRY 1435_mesa_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) 1436{ 1437 GET_CURRENT_CONTEXT(ctx); 1438 GLfloat u, du, v, dv, v1, u1; 1439 GLint i, j; 1440 1441 switch (mode) { 1442 case GL_POINT: 1443 case GL_LINE: 1444 case GL_FILL: 1445 break; 1446 default: 1447 _mesa_error(ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)"); 1448 return; 1449 } 1450 1451 /* No effect if vertex maps disabled. 1452 */ 1453 if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3) 1454 return; 1455 1456 du = ctx->Eval.MapGrid2du; 1457 dv = ctx->Eval.MapGrid2dv; 1458 v1 = ctx->Eval.MapGrid2v1 + j1 * dv; 1459 u1 = ctx->Eval.MapGrid2u1 + i1 * du; 1460 1461 struct _glapi_table *dispatch; 1462 1463 switch (mode) { 1464 case GL_POINT: 1465 CALL_Begin(ctx->CurrentServerDispatch, (GL_POINTS)); 1466 /* Begin can change CurrentServerDispatch. */ 1467 dispatch = ctx->CurrentServerDispatch; 1468 for (v = v1, j = j1; j <= j2; j++, v += dv) { 1469 for (u = u1, i = i1; i <= i2; i++, u += du) { 1470 CALL_EvalCoord2f(dispatch, (u, v)); 1471 } 1472 } 1473 CALL_End(dispatch, ()); 1474 break; 1475 case GL_LINE: 1476 for (v = v1, j = j1; j <= j2; j++, v += dv) { 1477 CALL_Begin(ctx->CurrentServerDispatch, (GL_LINE_STRIP)); 1478 /* Begin can change CurrentServerDispatch. */ 1479 dispatch = ctx->CurrentServerDispatch; 1480 for (u = u1, i = i1; i <= i2; i++, u += du) { 1481 CALL_EvalCoord2f(dispatch, (u, v)); 1482 } 1483 CALL_End(dispatch, ()); 1484 } 1485 for (u = u1, i = i1; i <= i2; i++, u += du) { 1486 CALL_Begin(ctx->CurrentServerDispatch, (GL_LINE_STRIP)); 1487 /* Begin can change CurrentServerDispatch. */ 1488 dispatch = ctx->CurrentServerDispatch; 1489 for (v = v1, j = j1; j <= j2; j++, v += dv) { 1490 CALL_EvalCoord2f(dispatch, (u, v)); 1491 } 1492 CALL_End(dispatch, ()); 1493 } 1494 break; 1495 case GL_FILL: 1496 for (v = v1, j = j1; j < j2; j++, v += dv) { 1497 CALL_Begin(ctx->CurrentServerDispatch, (GL_TRIANGLE_STRIP)); 1498 /* Begin can change CurrentServerDispatch. */ 1499 dispatch = ctx->CurrentServerDispatch; 1500 for (u = u1, i = i1; i <= i2; i++, u += du) { 1501 CALL_EvalCoord2f(dispatch, (u, v)); 1502 CALL_EvalCoord2f(dispatch, (u, v + dv)); 1503 } 1504 CALL_End(dispatch, ()); 1505 } 1506 break; 1507 } 1508} 1509 1510 1511/** 1512 * Called from glDrawArrays when in immediate mode (not display list mode). 1513 */ 1514void GLAPIENTRY 1515_mesa_DrawArrays(GLenum mode, GLint start, GLsizei count) 1516{ 1517 GET_CURRENT_CONTEXT(ctx); 1518 FLUSH_FOR_DRAW(ctx); 1519 1520 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 1521 ctx->VertexProgram._VPModeInputFilter); 1522 1523 if (ctx->NewState) 1524 _mesa_update_state(ctx); 1525 1526 if (!_mesa_is_no_error_enabled(ctx) && 1527 !_mesa_validate_DrawArrays(ctx, mode, count)) 1528 return; 1529 1530 if (0) 1531 check_draw_arrays_data(ctx, start, count); 1532 1533 _mesa_draw_arrays(ctx, mode, start, count, 1, 0); 1534 1535 if (0) 1536 print_draw_arrays(ctx, mode, start, count); 1537} 1538 1539 1540/** 1541 * Called from glDrawArraysInstanced when in immediate mode (not 1542 * display list mode). 1543 */ 1544void GLAPIENTRY 1545_mesa_DrawArraysInstancedARB(GLenum mode, GLint start, GLsizei count, 1546 GLsizei numInstances) 1547{ 1548 GET_CURRENT_CONTEXT(ctx); 1549 FLUSH_FOR_DRAW(ctx); 1550 1551 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 1552 ctx->VertexProgram._VPModeInputFilter); 1553 1554 if (ctx->NewState) 1555 _mesa_update_state(ctx); 1556 1557 if (!_mesa_is_no_error_enabled(ctx) && 1558 !_mesa_validate_DrawArraysInstanced(ctx, mode, start, count, 1559 numInstances)) 1560 return; 1561 1562 if (0) 1563 check_draw_arrays_data(ctx, start, count); 1564 1565 _mesa_draw_arrays(ctx, mode, start, count, numInstances, 0); 1566 1567 if (0) 1568 print_draw_arrays(ctx, mode, start, count); 1569} 1570 1571 1572/** 1573 * Called from glDrawArraysInstancedBaseInstance when in immediate mode. 1574 */ 1575void GLAPIENTRY 1576_mesa_DrawArraysInstancedBaseInstance(GLenum mode, GLint first, 1577 GLsizei count, GLsizei numInstances, 1578 GLuint baseInstance) 1579{ 1580 GET_CURRENT_CONTEXT(ctx); 1581 FLUSH_FOR_DRAW(ctx); 1582 1583 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 1584 ctx->VertexProgram._VPModeInputFilter); 1585 1586 if (ctx->NewState) 1587 _mesa_update_state(ctx); 1588 1589 if (!_mesa_is_no_error_enabled(ctx) && 1590 !_mesa_validate_DrawArraysInstanced(ctx, mode, first, count, 1591 numInstances)) 1592 return; 1593 1594 if (0) 1595 check_draw_arrays_data(ctx, first, count); 1596 1597 _mesa_draw_arrays(ctx, mode, first, count, numInstances, baseInstance); 1598 1599 if (0) 1600 print_draw_arrays(ctx, mode, first, count); 1601} 1602 1603 1604/** 1605 * Called from glMultiDrawArrays when in immediate mode. 1606 */ 1607void GLAPIENTRY 1608_mesa_MultiDrawArrays(GLenum mode, const GLint *first, 1609 const GLsizei *count, GLsizei primcount) 1610{ 1611 GET_CURRENT_CONTEXT(ctx); 1612 FLUSH_FOR_DRAW(ctx); 1613 1614 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 1615 ctx->VertexProgram._VPModeInputFilter); 1616 1617 if (ctx->NewState) 1618 _mesa_update_state(ctx); 1619 1620 if (!_mesa_is_no_error_enabled(ctx) && 1621 !_mesa_validate_MultiDrawArrays(ctx, mode, count, primcount)) 1622 return; 1623 1624 if (primcount == 0) 1625 return; 1626 1627 struct pipe_draw_info info; 1628 struct pipe_draw_start_count_bias *draw; 1629 1630 ALLOC_PRIMS(draw, primcount, "glMultiDrawElements"); 1631 1632 info.mode = mode; 1633 info.index_size = 0; 1634 /* Packed section begin. */ 1635 info.primitive_restart = false; 1636 info.has_user_indices = false; 1637 info.index_bounds_valid = false; 1638 info.increment_draw_id = primcount > 1; 1639 info.was_line_loop = false; 1640 info.take_index_buffer_ownership = false; 1641 info.index_bias_varies = false; 1642 /* Packed section end. */ 1643 info.start_instance = 0; 1644 info.instance_count = 1; 1645 info.view_mask = 0; 1646 1647 for (int i = 0; i < primcount; i++) { 1648 draw[i].start = first[i]; 1649 draw[i].count = count[i]; 1650 } 1651 1652 ctx->Driver.DrawGallium(ctx, &info, 0, draw, primcount); 1653 1654 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) 1655 _mesa_flush(ctx); 1656 1657 FREE_PRIMS(draw, primcount); 1658} 1659 1660 1661 1662/** 1663 * Map GL_ELEMENT_ARRAY_BUFFER and print contents. 1664 * For debugging. 1665 */ 1666#if 0 1667static void 1668dump_element_buffer(struct gl_context *ctx, GLenum type) 1669{ 1670 const GLvoid *map = 1671 ctx->Driver.MapBufferRange(ctx, 0, 1672 ctx->Array.VAO->IndexBufferObj->Size, 1673 GL_MAP_READ_BIT, 1674 ctx->Array.VAO->IndexBufferObj, 1675 MAP_INTERNAL); 1676 switch (type) { 1677 case GL_UNSIGNED_BYTE: 1678 { 1679 const GLubyte *us = (const GLubyte *) map; 1680 GLint i; 1681 for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size; i++) { 1682 printf("%02x ", us[i]); 1683 if (i % 32 == 31) 1684 printf("\n"); 1685 } 1686 printf("\n"); 1687 } 1688 break; 1689 case GL_UNSIGNED_SHORT: 1690 { 1691 const GLushort *us = (const GLushort *) map; 1692 GLint i; 1693 for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size / 2; i++) { 1694 printf("%04x ", us[i]); 1695 if (i % 16 == 15) 1696 printf("\n"); 1697 } 1698 printf("\n"); 1699 } 1700 break; 1701 case GL_UNSIGNED_INT: 1702 { 1703 const GLuint *us = (const GLuint *) map; 1704 GLint i; 1705 for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size / 4; i++) { 1706 printf("%08x ", us[i]); 1707 if (i % 8 == 7) 1708 printf("\n"); 1709 } 1710 printf("\n"); 1711 } 1712 break; 1713 default: 1714 ; 1715 } 1716 1717 ctx->Driver.UnmapBuffer(ctx, ctx->Array.VAO->IndexBufferObj, MAP_INTERNAL); 1718} 1719#endif 1720 1721 1722/** 1723 * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements. 1724 * Do the rendering for a glDrawElements or glDrawRangeElements call after 1725 * we've validated buffer bounds, etc. 1726 */ 1727static void 1728_mesa_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, 1729 bool index_bounds_valid, 1730 GLuint start, GLuint end, 1731 GLsizei count, GLenum type, 1732 const GLvoid * indices, 1733 GLint basevertex, GLuint numInstances, 1734 GLuint baseInstance) 1735{ 1736 /* Viewperf has many draws with count=0. Discarding them is faster than 1737 * processing them. 1738 */ 1739 if (!count || !numInstances) 1740 return; 1741 1742 if (!index_bounds_valid) { 1743 assert(start == 0u); 1744 assert(end == ~0u); 1745 } 1746 1747 struct pipe_draw_info info; 1748 struct pipe_draw_start_count_bias draw; 1749 unsigned index_size_shift = get_index_size_shift(type); 1750 struct gl_buffer_object *index_bo = ctx->Array.VAO->IndexBufferObj; 1751 1752 if (index_bo && !indices_aligned(index_size_shift, indices)) 1753 return; 1754 1755 info.mode = mode; 1756 info.index_size = 1 << index_size_shift; 1757 /* Packed section begin. */ 1758 info.primitive_restart = ctx->Array._PrimitiveRestart[index_size_shift]; 1759 info.has_user_indices = index_bo == NULL; 1760 info.index_bounds_valid = index_bounds_valid; 1761 info.increment_draw_id = false; 1762 info.was_line_loop = false; 1763 info.take_index_buffer_ownership = false; 1764 info.index_bias_varies = false; 1765 /* Packed section end. */ 1766 info.start_instance = baseInstance; 1767 info.instance_count = numInstances; 1768 info.view_mask = 0; 1769 info.restart_index = ctx->Array._RestartIndex[index_size_shift]; 1770 1771 if (info.has_user_indices) { 1772 info.index.user = indices; 1773 draw.start = 0; 1774 } else { 1775 uintptr_t start = (uintptr_t) indices; 1776 if (unlikely(index_bo->Size < start)) { 1777 _mesa_warning(ctx, "Invalid indices offset 0x%" PRIxPTR 1778 " (indices buffer size is %ld bytes)." 1779 " Draw skipped.", start, index_bo->Size); 1780 return; 1781 } 1782 info.index.gl_bo = index_bo; 1783 draw.start = start >> index_size_shift; 1784 } 1785 draw.index_bias = basevertex; 1786 1787 info.min_index = start; 1788 info.max_index = end; 1789 draw.count = count; 1790 1791 /* Need to give special consideration to rendering a range of 1792 * indices starting somewhere above zero. Typically the 1793 * application is issuing multiple DrawRangeElements() to draw 1794 * successive primitives layed out linearly in the vertex arrays. 1795 * Unless the vertex arrays are all in a VBO (or locked as with 1796 * CVA), the OpenGL semantics imply that we need to re-read or 1797 * re-upload the vertex data on each draw call. 1798 * 1799 * In the case of hardware tnl, we want to avoid starting the 1800 * upload at zero, as it will mean every draw call uploads an 1801 * increasing amount of not-used vertex data. Worse - in the 1802 * software tnl module, all those vertices might be transformed and 1803 * lit but never rendered. 1804 * 1805 * If we just upload or transform the vertices in start..end, 1806 * however, the indices will be incorrect. 1807 * 1808 * At this level, we don't know exactly what the requirements of 1809 * the backend are going to be, though it will likely boil down to 1810 * either: 1811 * 1812 * 1) Do nothing, everything is in a VBO and is processed once 1813 * only. 1814 * 1815 * 2) Adjust the indices and vertex arrays so that start becomes 1816 * zero. 1817 * 1818 * Rather than doing anything here, I'll provide a helper function 1819 * for the latter case elsewhere. 1820 */ 1821 1822 ctx->Driver.DrawGallium(ctx, &info, 0, &draw, 1); 1823 1824 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 1825 _mesa_flush(ctx); 1826 } 1827} 1828 1829 1830/** 1831 * Called by glDrawRangeElementsBaseVertex() in immediate mode. 1832 */ 1833void GLAPIENTRY 1834_mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, 1835 GLsizei count, GLenum type, 1836 const GLvoid * indices, GLint basevertex) 1837{ 1838 static GLuint warnCount = 0; 1839 bool index_bounds_valid = true; 1840 1841 /* This is only useful to catch invalid values in the "end" parameter 1842 * like ~0. 1843 */ 1844 GLuint max_element = 2 * 1000 * 1000 * 1000; /* just a big number */ 1845 1846 GET_CURRENT_CONTEXT(ctx); 1847 FLUSH_FOR_DRAW(ctx); 1848 1849 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 1850 ctx->VertexProgram._VPModeInputFilter); 1851 1852 if (ctx->NewState) 1853 _mesa_update_state(ctx); 1854 1855 if (!_mesa_is_no_error_enabled(ctx) && 1856 !_mesa_validate_DrawRangeElements(ctx, mode, start, end, count, 1857 type)) 1858 return; 1859 1860 if ((int) end + basevertex < 0 || start + basevertex >= max_element) { 1861 /* The application requested we draw using a range of indices that's 1862 * outside the bounds of the current VBO. This is invalid and appears 1863 * to give undefined results. The safest thing to do is to simply 1864 * ignore the range, in case the application botched their range tracking 1865 * but did provide valid indices. Also issue a warning indicating that 1866 * the application is broken. 1867 */ 1868 if (warnCount++ < 10) { 1869 _mesa_warning(ctx, "glDrawRangeElements(start %u, end %u, " 1870 "basevertex %d, count %d, type 0x%x, indices=%p):\n" 1871 "\trange is outside VBO bounds (max=%u); ignoring.\n" 1872 "\tThis should be fixed in the application.", 1873 start, end, basevertex, count, type, indices, 1874 max_element - 1); 1875 } 1876 index_bounds_valid = false; 1877 } 1878 1879 /* NOTE: It's important that 'end' is a reasonable value. 1880 * in _tnl_draw_prims(), we use end to determine how many vertices 1881 * to transform. If it's too large, we can unnecessarily split prims 1882 * or we can read/write out of memory in several different places! 1883 */ 1884 1885 /* Catch/fix some potential user errors */ 1886 if (type == GL_UNSIGNED_BYTE) { 1887 start = MIN2(start, 0xff); 1888 end = MIN2(end, 0xff); 1889 } 1890 else if (type == GL_UNSIGNED_SHORT) { 1891 start = MIN2(start, 0xffff); 1892 end = MIN2(end, 0xffff); 1893 } 1894 1895 if (0) { 1896 printf("glDraw[Range]Elements{,BaseVertex}" 1897 "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, " 1898 "base %d\n", 1899 start, end, type, count, 1900 ctx->Array.VAO->IndexBufferObj ? 1901 ctx->Array.VAO->IndexBufferObj->Name : 0, basevertex); 1902 } 1903 1904 if ((int) start + basevertex < 0 || end + basevertex >= max_element) 1905 index_bounds_valid = false; 1906 1907#if 0 1908 check_draw_elements_data(ctx, count, type, indices, basevertex); 1909#else 1910 (void) check_draw_elements_data; 1911#endif 1912 1913 if (!index_bounds_valid) { 1914 start = 0; 1915 end = ~0; 1916 } 1917 1918 _mesa_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end, 1919 count, type, indices, basevertex, 1, 0); 1920} 1921 1922 1923/** 1924 * Called by glDrawRangeElements() in immediate mode. 1925 */ 1926void GLAPIENTRY 1927_mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, 1928 GLsizei count, GLenum type, const GLvoid * indices) 1929{ 1930 _mesa_DrawRangeElementsBaseVertex(mode, start, end, count, type, 1931 indices, 0); 1932} 1933 1934 1935/** 1936 * Called by glDrawElements() in immediate mode. 1937 */ 1938void GLAPIENTRY 1939_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, 1940 const GLvoid * indices) 1941{ 1942 GET_CURRENT_CONTEXT(ctx); 1943 FLUSH_FOR_DRAW(ctx); 1944 1945 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 1946 ctx->VertexProgram._VPModeInputFilter); 1947 1948 if (ctx->NewState) 1949 _mesa_update_state(ctx); 1950 1951 if (!_mesa_is_no_error_enabled(ctx) && 1952 !_mesa_validate_DrawElements(ctx, mode, count, type)) 1953 return; 1954 1955 _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0, 1956 count, type, indices, 0, 1, 0); 1957} 1958 1959 1960/** 1961 * Called by glDrawElementsBaseVertex() in immediate mode. 1962 */ 1963void GLAPIENTRY 1964_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, 1965 const GLvoid * indices, GLint basevertex) 1966{ 1967 GET_CURRENT_CONTEXT(ctx); 1968 FLUSH_FOR_DRAW(ctx); 1969 1970 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 1971 ctx->VertexProgram._VPModeInputFilter); 1972 1973 if (ctx->NewState) 1974 _mesa_update_state(ctx); 1975 1976 if (!_mesa_is_no_error_enabled(ctx) && 1977 !_mesa_validate_DrawElements(ctx, mode, count, type)) 1978 return; 1979 1980 _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0, 1981 count, type, indices, basevertex, 1, 0); 1982} 1983 1984 1985/** 1986 * Called by glDrawElementsInstanced() in immediate mode. 1987 */ 1988void GLAPIENTRY 1989_mesa_DrawElementsInstancedARB(GLenum mode, GLsizei count, GLenum type, 1990 const GLvoid * indices, GLsizei numInstances) 1991{ 1992 GET_CURRENT_CONTEXT(ctx); 1993 FLUSH_FOR_DRAW(ctx); 1994 1995 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 1996 ctx->VertexProgram._VPModeInputFilter); 1997 1998 if (ctx->NewState) 1999 _mesa_update_state(ctx); 2000 2001 if (!_mesa_is_no_error_enabled(ctx) && 2002 !_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, 2003 numInstances)) 2004 return; 2005 2006 _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0, 2007 count, type, indices, 0, numInstances, 0); 2008} 2009 2010 2011/** 2012 * Called by glDrawElementsInstancedBaseVertex() in immediate mode. 2013 */ 2014void GLAPIENTRY 2015_mesa_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, 2016 GLenum type, const GLvoid * indices, 2017 GLsizei numInstances, 2018 GLint basevertex) 2019{ 2020 GET_CURRENT_CONTEXT(ctx); 2021 FLUSH_FOR_DRAW(ctx); 2022 2023 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 2024 ctx->VertexProgram._VPModeInputFilter); 2025 2026 if (ctx->NewState) 2027 _mesa_update_state(ctx); 2028 2029 if (!_mesa_is_no_error_enabled(ctx) && 2030 !_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, 2031 numInstances)) 2032 return; 2033 2034 _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0, 2035 count, type, indices, 2036 basevertex, numInstances, 0); 2037} 2038 2039 2040/** 2041 * Called by glDrawElementsInstancedBaseInstance() in immediate mode. 2042 */ 2043void GLAPIENTRY 2044_mesa_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, 2045 GLenum type, 2046 const GLvoid *indices, 2047 GLsizei numInstances, 2048 GLuint baseInstance) 2049{ 2050 GET_CURRENT_CONTEXT(ctx); 2051 FLUSH_FOR_DRAW(ctx); 2052 2053 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 2054 ctx->VertexProgram._VPModeInputFilter); 2055 2056 if (ctx->NewState) 2057 _mesa_update_state(ctx); 2058 2059 if (!_mesa_is_no_error_enabled(ctx) && 2060 !_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, 2061 numInstances)) 2062 return; 2063 2064 _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0, 2065 count, type, indices, 0, numInstances, 2066 baseInstance); 2067} 2068 2069 2070/** 2071 * Called by glDrawElementsInstancedBaseVertexBaseInstance() in immediate mode. 2072 */ 2073void GLAPIENTRY 2074_mesa_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, 2075 GLsizei count, 2076 GLenum type, 2077 const GLvoid *indices, 2078 GLsizei numInstances, 2079 GLint basevertex, 2080 GLuint baseInstance) 2081{ 2082 GET_CURRENT_CONTEXT(ctx); 2083 FLUSH_FOR_DRAW(ctx); 2084 2085 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 2086 ctx->VertexProgram._VPModeInputFilter); 2087 2088 if (ctx->NewState) 2089 _mesa_update_state(ctx); 2090 2091 if (!_mesa_is_no_error_enabled(ctx) && 2092 !_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, 2093 numInstances)) 2094 return; 2095 2096 _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0, 2097 count, type, indices, basevertex, 2098 numInstances, baseInstance); 2099} 2100 2101 2102/** 2103 * Inner support for both _mesa_MultiDrawElements() and 2104 * _mesa_MultiDrawRangeElements(). 2105 * This does the actual rendering after we've checked array indexes, etc. 2106 */ 2107static void 2108_mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, 2109 const GLsizei *count, GLenum type, 2110 const GLvoid * const *indices, 2111 GLsizei primcount, const GLint *basevertex) 2112{ 2113 uintptr_t min_index_ptr, max_index_ptr; 2114 bool fallback = false; 2115 int i; 2116 2117 if (primcount == 0) 2118 return; 2119 2120 unsigned index_size_shift = get_index_size_shift(type); 2121 2122 min_index_ptr = (uintptr_t) indices[0]; 2123 max_index_ptr = 0; 2124 for (i = 0; i < primcount; i++) { 2125 min_index_ptr = MIN2(min_index_ptr, (uintptr_t) indices[i]); 2126 max_index_ptr = MAX2(max_index_ptr, (uintptr_t) indices[i] + 2127 (count[i] << index_size_shift)); 2128 } 2129 2130 /* Check if we can handle this thing as a bunch of index offsets from the 2131 * same index pointer. If we can't, then we have to fall back to doing 2132 * a draw_prims per primitive. 2133 * Check that the difference between each prim's indexes is a multiple of 2134 * the index/element size. 2135 */ 2136 if (index_size_shift) { 2137 for (i = 0; i < primcount; i++) { 2138 if ((((uintptr_t) indices[i] - min_index_ptr) & 2139 ((1 << index_size_shift) - 1)) != 0) { 2140 fallback = true; 2141 break; 2142 } 2143 } 2144 } 2145 2146 struct gl_buffer_object *index_bo = ctx->Array.VAO->IndexBufferObj; 2147 struct pipe_draw_info info; 2148 2149 info.mode = mode; 2150 info.index_size = 1 << index_size_shift; 2151 /* Packed section begin. */ 2152 info.primitive_restart = ctx->Array._PrimitiveRestart[index_size_shift]; 2153 info.has_user_indices = index_bo == NULL; 2154 info.index_bounds_valid = false; 2155 info.increment_draw_id = primcount > 1; 2156 info.was_line_loop = false; 2157 info.take_index_buffer_ownership = false; 2158 info.index_bias_varies = !!basevertex; 2159 /* Packed section end. */ 2160 info.start_instance = 0; 2161 info.instance_count = 1; 2162 info.view_mask = 0; 2163 info.restart_index = ctx->Array._RestartIndex[index_size_shift]; 2164 2165 if (info.has_user_indices) 2166 info.index.user = (void*)min_index_ptr; 2167 else 2168 info.index.gl_bo = index_bo; 2169 2170 if (!fallback && 2171 (!info.has_user_indices || 2172 /* "max_index_ptr - min_index_ptr >> index_size_shift" is stored 2173 * in draw[i].start. The driver will multiply it later by index_size 2174 * so make sure the final value won't overflow. 2175 * 2176 * For real index buffers, gallium doesn't support index buffer offsets 2177 * greater than UINT32_MAX bytes. 2178 */ 2179 max_index_ptr - min_index_ptr <= UINT32_MAX)) { 2180 struct pipe_draw_start_count_bias *draw; 2181 2182 ALLOC_PRIMS(draw, primcount, "glMultiDrawElements"); 2183 2184 if (info.has_user_indices) { 2185 for (int i = 0; i < primcount; i++) { 2186 draw[i].start = 2187 ((uintptr_t)indices[i] - min_index_ptr) >> index_size_shift; 2188 draw[i].count = count[i]; 2189 draw[i].index_bias = basevertex ? basevertex[i] : 0; 2190 } 2191 } else { 2192 for (int i = 0; i < primcount; i++) { 2193 draw[i].start = (uintptr_t)indices[i] >> index_size_shift; 2194 draw[i].count = 2195 indices_aligned(index_size_shift, indices[i]) ? count[i] : 0; 2196 draw[i].index_bias = basevertex ? basevertex[i] : 0; 2197 } 2198 } 2199 2200 ctx->Driver.DrawGallium(ctx, &info, 0, draw, primcount); 2201 FREE_PRIMS(draw, primcount); 2202 } else { 2203 /* draw[i].start would overflow. Draw one at a time. */ 2204 assert(info.has_user_indices); 2205 info.increment_draw_id = false; 2206 2207 for (int i = 0; i < primcount; i++) { 2208 struct pipe_draw_start_count_bias draw; 2209 2210 if (!count[i]) 2211 continue; 2212 2213 /* Reset these, because the callee can change them. */ 2214 info.index_bounds_valid = false; 2215 info.index.user = indices[i]; 2216 draw.start = 0; 2217 draw.index_bias = basevertex ? basevertex[i] : 0; 2218 draw.count = count[i]; 2219 2220 ctx->Driver.DrawGallium(ctx, &info, i, &draw, 1); 2221 } 2222 } 2223 2224 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 2225 _mesa_flush(ctx); 2226 } 2227} 2228 2229 2230void GLAPIENTRY 2231_mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type, 2232 const GLvoid * const *indices, GLsizei primcount) 2233{ 2234 GET_CURRENT_CONTEXT(ctx); 2235 FLUSH_FOR_DRAW(ctx); 2236 2237 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 2238 ctx->VertexProgram._VPModeInputFilter); 2239 2240 if (ctx->NewState) 2241 _mesa_update_state(ctx); 2242 2243 if (!_mesa_is_no_error_enabled(ctx) && 2244 !_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices, 2245 primcount)) 2246 return; 2247 2248 _mesa_validated_multidrawelements(ctx, mode, count, type, indices, primcount, 2249 NULL); 2250} 2251 2252 2253void GLAPIENTRY 2254_mesa_MultiDrawElementsBaseVertex(GLenum mode, 2255 const GLsizei *count, GLenum type, 2256 const GLvoid * const *indices, 2257 GLsizei primcount, 2258 const GLsizei *basevertex) 2259{ 2260 GET_CURRENT_CONTEXT(ctx); 2261 FLUSH_FOR_DRAW(ctx); 2262 2263 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 2264 ctx->VertexProgram._VPModeInputFilter); 2265 2266 if (ctx->NewState) 2267 _mesa_update_state(ctx); 2268 2269 if (!_mesa_is_no_error_enabled(ctx) && 2270 !_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices, 2271 primcount)) 2272 return; 2273 2274 _mesa_validated_multidrawelements(ctx, mode, count, type, indices, primcount, 2275 basevertex); 2276} 2277 2278 2279/** 2280 * Draw a GL primitive using a vertex count obtained from transform feedback. 2281 * \param mode the type of GL primitive to draw 2282 * \param obj the transform feedback object to use 2283 * \param stream index of the transform feedback stream from which to 2284 * get the primitive count. 2285 * \param numInstances number of instances to draw 2286 */ 2287static void 2288_mesa_draw_transform_feedback(struct gl_context *ctx, GLenum mode, 2289 struct gl_transform_feedback_object *obj, 2290 GLuint stream, GLuint numInstances) 2291{ 2292 FLUSH_FOR_DRAW(ctx); 2293 2294 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 2295 ctx->VertexProgram._VPModeInputFilter); 2296 2297 if (ctx->NewState) 2298 _mesa_update_state(ctx); 2299 2300 if (!_mesa_is_no_error_enabled(ctx) && 2301 !_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream, 2302 numInstances)) 2303 return; 2304 2305 /* Maybe we should do some primitive splitting for primitive restart 2306 * (like in DrawArrays), but we have no way to know how many vertices 2307 * will be rendered. */ 2308 2309 st_draw_transform_feedback(ctx, mode, numInstances, stream, obj); 2310 2311 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { 2312 _mesa_flush(ctx); 2313 } 2314} 2315 2316 2317/** 2318 * Like DrawArrays, but take the count from a transform feedback object. 2319 * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc. 2320 * \param name the transform feedback object 2321 * User still has to setup of the vertex attribute info with 2322 * glVertexPointer, glColorPointer, etc. 2323 * Part of GL_ARB_transform_feedback2. 2324 */ 2325void GLAPIENTRY 2326_mesa_DrawTransformFeedback(GLenum mode, GLuint name) 2327{ 2328 GET_CURRENT_CONTEXT(ctx); 2329 struct gl_transform_feedback_object *obj = 2330 _mesa_lookup_transform_feedback_object(ctx, name); 2331 2332 _mesa_draw_transform_feedback(ctx, mode, obj, 0, 1); 2333} 2334 2335 2336void GLAPIENTRY 2337_mesa_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream) 2338{ 2339 GET_CURRENT_CONTEXT(ctx); 2340 struct gl_transform_feedback_object *obj = 2341 _mesa_lookup_transform_feedback_object(ctx, name); 2342 2343 _mesa_draw_transform_feedback(ctx, mode, obj, stream, 1); 2344} 2345 2346 2347void GLAPIENTRY 2348_mesa_DrawTransformFeedbackInstanced(GLenum mode, GLuint name, 2349 GLsizei primcount) 2350{ 2351 GET_CURRENT_CONTEXT(ctx); 2352 struct gl_transform_feedback_object *obj = 2353 _mesa_lookup_transform_feedback_object(ctx, name); 2354 2355 _mesa_draw_transform_feedback(ctx, mode, obj, 0, primcount); 2356} 2357 2358 2359void GLAPIENTRY 2360_mesa_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name, 2361 GLuint stream, 2362 GLsizei primcount) 2363{ 2364 GET_CURRENT_CONTEXT(ctx); 2365 struct gl_transform_feedback_object *obj = 2366 _mesa_lookup_transform_feedback_object(ctx, name); 2367 2368 _mesa_draw_transform_feedback(ctx, mode, obj, stream, primcount); 2369} 2370 2371 2372static void 2373_mesa_validated_multidrawarraysindirect(struct gl_context *ctx, GLenum mode, 2374 GLintptr indirect, 2375 GLintptr drawcount_offset, 2376 GLsizei drawcount, GLsizei stride, 2377 struct gl_buffer_object *drawcount_buffer) 2378{ 2379 /* If drawcount_buffer is set, drawcount is the maximum draw count.*/ 2380 if (drawcount == 0) 2381 return; 2382 2383 st_indirect_draw_vbo(ctx, mode, ctx->DrawIndirectBuffer, indirect, 2384 drawcount, stride, drawcount_buffer, 2385 drawcount_offset, NULL, false, 0); 2386 2387 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) 2388 _mesa_flush(ctx); 2389} 2390 2391 2392static void 2393_mesa_validated_multidrawelementsindirect(struct gl_context *ctx, 2394 GLenum mode, GLenum type, 2395 GLintptr indirect, 2396 GLintptr drawcount_offset, 2397 GLsizei drawcount, GLsizei stride, 2398 struct gl_buffer_object *drawcount_buffer) 2399{ 2400 /* If drawcount_buffer is set, drawcount is the maximum draw count.*/ 2401 if (drawcount == 0) 2402 return; 2403 2404 /* NOTE: IndexBufferObj is guaranteed to be a VBO. */ 2405 struct _mesa_index_buffer ib; 2406 ib.count = 0; /* unknown */ 2407 ib.obj = ctx->Array.VAO->IndexBufferObj; 2408 ib.ptr = NULL; 2409 ib.index_size_shift = get_index_size_shift(type); 2410 2411 st_indirect_draw_vbo(ctx, mode, ctx->DrawIndirectBuffer, indirect, 2412 drawcount, stride, drawcount_buffer, 2413 drawcount_offset, &ib, 2414 ctx->Array._PrimitiveRestart[ib.index_size_shift], 2415 ctx->Array._RestartIndex[ib.index_size_shift]); 2416 2417 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) 2418 _mesa_flush(ctx); 2419} 2420 2421 2422/** 2423 * Like [Multi]DrawArrays/Elements, but they take most arguments from 2424 * a buffer object. 2425 */ 2426void GLAPIENTRY 2427_mesa_DrawArraysIndirect(GLenum mode, const GLvoid *indirect) 2428{ 2429 GET_CURRENT_CONTEXT(ctx); 2430 2431 /* From the ARB_draw_indirect spec: 2432 * 2433 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the 2434 * compatibility profile, this indicates that DrawArraysIndirect and 2435 * DrawElementsIndirect are to source their arguments directly from the 2436 * pointer passed as their <indirect> parameters." 2437 */ 2438 if (ctx->API == API_OPENGL_COMPAT && 2439 !ctx->DrawIndirectBuffer) { 2440 DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) indirect; 2441 2442 _mesa_DrawArraysInstancedBaseInstance(mode, cmd->first, cmd->count, 2443 cmd->primCount, 2444 cmd->baseInstance); 2445 return; 2446 } 2447 2448 FLUSH_FOR_DRAW(ctx); 2449 2450 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 2451 ctx->VertexProgram._VPModeInputFilter); 2452 2453 if (ctx->NewState) 2454 _mesa_update_state(ctx); 2455 2456 if (!_mesa_is_no_error_enabled(ctx) && 2457 !_mesa_validate_DrawArraysIndirect(ctx, mode, indirect)) 2458 return; 2459 2460 _mesa_validated_multidrawarraysindirect(ctx, mode, (GLintptr)indirect, 2461 0, 1, 16, NULL); 2462} 2463 2464 2465void GLAPIENTRY 2466_mesa_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect) 2467{ 2468 GET_CURRENT_CONTEXT(ctx); 2469 2470 /* From the ARB_draw_indirect spec: 2471 * 2472 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the 2473 * compatibility profile, this indicates that DrawArraysIndirect and 2474 * DrawElementsIndirect are to source their arguments directly from the 2475 * pointer passed as their <indirect> parameters." 2476 */ 2477 if (ctx->API == API_OPENGL_COMPAT && 2478 !ctx->DrawIndirectBuffer) { 2479 /* 2480 * Unlike regular DrawElementsInstancedBaseVertex commands, the indices 2481 * may not come from a client array and must come from an index buffer. 2482 * If no element array buffer is bound, an INVALID_OPERATION error is 2483 * generated. 2484 */ 2485 if (!ctx->Array.VAO->IndexBufferObj) { 2486 _mesa_error(ctx, GL_INVALID_OPERATION, 2487 "glDrawElementsIndirect(no buffer bound " 2488 "to GL_ELEMENT_ARRAY_BUFFER)"); 2489 } else { 2490 DrawElementsIndirectCommand *cmd = 2491 (DrawElementsIndirectCommand *) indirect; 2492 2493 /* Convert offset to pointer */ 2494 void *offset = (void *) 2495 (uintptr_t)((cmd->firstIndex * _mesa_sizeof_type(type)) & 0xffffffffUL); 2496 2497 _mesa_DrawElementsInstancedBaseVertexBaseInstance(mode, cmd->count, 2498 type, offset, 2499 cmd->primCount, 2500 cmd->baseVertex, 2501 cmd->baseInstance); 2502 } 2503 2504 return; 2505 } 2506 2507 FLUSH_FOR_DRAW(ctx); 2508 2509 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 2510 ctx->VertexProgram._VPModeInputFilter); 2511 2512 if (ctx->NewState) 2513 _mesa_update_state(ctx); 2514 2515 if (!_mesa_is_no_error_enabled(ctx) && 2516 !_mesa_validate_DrawElementsIndirect(ctx, mode, type, indirect)) 2517 return; 2518 2519 _mesa_validated_multidrawelementsindirect(ctx, mode, type, 2520 (GLintptr)indirect, 0, 2521 1, 20, NULL); 2522} 2523 2524 2525void GLAPIENTRY 2526_mesa_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect, 2527 GLsizei primcount, GLsizei stride) 2528{ 2529 GET_CURRENT_CONTEXT(ctx); 2530 2531 /* If <stride> is zero, the array elements are treated as tightly packed. */ 2532 if (stride == 0) 2533 stride = sizeof(DrawArraysIndirectCommand); 2534 2535 FLUSH_FOR_DRAW(ctx); 2536 2537 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 2538 ctx->VertexProgram._VPModeInputFilter); 2539 2540 if (ctx->NewState) 2541 _mesa_update_state(ctx); 2542 2543 /* From the ARB_draw_indirect spec: 2544 * 2545 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the 2546 * compatibility profile, this indicates that DrawArraysIndirect and 2547 * DrawElementsIndirect are to source their arguments directly from the 2548 * pointer passed as their <indirect> parameters." 2549 */ 2550 if (ctx->API == API_OPENGL_COMPAT && 2551 !ctx->DrawIndirectBuffer) { 2552 2553 if (!_mesa_is_no_error_enabled(ctx) && 2554 (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride, 2555 "glMultiDrawArraysIndirect") || 2556 !_mesa_validate_DrawArrays(ctx, mode, 1))) 2557 return; 2558 2559 struct pipe_draw_info info; 2560 info.mode = mode; 2561 info.index_size = 0; 2562 info.view_mask = 0; 2563 /* Packed section begin. */ 2564 info.primitive_restart = false; 2565 info.has_user_indices = false; 2566 info.index_bounds_valid = false; 2567 info.increment_draw_id = primcount > 1; 2568 info.was_line_loop = false; 2569 info.take_index_buffer_ownership = false; 2570 info.index_bias_varies = false; 2571 /* Packed section end. */ 2572 2573 const uint8_t *ptr = (const uint8_t *) indirect; 2574 for (unsigned i = 0; i < primcount; i++) { 2575 DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) ptr; 2576 2577 info.start_instance = cmd->baseInstance; 2578 info.instance_count = cmd->primCount; 2579 2580 struct pipe_draw_start_count_bias draw; 2581 draw.start = cmd->first; 2582 draw.count = cmd->count; 2583 2584 ctx->Driver.DrawGallium(ctx, &info, i, &draw, 1); 2585 ptr += stride; 2586 } 2587 2588 return; 2589 } 2590 2591 if (!_mesa_is_no_error_enabled(ctx) && 2592 !_mesa_validate_MultiDrawArraysIndirect(ctx, mode, indirect, 2593 primcount, stride)) 2594 return; 2595 2596 _mesa_validated_multidrawarraysindirect(ctx, mode, (GLintptr)indirect, 0, 2597 primcount, stride, NULL); 2598} 2599 2600 2601void GLAPIENTRY 2602_mesa_MultiDrawElementsIndirect(GLenum mode, GLenum type, 2603 const GLvoid *indirect, 2604 GLsizei primcount, GLsizei stride) 2605{ 2606 GET_CURRENT_CONTEXT(ctx); 2607 2608 FLUSH_FOR_DRAW(ctx); 2609 2610 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 2611 ctx->VertexProgram._VPModeInputFilter); 2612 2613 if (ctx->NewState) 2614 _mesa_update_state(ctx); 2615 2616 /* If <stride> is zero, the array elements are treated as tightly packed. */ 2617 if (stride == 0) 2618 stride = sizeof(DrawElementsIndirectCommand); 2619 2620 /* From the ARB_draw_indirect spec: 2621 * 2622 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the 2623 * compatibility profile, this indicates that DrawArraysIndirect and 2624 * DrawElementsIndirect are to source their arguments directly from the 2625 * pointer passed as their <indirect> parameters." 2626 */ 2627 if (ctx->API == API_OPENGL_COMPAT && 2628 !ctx->DrawIndirectBuffer) { 2629 /* 2630 * Unlike regular DrawElementsInstancedBaseVertex commands, the indices 2631 * may not come from a client array and must come from an index buffer. 2632 * If no element array buffer is bound, an INVALID_OPERATION error is 2633 * generated. 2634 */ 2635 if (!ctx->Array.VAO->IndexBufferObj) { 2636 _mesa_error(ctx, GL_INVALID_OPERATION, 2637 "glMultiDrawElementsIndirect(no buffer bound " 2638 "to GL_ELEMENT_ARRAY_BUFFER)"); 2639 2640 return; 2641 } 2642 2643 if (!_mesa_is_no_error_enabled(ctx) && 2644 (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride, 2645 "glMultiDrawArraysIndirect") || 2646 !_mesa_validate_DrawElements(ctx, mode, 1, type))) 2647 return; 2648 2649 unsigned index_size_shift = get_index_size_shift(type); 2650 2651 struct pipe_draw_info info; 2652 info.mode = mode; 2653 info.index_size = 1 << index_size_shift; 2654 info.view_mask = 0; 2655 /* Packed section begin. */ 2656 info.primitive_restart = ctx->Array._PrimitiveRestart[index_size_shift]; 2657 info.has_user_indices = false; 2658 info.index_bounds_valid = false; 2659 info.increment_draw_id = primcount > 1; 2660 info.was_line_loop = false; 2661 info.take_index_buffer_ownership = false; 2662 info.index_bias_varies = false; 2663 /* Packed section end. */ 2664 info.restart_index = ctx->Array._RestartIndex[index_size_shift]; 2665 2666 const uint8_t *ptr = (const uint8_t *) indirect; 2667 for (unsigned i = 0; i < primcount; i++) { 2668 DrawElementsIndirectCommand *cmd = (DrawElementsIndirectCommand*)ptr; 2669 2670 info.index.gl_bo = ctx->Array.VAO->IndexBufferObj; 2671 info.start_instance = cmd->baseInstance; 2672 info.instance_count = cmd->primCount; 2673 2674 struct pipe_draw_start_count_bias draw; 2675 draw.start = cmd->firstIndex; 2676 draw.count = cmd->count; 2677 draw.index_bias = cmd->baseVertex; 2678 2679 ctx->Driver.DrawGallium(ctx, &info, i, &draw, 1); 2680 ptr += stride; 2681 } 2682 2683 return; 2684 } 2685 2686 if (!_mesa_is_no_error_enabled(ctx) && 2687 !_mesa_validate_MultiDrawElementsIndirect(ctx, mode, type, indirect, 2688 primcount, stride)) 2689 return; 2690 2691 _mesa_validated_multidrawelementsindirect(ctx, mode, type, 2692 (GLintptr)indirect, 0, primcount, 2693 stride, NULL); 2694} 2695 2696 2697void GLAPIENTRY 2698_mesa_MultiDrawArraysIndirectCountARB(GLenum mode, GLintptr indirect, 2699 GLintptr drawcount_offset, 2700 GLsizei maxdrawcount, GLsizei stride) 2701{ 2702 GET_CURRENT_CONTEXT(ctx); 2703 FLUSH_FOR_DRAW(ctx); 2704 2705 /* If <stride> is zero, the array elements are treated as tightly packed. */ 2706 if (stride == 0) 2707 stride = 4 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */ 2708 2709 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 2710 ctx->VertexProgram._VPModeInputFilter); 2711 2712 if (ctx->NewState) 2713 _mesa_update_state(ctx); 2714 2715 if (!_mesa_is_no_error_enabled(ctx) && 2716 !_mesa_validate_MultiDrawArraysIndirectCount(ctx, mode, indirect, 2717 drawcount_offset, 2718 maxdrawcount, stride)) 2719 return; 2720 2721 _mesa_validated_multidrawarraysindirect(ctx, mode, indirect, 2722 drawcount_offset, maxdrawcount, 2723 stride, ctx->ParameterBuffer); 2724} 2725 2726 2727void GLAPIENTRY 2728_mesa_MultiDrawElementsIndirectCountARB(GLenum mode, GLenum type, 2729 GLintptr indirect, 2730 GLintptr drawcount_offset, 2731 GLsizei maxdrawcount, GLsizei stride) 2732{ 2733 GET_CURRENT_CONTEXT(ctx); 2734 FLUSH_FOR_DRAW(ctx); 2735 2736 /* If <stride> is zero, the array elements are treated as tightly packed. */ 2737 if (stride == 0) 2738 stride = 5 * sizeof(GLuint); /* sizeof(DrawElementsIndirectCommand) */ 2739 2740 _mesa_set_draw_vao(ctx, ctx->Array.VAO, 2741 ctx->VertexProgram._VPModeInputFilter); 2742 2743 if (ctx->NewState) 2744 _mesa_update_state(ctx); 2745 2746 if (!_mesa_is_no_error_enabled(ctx) && 2747 !_mesa_validate_MultiDrawElementsIndirectCount(ctx, mode, type, 2748 indirect, 2749 drawcount_offset, 2750 maxdrawcount, stride)) 2751 return; 2752 2753 _mesa_validated_multidrawelementsindirect(ctx, mode, type, indirect, 2754 drawcount_offset, maxdrawcount, 2755 stride, ctx->ParameterBuffer); 2756} 2757 2758 2759/* GL_IBM_multimode_draw_arrays */ 2760void GLAPIENTRY 2761_mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first, 2762 const GLsizei * count, 2763 GLsizei primcount, GLint modestride ) 2764{ 2765 GET_CURRENT_CONTEXT(ctx); 2766 GLint i; 2767 2768 for ( i = 0 ; i < primcount ; i++ ) { 2769 if ( count[i] > 0 ) { 2770 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); 2771 CALL_DrawArrays(ctx->CurrentServerDispatch, ( m, first[i], count[i] )); 2772 } 2773 } 2774} 2775 2776 2777/* GL_IBM_multimode_draw_arrays */ 2778void GLAPIENTRY 2779_mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count, 2780 GLenum type, const GLvoid * const * indices, 2781 GLsizei primcount, GLint modestride ) 2782{ 2783 GET_CURRENT_CONTEXT(ctx); 2784 GLint i; 2785 2786 for ( i = 0 ; i < primcount ; i++ ) { 2787 if ( count[i] > 0 ) { 2788 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); 2789 CALL_DrawElements(ctx->CurrentServerDispatch, ( m, count[i], type, 2790 indices[i] )); 2791 } 2792 } 2793} 2794