From 5f90fb4007d6f2bb763b1cc63aef98fd38f65d0b Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Sat, 23 Jun 2018 17:09:13 +1000 Subject: [PATCH] mesa: add ARB_draw_indirect support to compat profile MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit v2: add missing ARB_base_instance support Reviewed-by: Marek Olšák --- src/mesa/main/bufferobj.c | 3 +- src/mesa/main/extensions_table.h | 2 +- src/mesa/vbo/vbo_exec_array.c | 71 +++++++++++++++++++++++++++++++- 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 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 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); } -- 2.30.2