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