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