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