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