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