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