+
+ /* From the ARB_multi_draw_indirect specification:
+ * "<stride> must be a multiple of four, otherwise an INVALID_VALUE
+ * error is generated."
+ */
+ if (stride % 4) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride %% 4)", name);
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+GLboolean
+_mesa_validate_DrawArraysIndirect(struct gl_context *ctx,
+ GLenum mode,
+ const GLvoid *indirect)
+{
+ const unsigned drawArraysNumParams = 4;
+
+ FLUSH_CURRENT(ctx, 0);
+
+ return valid_draw_indirect(ctx, mode,
+ indirect, drawArraysNumParams * sizeof(GLuint),
+ "glDrawArraysIndirect");
+}
+
+GLboolean
+_mesa_validate_DrawElementsIndirect(struct gl_context *ctx,
+ GLenum mode, GLenum type,
+ const GLvoid *indirect)
+{
+ const unsigned drawElementsNumParams = 5;
+
+ FLUSH_CURRENT(ctx, 0);
+
+ return valid_draw_indirect_elements(ctx, mode, type,
+ indirect, drawElementsNumParams * sizeof(GLuint),
+ "glDrawElementsIndirect");
+}
+
+GLboolean
+_mesa_validate_MultiDrawArraysIndirect(struct gl_context *ctx,
+ GLenum mode,
+ const GLvoid *indirect,
+ GLsizei primcount, GLsizei stride)
+{
+ GLsizeiptr size = 0;
+ const unsigned drawArraysNumParams = 4;
+
+ FLUSH_CURRENT(ctx, 0);
+
+ /* caller has converted stride==0 to drawArraysNumParams * sizeof(GLuint) */
+ assert(stride != 0);
+
+ if (!valid_draw_indirect_multi(ctx, primcount, stride,
+ "glMultiDrawArraysIndirect"))
+ return GL_FALSE;
+
+ /* number of bytes of the indirect buffer which will be read */
+ size = primcount
+ ? (primcount - 1) * stride + drawArraysNumParams * sizeof(GLuint)
+ : 0;
+
+ if (!valid_draw_indirect(ctx, mode, indirect, size,
+ "glMultiDrawArraysIndirect"))
+ return GL_FALSE;
+
+ return GL_TRUE;
+}
+
+GLboolean
+_mesa_validate_MultiDrawElementsIndirect(struct gl_context *ctx,
+ GLenum mode, GLenum type,
+ const GLvoid *indirect,
+ GLsizei primcount, GLsizei stride)
+{
+ GLsizeiptr size = 0;
+ const unsigned drawElementsNumParams = 5;
+
+ FLUSH_CURRENT(ctx, 0);
+
+ /* caller has converted stride==0 to drawElementsNumParams * sizeof(GLuint) */
+ assert(stride != 0);
+
+ if (!valid_draw_indirect_multi(ctx, primcount, stride,
+ "glMultiDrawElementsIndirect"))
+ return GL_FALSE;
+
+ /* number of bytes of the indirect buffer which will be read */
+ size = primcount
+ ? (primcount - 1) * stride + drawElementsNumParams * sizeof(GLuint)
+ : 0;
+
+ if (!valid_draw_indirect_elements(ctx, mode, type,
+ indirect, size,
+ "glMultiDrawElementsIndirect"))
+ return GL_FALSE;
+
+ return GL_TRUE;
+}
+
+static GLboolean
+valid_draw_indirect_parameters(struct gl_context *ctx,
+ const char *name,
+ GLintptr drawcount)
+{
+ /* From the ARB_indirect_parameters specification:
+ * "INVALID_VALUE is generated by MultiDrawArraysIndirectCountARB or
+ * MultiDrawElementsIndirectCountARB if <drawcount> is not a multiple of
+ * four."
+ */
+ if (drawcount & 3) {