summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTimothy Arceri <[email protected]>2018-06-25 10:32:58 +1000
committerTimothy Arceri <[email protected]>2018-06-30 08:38:33 +1000
commitd2caa377416de12964b5763ad333f21622d11360 (patch)
tree949473d6a6f853ef29d2646661d4232d16c24d3e /src
parent103b8f11d660457c8b1c0041bb85a2f0e8d2ec95 (diff)
mesa: add compat profile support for ARB_multi_draw_indirect
v2: add missing ARB_base_instance support Reviewed-by: Marek Olšák <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/mesa/main/extensions_table.h2
-rw-r--r--src/mesa/vbo/vbo_exec_array.c77
2 files changed, 76 insertions, 3 deletions
diff --git a/src/mesa/main/extensions_table.h b/src/mesa/main/extensions_table.h
index 1446a4bd421..12b796777df 100644
--- a/src/mesa/main/extensions_table.h
+++ b/src/mesa/main/extensions_table.h
@@ -88,7 +88,7 @@ EXT(ARB_invalidate_subdata , dummy_true
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)
diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index dbb2590f0c9..58bba208db1 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -1749,7 +1749,38 @@ vbo_exec_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect,
/* 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);
@@ -1788,7 +1819,49 @@ vbo_exec_MultiDrawElementsIndirect(GLenum mode, GLenum type,
/* 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);