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