vbo: add a comment on vbo_draw_transform_feedback()
[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 /**
1420 * Draw a GL primitive using a vertex count obtained from transform feedback.
1421 * \param mode the type of GL primitive to draw
1422 * \param obj the transform feedback object to use
1423 * \param stream index of the transform feedback stream from which to
1424 * get the primitive count.
1425 * \param numInstances number of instances to draw
1426 */
1427 static void
1428 vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
1429 struct gl_transform_feedback_object *obj,
1430 GLuint stream, GLuint numInstances)
1431 {
1432 struct vbo_context *vbo = vbo_context(ctx);
1433 struct _mesa_prim prim;
1434
1435 if (_mesa_is_no_error_enabled(ctx)) {
1436 FLUSH_CURRENT(ctx, 0);
1437
1438 if (ctx->NewState)
1439 _mesa_update_state(ctx);
1440 } else {
1441 if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream,
1442 numInstances)) {
1443 return;
1444 }
1445 }
1446
1447 if (ctx->Driver.GetTransformFeedbackVertexCount &&
1448 (ctx->Const.AlwaysUseGetTransformFeedbackVertexCount ||
1449 !_mesa_all_varyings_in_vbos(ctx->Array.VAO))) {
1450 GLsizei n =
1451 ctx->Driver.GetTransformFeedbackVertexCount(ctx, obj, stream);
1452 vbo_draw_arrays(ctx, mode, 0, n, numInstances, 0, 0);
1453 return;
1454 }
1455
1456 if (skip_validated_draw(ctx))
1457 return;
1458
1459 vbo_bind_arrays(ctx);
1460
1461 /* init most fields to zero */
1462 memset(&prim, 0, sizeof(prim));
1463 prim.begin = 1;
1464 prim.end = 1;
1465 prim.mode = mode;
1466 prim.num_instances = numInstances;
1467 prim.base_instance = 0;
1468 prim.is_indirect = 0;
1469
1470 /* Maybe we should do some primitive splitting for primitive restart
1471 * (like in DrawArrays), but we have no way to know how many vertices
1472 * will be rendered. */
1473
1474 vbo->draw_prims(ctx, &prim, 1, NULL, GL_FALSE, 0, ~0, obj, stream, NULL);
1475
1476 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1477 _mesa_flush(ctx);
1478 }
1479 }
1480
1481
1482 /**
1483 * Like DrawArrays, but take the count from a transform feedback object.
1484 * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc.
1485 * \param name the transform feedback object
1486 * User still has to setup of the vertex attribute info with
1487 * glVertexPointer, glColorPointer, etc.
1488 * Part of GL_ARB_transform_feedback2.
1489 */
1490 static void GLAPIENTRY
1491 vbo_exec_DrawTransformFeedback(GLenum mode, GLuint name)
1492 {
1493 GET_CURRENT_CONTEXT(ctx);
1494 struct gl_transform_feedback_object *obj =
1495 _mesa_lookup_transform_feedback_object(ctx, name);
1496
1497 if (MESA_VERBOSE & VERBOSE_DRAW)
1498 _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n",
1499 _mesa_enum_to_string(mode), name);
1500
1501 vbo_draw_transform_feedback(ctx, mode, obj, 0, 1);
1502 }
1503
1504
1505 static void GLAPIENTRY
1506 vbo_exec_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream)
1507 {
1508 GET_CURRENT_CONTEXT(ctx);
1509 struct gl_transform_feedback_object *obj =
1510 _mesa_lookup_transform_feedback_object(ctx, name);
1511
1512 if (MESA_VERBOSE & VERBOSE_DRAW)
1513 _mesa_debug(ctx, "glDrawTransformFeedbackStream(%s, %u, %u)\n",
1514 _mesa_enum_to_string(mode), name, stream);
1515
1516 vbo_draw_transform_feedback(ctx, mode, obj, stream, 1);
1517 }
1518
1519
1520 static void GLAPIENTRY
1521 vbo_exec_DrawTransformFeedbackInstanced(GLenum mode, GLuint name,
1522 GLsizei primcount)
1523 {
1524 GET_CURRENT_CONTEXT(ctx);
1525 struct gl_transform_feedback_object *obj =
1526 _mesa_lookup_transform_feedback_object(ctx, name);
1527
1528 if (MESA_VERBOSE & VERBOSE_DRAW)
1529 _mesa_debug(ctx, "glDrawTransformFeedbackInstanced(%s, %d)\n",
1530 _mesa_enum_to_string(mode), name);
1531
1532 vbo_draw_transform_feedback(ctx, mode, obj, 0, primcount);
1533 }
1534
1535
1536 static void GLAPIENTRY
1537 vbo_exec_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name,
1538 GLuint stream,
1539 GLsizei primcount)
1540 {
1541 GET_CURRENT_CONTEXT(ctx);
1542 struct gl_transform_feedback_object *obj =
1543 _mesa_lookup_transform_feedback_object(ctx, name);
1544
1545 if (MESA_VERBOSE & VERBOSE_DRAW)
1546 _mesa_debug(ctx, "glDrawTransformFeedbackStreamInstanced"
1547 "(%s, %u, %u, %i)\n",
1548 _mesa_enum_to_string(mode), name, stream, primcount);
1549
1550 vbo_draw_transform_feedback(ctx, mode, obj, stream, primcount);
1551 }
1552
1553
1554 static void
1555 vbo_validated_drawarraysindirect(struct gl_context *ctx,
1556 GLenum mode, const GLvoid *indirect)
1557 {
1558 struct vbo_context *vbo = vbo_context(ctx);
1559
1560 vbo_bind_arrays(ctx);
1561
1562 vbo->draw_indirect_prims(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 struct vbo_context *vbo = vbo_context(ctx);
1579 GLsizeiptr offset = (GLsizeiptr) indirect;
1580
1581 if (primcount == 0)
1582 return;
1583
1584 vbo_bind_arrays(ctx);
1585
1586 vbo->draw_indirect_prims(ctx, mode, ctx->DrawIndirectBuffer, offset,
1587 primcount, stride, NULL, 0, NULL);
1588
1589 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1590 _mesa_flush(ctx);
1591 }
1592
1593
1594 static void
1595 vbo_validated_drawelementsindirect(struct gl_context *ctx,
1596 GLenum mode, GLenum type,
1597 const GLvoid *indirect)
1598 {
1599 struct vbo_context *vbo = vbo_context(ctx);
1600 struct _mesa_index_buffer ib;
1601
1602 vbo_bind_arrays(ctx);
1603
1604 ib.count = 0; /* unknown */
1605 ib.index_size = sizeof_ib_type(type);
1606 ib.obj = ctx->Array.VAO->IndexBufferObj;
1607 ib.ptr = NULL;
1608
1609 vbo->draw_indirect_prims(ctx, mode,
1610 ctx->DrawIndirectBuffer, (GLsizeiptr) indirect,
1611 1 /* draw_count */ , 20 /* stride */ ,
1612 NULL, 0, &ib);
1613
1614 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1615 _mesa_flush(ctx);
1616 }
1617
1618
1619 static void
1620 vbo_validated_multidrawelementsindirect(struct gl_context *ctx,
1621 GLenum mode, GLenum type,
1622 const GLvoid *indirect,
1623 GLsizei primcount, GLsizei stride)
1624 {
1625 struct vbo_context *vbo = vbo_context(ctx);
1626 struct _mesa_index_buffer ib;
1627 GLsizeiptr offset = (GLsizeiptr) indirect;
1628
1629 if (primcount == 0)
1630 return;
1631
1632 vbo_bind_arrays(ctx);
1633
1634 /* NOTE: IndexBufferObj is guaranteed to be a VBO. */
1635
1636 ib.count = 0; /* unknown */
1637 ib.index_size = sizeof_ib_type(type);
1638 ib.obj = ctx->Array.VAO->IndexBufferObj;
1639 ib.ptr = NULL;
1640
1641 vbo->draw_indirect_prims(ctx, mode,
1642 ctx->DrawIndirectBuffer, offset,
1643 primcount, stride, NULL, 0, &ib);
1644
1645 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1646 _mesa_flush(ctx);
1647 }
1648
1649
1650 /**
1651 * Like [Multi]DrawArrays/Elements, but they take most arguments from
1652 * a buffer object.
1653 */
1654 static void GLAPIENTRY
1655 vbo_exec_DrawArraysIndirect(GLenum mode, const GLvoid *indirect)
1656 {
1657 GET_CURRENT_CONTEXT(ctx);
1658
1659 if (MESA_VERBOSE & VERBOSE_DRAW)
1660 _mesa_debug(ctx, "glDrawArraysIndirect(%s, %p)\n",
1661 _mesa_enum_to_string(mode), indirect);
1662
1663 if (_mesa_is_no_error_enabled(ctx)) {
1664 FLUSH_CURRENT(ctx, 0);
1665
1666 if (ctx->NewState)
1667 _mesa_update_state(ctx);
1668 } else {
1669 if (!_mesa_validate_DrawArraysIndirect(ctx, mode, indirect))
1670 return;
1671 }
1672
1673 if (skip_validated_draw(ctx))
1674 return;
1675
1676 vbo_validated_drawarraysindirect(ctx, mode, indirect);
1677 }
1678
1679
1680 static void GLAPIENTRY
1681 vbo_exec_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1682 {
1683 GET_CURRENT_CONTEXT(ctx);
1684
1685 if (MESA_VERBOSE & VERBOSE_DRAW)
1686 _mesa_debug(ctx, "glDrawElementsIndirect(%s, %s, %p)\n",
1687 _mesa_enum_to_string(mode),
1688 _mesa_enum_to_string(type), indirect);
1689
1690 if (_mesa_is_no_error_enabled(ctx)) {
1691 FLUSH_CURRENT(ctx, 0);
1692
1693 if (ctx->NewState)
1694 _mesa_update_state(ctx);
1695 } else {
1696 if (!_mesa_validate_DrawElementsIndirect(ctx, mode, type, indirect))
1697 return;
1698 }
1699
1700 if (skip_validated_draw(ctx))
1701 return;
1702
1703 vbo_validated_drawelementsindirect(ctx, mode, type, indirect);
1704 }
1705
1706
1707 static void GLAPIENTRY
1708 vbo_exec_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect,
1709 GLsizei primcount, GLsizei stride)
1710 {
1711 GET_CURRENT_CONTEXT(ctx);
1712
1713 if (MESA_VERBOSE & VERBOSE_DRAW)
1714 _mesa_debug(ctx, "glMultiDrawArraysIndirect(%s, %p, %i, %i)\n",
1715 _mesa_enum_to_string(mode), indirect, primcount, stride);
1716
1717 /* If <stride> is zero, the array elements are treated as tightly packed. */
1718 if (stride == 0)
1719 stride = 4 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */
1720
1721 if (_mesa_is_no_error_enabled(ctx)) {
1722 FLUSH_CURRENT(ctx, 0);
1723
1724 if (ctx->NewState)
1725 _mesa_update_state(ctx);
1726 } else {
1727 if (!_mesa_validate_MultiDrawArraysIndirect(ctx, mode, indirect,
1728 primcount, stride))
1729 return;
1730 }
1731
1732 if (skip_validated_draw(ctx))
1733 return;
1734
1735 vbo_validated_multidrawarraysindirect(ctx, mode, indirect,
1736 primcount, stride);
1737 }
1738
1739
1740 static void GLAPIENTRY
1741 vbo_exec_MultiDrawElementsIndirect(GLenum mode, GLenum type,
1742 const GLvoid *indirect,
1743 GLsizei primcount, GLsizei stride)
1744 {
1745 GET_CURRENT_CONTEXT(ctx);
1746
1747 if (MESA_VERBOSE & VERBOSE_DRAW)
1748 _mesa_debug(ctx, "glMultiDrawElementsIndirect(%s, %s, %p, %i, %i)\n",
1749 _mesa_enum_to_string(mode),
1750 _mesa_enum_to_string(type), indirect, primcount, stride);
1751
1752 /* If <stride> is zero, the array elements are treated as tightly packed. */
1753 if (stride == 0)
1754 stride = 5 * sizeof(GLuint); /* sizeof(DrawElementsIndirectCommand) */
1755
1756 if (_mesa_is_no_error_enabled(ctx)) {
1757 FLUSH_CURRENT(ctx, 0);
1758
1759 if (ctx->NewState)
1760 _mesa_update_state(ctx);
1761 } else {
1762 if (!_mesa_validate_MultiDrawElementsIndirect(ctx, mode, type, indirect,
1763 primcount, stride))
1764 return;
1765 }
1766
1767 if (skip_validated_draw(ctx))
1768 return;
1769
1770 vbo_validated_multidrawelementsindirect(ctx, mode, type, indirect,
1771 primcount, stride);
1772 }
1773
1774
1775 static void
1776 vbo_validated_multidrawarraysindirectcount(struct gl_context *ctx,
1777 GLenum mode,
1778 GLintptr indirect,
1779 GLintptr drawcount_offset,
1780 GLsizei maxdrawcount,
1781 GLsizei stride)
1782 {
1783 struct vbo_context *vbo = vbo_context(ctx);
1784 GLsizeiptr offset = indirect;
1785
1786 if (maxdrawcount == 0)
1787 return;
1788
1789 vbo_bind_arrays(ctx);
1790
1791 vbo->draw_indirect_prims(ctx, mode,
1792 ctx->DrawIndirectBuffer, offset,
1793 maxdrawcount, stride,
1794 ctx->ParameterBuffer, drawcount_offset, NULL);
1795
1796 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1797 _mesa_flush(ctx);
1798 }
1799
1800
1801 static void
1802 vbo_validated_multidrawelementsindirectcount(struct gl_context *ctx,
1803 GLenum mode, GLenum type,
1804 GLintptr indirect,
1805 GLintptr drawcount_offset,
1806 GLsizei maxdrawcount,
1807 GLsizei stride)
1808 {
1809 struct vbo_context *vbo = vbo_context(ctx);
1810 struct _mesa_index_buffer ib;
1811 GLsizeiptr offset = (GLsizeiptr) indirect;
1812
1813 if (maxdrawcount == 0)
1814 return;
1815
1816 vbo_bind_arrays(ctx);
1817
1818 /* NOTE: IndexBufferObj is guaranteed to be a VBO. */
1819
1820 ib.count = 0; /* unknown */
1821 ib.index_size = sizeof_ib_type(type);
1822 ib.obj = ctx->Array.VAO->IndexBufferObj;
1823 ib.ptr = NULL;
1824
1825 vbo->draw_indirect_prims(ctx, mode,
1826 ctx->DrawIndirectBuffer, offset,
1827 maxdrawcount, stride,
1828 ctx->ParameterBuffer, drawcount_offset, &ib);
1829
1830 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1831 _mesa_flush(ctx);
1832 }
1833
1834
1835 static void GLAPIENTRY
1836 vbo_exec_MultiDrawArraysIndirectCount(GLenum mode, GLintptr indirect,
1837 GLintptr drawcount_offset,
1838 GLsizei maxdrawcount, GLsizei stride)
1839 {
1840 GET_CURRENT_CONTEXT(ctx);
1841
1842 if (MESA_VERBOSE & VERBOSE_DRAW)
1843 _mesa_debug(ctx, "glMultiDrawArraysIndirectCountARB"
1844 "(%s, %lx, %lx, %i, %i)\n",
1845 _mesa_enum_to_string(mode),
1846 (unsigned long) indirect, (unsigned long) drawcount_offset,
1847 maxdrawcount, stride);
1848
1849 /* If <stride> is zero, the array elements are treated as tightly packed. */
1850 if (stride == 0)
1851 stride = 4 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */
1852
1853 if (_mesa_is_no_error_enabled(ctx)) {
1854 FLUSH_CURRENT(ctx, 0);
1855
1856 if (ctx->NewState)
1857 _mesa_update_state(ctx);
1858 } else {
1859 if (!_mesa_validate_MultiDrawArraysIndirectCount(ctx, mode,
1860 indirect,
1861 drawcount_offset,
1862 maxdrawcount, stride))
1863 return;
1864 }
1865
1866 if (skip_validated_draw(ctx))
1867 return;
1868
1869 vbo_validated_multidrawarraysindirectcount(ctx, mode, indirect,
1870 drawcount_offset,
1871 maxdrawcount, stride);
1872 }
1873
1874
1875 static void GLAPIENTRY
1876 vbo_exec_MultiDrawElementsIndirectCount(GLenum mode, GLenum type,
1877 GLintptr indirect,
1878 GLintptr drawcount_offset,
1879 GLsizei maxdrawcount, GLsizei stride)
1880 {
1881 GET_CURRENT_CONTEXT(ctx);
1882
1883 if (MESA_VERBOSE & VERBOSE_DRAW)
1884 _mesa_debug(ctx, "glMultiDrawElementsIndirectCountARB"
1885 "(%s, %s, %lx, %lx, %i, %i)\n",
1886 _mesa_enum_to_string(mode), _mesa_enum_to_string(type),
1887 (unsigned long) indirect, (unsigned long) drawcount_offset,
1888 maxdrawcount, stride);
1889
1890 /* If <stride> is zero, the array elements are treated as tightly packed. */
1891 if (stride == 0)
1892 stride = 5 * sizeof(GLuint); /* sizeof(DrawElementsIndirectCommand) */
1893
1894 if (_mesa_is_no_error_enabled(ctx)) {
1895 FLUSH_CURRENT(ctx, 0);
1896
1897 if (ctx->NewState)
1898 _mesa_update_state(ctx);
1899 } else {
1900 if (!_mesa_validate_MultiDrawElementsIndirectCount(ctx, mode, type,
1901 indirect,
1902 drawcount_offset,
1903 maxdrawcount, stride))
1904 return;
1905 }
1906
1907 if (skip_validated_draw(ctx))
1908 return;
1909
1910 vbo_validated_multidrawelementsindirectcount(ctx, mode, type, indirect,
1911 drawcount_offset, maxdrawcount,
1912 stride);
1913 }
1914
1915
1916 /**
1917 * Initialize the dispatch table with the VBO functions for drawing.
1918 */
1919 void
1920 vbo_initialize_exec_dispatch(const struct gl_context *ctx,
1921 struct _glapi_table *exec)
1922 {
1923 SET_DrawArrays(exec, vbo_exec_DrawArrays);
1924 SET_DrawElements(exec, vbo_exec_DrawElements);
1925
1926 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1927 SET_DrawRangeElements(exec, vbo_exec_DrawRangeElements);
1928 }
1929
1930 SET_MultiDrawArrays(exec, vbo_exec_MultiDrawArrays);
1931 SET_MultiDrawElementsEXT(exec, vbo_exec_MultiDrawElements);
1932
1933 if (ctx->API == API_OPENGL_COMPAT) {
1934 SET_Rectf(exec, vbo_exec_Rectf);
1935 SET_EvalMesh1(exec, vbo_exec_EvalMesh1);
1936 SET_EvalMesh2(exec, vbo_exec_EvalMesh2);
1937 }
1938
1939 if (ctx->API != API_OPENGLES &&
1940 ctx->Extensions.ARB_draw_elements_base_vertex) {
1941 SET_DrawElementsBaseVertex(exec, vbo_exec_DrawElementsBaseVertex);
1942 SET_MultiDrawElementsBaseVertex(exec,
1943 vbo_exec_MultiDrawElementsBaseVertex);
1944
1945 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1946 SET_DrawRangeElementsBaseVertex(exec,
1947 vbo_exec_DrawRangeElementsBaseVertex);
1948 SET_DrawElementsInstancedBaseVertex(exec,
1949 vbo_exec_DrawElementsInstancedBaseVertex);
1950 }
1951 }
1952
1953 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1954 SET_DrawArraysInstancedBaseInstance(exec,
1955 vbo_exec_DrawArraysInstancedBaseInstance);
1956 SET_DrawElementsInstancedBaseInstance(exec,
1957 vbo_exec_DrawElementsInstancedBaseInstance);
1958 SET_DrawElementsInstancedBaseVertexBaseInstance(exec,
1959 vbo_exec_DrawElementsInstancedBaseVertexBaseInstance);
1960 }
1961
1962 if (ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) {
1963 SET_DrawArraysIndirect(exec, vbo_exec_DrawArraysIndirect);
1964 SET_DrawElementsIndirect(exec, vbo_exec_DrawElementsIndirect);
1965 }
1966
1967 if (ctx->API == API_OPENGL_CORE) {
1968 SET_MultiDrawArraysIndirect(exec, vbo_exec_MultiDrawArraysIndirect);
1969 SET_MultiDrawElementsIndirect(exec, vbo_exec_MultiDrawElementsIndirect);
1970 SET_MultiDrawArraysIndirectCountARB(exec,
1971 vbo_exec_MultiDrawArraysIndirectCount);
1972 SET_MultiDrawElementsIndirectCountARB(exec,
1973 vbo_exec_MultiDrawElementsIndirectCount);
1974 }
1975
1976 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1977 SET_DrawArraysInstancedARB(exec, vbo_exec_DrawArraysInstanced);
1978 SET_DrawElementsInstancedARB(exec, vbo_exec_DrawElementsInstanced);
1979 }
1980
1981 if (_mesa_is_desktop_gl(ctx)) {
1982 SET_DrawTransformFeedback(exec, vbo_exec_DrawTransformFeedback);
1983 SET_DrawTransformFeedbackStream(exec,
1984 vbo_exec_DrawTransformFeedbackStream);
1985 SET_DrawTransformFeedbackInstanced(exec,
1986 vbo_exec_DrawTransformFeedbackInstanced);
1987 SET_DrawTransformFeedbackStreamInstanced(exec,
1988 vbo_exec_DrawTransformFeedbackStreamInstanced);
1989 }
1990 }
1991
1992
1993
1994 /**
1995 * The following functions are only used for OpenGL ES 1/2 support.
1996 * And some aren't even supported (yet) in ES 1/2.
1997 */
1998
1999
2000 void GLAPIENTRY
2001 _mesa_DrawArrays(GLenum mode, GLint first, GLsizei count)
2002 {
2003 vbo_exec_DrawArrays(mode, first, count);
2004 }
2005
2006
2007 void GLAPIENTRY
2008 _mesa_DrawArraysInstanced(GLenum mode, GLint first, GLsizei count,
2009 GLsizei primcount)
2010 {
2011 vbo_exec_DrawArraysInstanced(mode, first, count, primcount);
2012 }
2013
2014
2015 void GLAPIENTRY
2016 _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
2017 const GLvoid *indices)
2018 {
2019 vbo_exec_DrawElements(mode, count, type, indices);
2020 }
2021
2022
2023 void GLAPIENTRY
2024 _mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
2025 const GLvoid *indices, GLint basevertex)
2026 {
2027 vbo_exec_DrawElementsBaseVertex(mode, count, type, indices, basevertex);
2028 }
2029
2030
2031 void GLAPIENTRY
2032 _mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
2033 GLenum type, const GLvoid * indices)
2034 {
2035 vbo_exec_DrawRangeElements(mode, start, end, count, type, indices);
2036 }
2037
2038
2039 void GLAPIENTRY
2040 _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
2041 GLsizei count, GLenum type,
2042 const GLvoid *indices, GLint basevertex)
2043 {
2044 vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
2045 indices, basevertex);
2046 }
2047
2048
2049 void GLAPIENTRY
2050 _mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type,
2051 const GLvoid ** indices, GLsizei primcount)
2052 {
2053 vbo_exec_MultiDrawElements(mode, count, type, indices, primcount);
2054 }
2055
2056
2057 void GLAPIENTRY
2058 _mesa_MultiDrawElementsBaseVertex(GLenum mode,
2059 const GLsizei *count, GLenum type,
2060 const GLvoid **indices, GLsizei primcount,
2061 const GLint *basevertex)
2062 {
2063 vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices,
2064 primcount, basevertex);
2065 }
2066
2067
2068 void GLAPIENTRY
2069 _mesa_DrawTransformFeedback(GLenum mode, GLuint name)
2070 {
2071 vbo_exec_DrawTransformFeedback(mode, name);
2072 }