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