EXT(ARB_map_buffer_alignment , dummy_true , GLL, GLC, x , x , 2011)
EXT(ARB_map_buffer_range , ARB_map_buffer_range , GLL, GLC, x , x , 2008)
EXT(ARB_multi_bind , dummy_true , GLL, GLC, x , x , 2013)
-EXT(ARB_multi_draw_indirect , ARB_draw_indirect , x , GLC, x , x , 2012)
+EXT(ARB_multi_draw_indirect , ARB_draw_indirect , GLL, GLC, x , x , 2012)
EXT(ARB_multisample , dummy_true , GLL, x , x , x , 1994)
EXT(ARB_multitexture , dummy_true , GLL, x , x , x , 1998)
EXT(ARB_occlusion_query , ARB_occlusion_query , GLL, x , x , x , 2001)
/* If <stride> is zero, the array elements are treated as tightly packed. */
if (stride == 0)
- stride = 4 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */
+ stride = sizeof(DrawArraysIndirectCommand);
+
+ /* From the ARB_draw_indirect spec:
+ *
+ * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
+ * compatibility profile, this indicates that DrawArraysIndirect and
+ * DrawElementsIndirect are to source their arguments directly from the
+ * pointer passed as their <indirect> parameters."
+ */
+ if (ctx->API == API_OPENGL_COMPAT &&
+ !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) {
+
+ if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride,
+ "glMultiDrawArraysIndirect"))
+ return;
+
+ const ubyte *ptr = (const ubyte *) indirect;
+ for (unsigned i = 0; i < primcount; i++) {
+ DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) ptr;
+ vbo_exec_DrawArraysInstancedBaseInstance(mode, cmd->first,
+ cmd->count, cmd->primCount,
+ cmd->baseInstance);
+
+ if (stride == 0) {
+ ptr += sizeof(DrawArraysIndirectCommand);
+ } else {
+ ptr += stride;
+ }
+ }
+
+ return;
+ }
FLUSH_FOR_DRAW(ctx);
/* If <stride> is zero, the array elements are treated as tightly packed. */
if (stride == 0)
- stride = 5 * sizeof(GLuint); /* sizeof(DrawElementsIndirectCommand) */
+ stride = sizeof(DrawElementsIndirectCommand);
+
+
+ /* From the ARB_draw_indirect spec:
+ *
+ * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
+ * compatibility profile, this indicates that DrawArraysIndirect and
+ * DrawElementsIndirect are to source their arguments directly from the
+ * pointer passed as their <indirect> parameters."
+ */
+ if (ctx->API == API_OPENGL_COMPAT &&
+ !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) {
+ /*
+ * Unlike regular DrawElementsInstancedBaseVertex commands, the indices
+ * may not come from a client array and must come from an index buffer.
+ * If no element array buffer is bound, an INVALID_OPERATION error is
+ * generated.
+ */
+ if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glMultiDrawElementsIndirect(no buffer bound "
+ "to GL_ELEMENT_ARRAY_BUFFER)");
+
+ return;
+ }
+
+ if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride,
+ "glMultiDrawArraysIndirect"))
+ return;
+
+ const ubyte *ptr = (const ubyte *) indirect;
+ for (unsigned i = 0; i < primcount; i++) {
+ vbo_exec_DrawElementsIndirect(mode, type, ptr);
+
+ if (stride == 0) {
+ ptr += sizeof(DrawElementsIndirectCommand);
+ } else {
+ ptr += stride;
+ }
+ }
+
+ return;
+ }
FLUSH_FOR_DRAW(ctx);