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