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