summaryrefslogtreecommitdiffstats
path: root/src/mesa/vbo
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/mesa/vbo
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/mesa/vbo')
-rw-r--r--src/mesa/vbo/vbo_exec_array.c77
1 files changed, 75 insertions, 2 deletions
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);