+
+static void
+vbo_validated_multidrawarraysindirectcount(struct gl_context *ctx,
+ GLenum mode,
+ GLintptr indirect,
+ GLintptr drawcount_offset,
+ GLsizei maxdrawcount,
+ GLsizei stride)
+{
+ GLsizeiptr offset = indirect;
+
+ if (maxdrawcount == 0)
+ return;
+
+ ctx->Driver.DrawIndirect(ctx, mode,
+ ctx->DrawIndirectBuffer, offset,
+ maxdrawcount, stride,
+ ctx->ParameterBuffer, drawcount_offset, NULL);
+
+ if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
+ _mesa_flush(ctx);
+}
+
+
+static void
+vbo_validated_multidrawelementsindirectcount(struct gl_context *ctx,
+ GLenum mode, GLenum type,
+ GLintptr indirect,
+ GLintptr drawcount_offset,
+ GLsizei maxdrawcount,
+ GLsizei stride)
+{
+ struct _mesa_index_buffer ib;
+ GLsizeiptr offset = (GLsizeiptr) indirect;
+
+ if (maxdrawcount == 0)
+ return;
+
+ /* NOTE: IndexBufferObj is guaranteed to be a VBO. */
+
+ ib.count = 0; /* unknown */
+ ib.index_size = sizeof_ib_type(type);
+ ib.obj = ctx->Array.VAO->IndexBufferObj;
+ ib.ptr = NULL;
+
+ ctx->Driver.DrawIndirect(ctx, mode,
+ ctx->DrawIndirectBuffer, offset,
+ maxdrawcount, stride,
+ ctx->ParameterBuffer, drawcount_offset, &ib);
+
+ if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
+ _mesa_flush(ctx);
+}
+
+
+static void GLAPIENTRY
+vbo_exec_MultiDrawArraysIndirectCount(GLenum mode, GLintptr indirect,
+ GLintptr drawcount_offset,
+ GLsizei maxdrawcount, GLsizei stride)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_DRAW)
+ _mesa_debug(ctx, "glMultiDrawArraysIndirectCountARB"
+ "(%s, %lx, %lx, %i, %i)\n",
+ _mesa_enum_to_string(mode),
+ (unsigned long) indirect, (unsigned long) drawcount_offset,
+ maxdrawcount, stride);
+
+ /* If <stride> is zero, the array elements are treated as tightly packed. */
+ if (stride == 0)
+ stride = 4 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */
+
+ FLUSH_FOR_DRAW(ctx);
+
+ if (_mesa_is_no_error_enabled(ctx)) {
+ _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
+
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+ } else {
+ _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
+
+ if (!_mesa_validate_MultiDrawArraysIndirectCount(ctx, mode,
+ indirect,
+ drawcount_offset,
+ maxdrawcount, stride))
+ return;
+ }
+
+ if (skip_validated_draw(ctx))
+ return;
+
+ vbo_validated_multidrawarraysindirectcount(ctx, mode, indirect,
+ drawcount_offset,
+ maxdrawcount, stride);
+}
+
+
+static void GLAPIENTRY
+vbo_exec_MultiDrawElementsIndirectCount(GLenum mode, GLenum type,
+ GLintptr indirect,
+ GLintptr drawcount_offset,
+ GLsizei maxdrawcount, GLsizei stride)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (MESA_VERBOSE & VERBOSE_DRAW)
+ _mesa_debug(ctx, "glMultiDrawElementsIndirectCountARB"
+ "(%s, %s, %lx, %lx, %i, %i)\n",
+ _mesa_enum_to_string(mode), _mesa_enum_to_string(type),
+ (unsigned long) indirect, (unsigned long) drawcount_offset,
+ maxdrawcount, stride);
+
+ /* If <stride> is zero, the array elements are treated as tightly packed. */
+ if (stride == 0)
+ stride = 5 * sizeof(GLuint); /* sizeof(DrawElementsIndirectCommand) */
+
+ FLUSH_FOR_DRAW(ctx);
+
+ if (_mesa_is_no_error_enabled(ctx)) {
+ _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
+
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+ } else {
+ _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
+
+ if (!_mesa_validate_MultiDrawElementsIndirectCount(ctx, mode, type,
+ indirect,
+ drawcount_offset,
+ maxdrawcount, stride))
+ return;
+ }
+
+ if (skip_validated_draw(ctx))
+ return;
+
+ vbo_validated_multidrawelementsindirectcount(ctx, mode, type, indirect,
+ drawcount_offset, maxdrawcount,
+ stride);
+}
+
+