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