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