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