summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/main/bufferobj.c3
-rw-r--r--src/mesa/main/extensions_table.h2
-rw-r--r--src/mesa/vbo/vbo_exec_array.c71
3 files changed, 72 insertions, 4 deletions
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index 67f9cd0a902..1d1e51bc015 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -129,8 +129,7 @@ get_buffer_target(struct gl_context *ctx, GLenum target)
return &ctx->QueryBuffer;
break;
case GL_DRAW_INDIRECT_BUFFER:
- if ((ctx->API == API_OPENGL_CORE &&
- ctx->Extensions.ARB_draw_indirect) ||
+ if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_draw_indirect) ||
_mesa_is_gles31(ctx)) {
return &ctx->DrawIndirectBuffer;
}
diff --git a/src/mesa/main/extensions_table.h b/src/mesa/main/extensions_table.h
index f79a52cee8c..1446a4bd421 100644
--- a/src/mesa/main/extensions_table.h
+++ b/src/mesa/main/extensions_table.h
@@ -58,7 +58,7 @@ EXT(ARB_direct_state_access , dummy_true
EXT(ARB_draw_buffers , dummy_true , GLL, GLC, x , x , 2002)
EXT(ARB_draw_buffers_blend , ARB_draw_buffers_blend , GLL, GLC, x , x , 2009)
EXT(ARB_draw_elements_base_vertex , ARB_draw_elements_base_vertex , GLL, GLC, x , x , 2009)
-EXT(ARB_draw_indirect , ARB_draw_indirect , x , GLC, x , x , 2010)
+EXT(ARB_draw_indirect , ARB_draw_indirect , GLL, GLC, x , x , 2010)
EXT(ARB_draw_instanced , ARB_draw_instanced , GLL, GLC, x , x , 2008)
EXT(ARB_enhanced_layouts , ARB_enhanced_layouts , GLL, GLC, x , x , 2013)
EXT(ARB_explicit_attrib_location , ARB_explicit_attrib_location , GLL, GLC, x , x , 2009)
diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index 792907ac044..dbb2590f0c9 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -39,6 +39,21 @@
#include "main/macros.h"
#include "main/transformfeedback.h"
+typedef struct {
+ GLuint count;
+ GLuint primCount;
+ GLuint first;
+ GLuint baseInstance;
+} DrawArraysIndirectCommand;
+
+typedef struct {
+ GLuint count;
+ GLuint primCount;
+ GLuint firstIndex;
+ GLint baseVertex;
+ GLuint baseInstance;
+} DrawElementsIndirectCommand;
+
/**
* Check that element 'j' of the array has reasonable data.
@@ -1616,6 +1631,23 @@ vbo_exec_DrawArraysIndirect(GLenum mode, const GLvoid *indirect)
_mesa_debug(ctx, "glDrawArraysIndirect(%s, %p)\n",
_mesa_enum_to_string(mode), indirect);
+ /* 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)) {
+ DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) indirect;
+
+ vbo_exec_DrawArraysInstancedBaseInstance(mode, cmd->first, cmd->count,
+ cmd->primCount,
+ cmd->baseInstance);
+ return;
+ }
+
FLUSH_FOR_DRAW(ctx);
if (_mesa_is_no_error_enabled(ctx)) {
@@ -1647,6 +1679,43 @@ vbo_exec_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
_mesa_enum_to_string(mode),
_mesa_enum_to_string(type), indirect);
+ /* 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,
+ "glDrawElementsIndirect(no buffer bound "
+ "to GL_ELEMENT_ARRAY_BUFFER)");
+ } else {
+ DrawElementsIndirectCommand *cmd =
+ (DrawElementsIndirectCommand *) indirect;
+
+ /* Convert offset to pointer */
+ void *offset = (void *)
+ ((cmd->firstIndex * _mesa_sizeof_type(type)) & 0xffffffffUL);
+
+ vbo_exec_DrawElementsInstancedBaseVertexBaseInstance(mode, cmd->count,
+ type, offset,
+ cmd->primCount,
+ cmd->baseVertex,
+ cmd->baseInstance);
+ }
+
+ return;
+ }
+
FLUSH_FOR_DRAW(ctx);
if (_mesa_is_no_error_enabled(ctx)) {
@@ -1933,7 +2002,7 @@ vbo_initialize_exec_dispatch(const struct gl_context *ctx,
vbo_exec_DrawElementsInstancedBaseVertexBaseInstance);
}
- if (ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) {
+ if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) {
SET_DrawArraysIndirect(exec, vbo_exec_DrawArraysIndirect);
SET_DrawElementsIndirect(exec, vbo_exec_DrawElementsIndirect);
}