[Mesa-dev] [PATCH 2/5] mesa: implement GL_ARB_draw_indirect and GL_ARB_multi_draw_indirect
v2: Removed some stray extern qualifiers. Documented use of Draw*IndirectCommand sizes. Removed separate extension enable flag for ARB_multi_draw_indirect since this can always be supported by looping. Kept generation of GL_INVALID_OPERATION in display list compile. The spec doesn't say anything about them, but all the direct drawing commands that support instancing do the same. --- src/mapi/glapi/gen/Makefile.am |1 + src/mapi/glapi/gen/gl_API.xml |4 +- src/mesa/main/api_validate.c| 153 +++ src/mesa/main/api_validate.h| 26 src/mesa/main/bufferobj.c |9 + src/mesa/main/dd.h | 12 ++ src/mesa/main/dlist.c | 41 + src/mesa/main/extensions.c |2 + src/mesa/main/get.c |5 + src/mesa/main/get_hash_params.py|2 + src/mesa/main/mtypes.h |3 + src/mesa/main/tests/dispatch_sanity.cpp |8 +- src/mesa/main/vtxfmt.c |7 + src/mesa/vbo/vbo_exec_array.c | 249 +++ src/mesa/vbo/vbo_save_api.c | 53 +++ 15 files changed, 570 insertions(+), 5 deletions(-) diff --git a/src/mapi/glapi/gen/Makefile.am b/src/mapi/glapi/gen/Makefile.am index 36e47e2..243c148 100644 --- a/src/mapi/glapi/gen/Makefile.am +++ b/src/mapi/glapi/gen/Makefile.am @@ -96,6 +96,7 @@ API_XML = \ ARB_depth_clamp.xml \ ARB_draw_buffers_blend.xml \ ARB_draw_elements_base_vertex.xml \ + ARB_draw_indirect.xml \ ARB_draw_instanced.xml \ ARB_ES2_compatibility.xml \ ARB_ES3_compatibility.xml \ diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml index df95924..f22fdac 100644 --- a/src/mapi/glapi/gen/gl_API.xml +++ b/src/mapi/glapi/gen/gl_API.xml @@ -8240,6 +8240,8 @@ !-- ARB extensions #86...#93 -- +xi:include href=ARB_draw_indirect.xml xmlns:xi=http://www.w3.org/2001/XInclude/ + category name=GL_ARB_transform_feedback3 number=94 enum name=MAX_TRANSFORM_FEEDBACK_BUFFERS value=0x8E70/ enum name=MAX_VERTEX_STREAMS value=0x8E71/ @@ -8317,7 +8319,7 @@ xi:include href=ARB_invalidate_subdata.xml xmlns:xi=http://www.w3.org/2001/XInclude/ -!-- ARB extensions #133...#138 -- +!-- ARB extensions #134...#138 -- xi:include href=ARB_texture_buffer_range.xml xmlns:xi=http://www.w3.org/2001/XInclude/ diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 53b0021..e875c5d 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -737,3 +737,156 @@ _mesa_validate_DrawTransformFeedback(struct gl_context *ctx, return GL_TRUE; } + +static GLboolean +valid_draw_indirect(struct gl_context *ctx, +GLenum mode, const GLvoid *indirect, +GLsizei size, const char *name) +{ + const GLsizeiptr end = (GLsizeiptr)indirect + size; + + if (!_mesa_valid_prim_mode(ctx, mode, name)) + return GL_FALSE; + + if ((GLsizeiptr)indirect (sizeof(GLuint) - 1)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + %s(indirect is not aligned), name); + return GL_FALSE; + } + + if (_mesa_is_bufferobj(ctx-DrawIndirectBuffer)) { + if (_mesa_bufferobj_mapped(ctx-DrawIndirectBuffer)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + %s(DRAW_INDIRECT_BUFFER is mapped), name); + return GL_FALSE; + } + if (ctx-DrawIndirectBuffer-Size end) { + _mesa_error(ctx, GL_INVALID_OPERATION, + %s(DRAW_INDIRECT_BUFFER too small), name); + return GL_FALSE; + } + } else { + if (ctx-API != API_OPENGL_COMPAT) { + _mesa_error(ctx, GL_INVALID_OPERATION, + %s: no buffer bound to DRAW_INDIRECT_BUFFER, name); + return GL_FALSE; + } + } + + if (!check_valid_to_render(ctx, name)) + return GL_FALSE; + + return GL_TRUE; +} + +static inline GLboolean +valid_draw_indirect_elements(struct gl_context *ctx, + GLenum mode, GLenum type, const GLvoid *indirect, + GLsizeiptr size, const char *name) +{ + if (!valid_elements_type(ctx, type, name)) + return GL_FALSE; + + /* +* 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.ArrayObj-ElementArrayBufferObj)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + %s(no buffer bound to GL_ELEMENT_ARRAY_BUFFER), name); + return GL_FALSE; + } + + return valid_draw_indirect(ctx, mode, indirect, size, name); +} + +static inline GLboolean +valid_draw_indirect_multi(struct gl_context *ctx, +
Re: [Mesa-dev] [PATCH 2/5] mesa: implement GL_ARB_draw_indirect and GL_ARB_multi_draw_indirect
On 04/05/2013 05:29 AM, Christoph Bumiller wrote: v2: Removed some stray extern qualifiers. Documented use of Draw*IndirectCommand sizes. Removed separate extension enable flag for ARB_multi_draw_indirect since this can always be supported by looping. Kept generation of GL_INVALID_OPERATION in display list compile. The spec doesn't say anything about them, but all the direct drawing commands that support instancing do the same. I think we can dodge the issue entirely. The extension spec says OpenGL 3.1 is required (though it's not immediately obvious to me why), and we only expose OpenGL 3.1 without compatibility... without display lists. It looks like (below) this extension is only exposed in core profile any way. Just gut all the API_OPENGL_COMPAT checks and all the display list stuff. That should simplify things a bit... --- src/mapi/glapi/gen/Makefile.am |1 + src/mapi/glapi/gen/gl_API.xml |4 +- src/mesa/main/api_validate.c| 153 +++ src/mesa/main/api_validate.h| 26 src/mesa/main/bufferobj.c |9 + src/mesa/main/dd.h | 12 ++ src/mesa/main/dlist.c | 41 + src/mesa/main/extensions.c |2 + src/mesa/main/get.c |5 + src/mesa/main/get_hash_params.py|2 + src/mesa/main/mtypes.h |3 + src/mesa/main/tests/dispatch_sanity.cpp |8 +- src/mesa/main/vtxfmt.c |7 + src/mesa/vbo/vbo_exec_array.c | 249 +++ src/mesa/vbo/vbo_save_api.c | 53 +++ 15 files changed, 570 insertions(+), 5 deletions(-) diff --git a/src/mapi/glapi/gen/Makefile.am b/src/mapi/glapi/gen/Makefile.am index 36e47e2..243c148 100644 --- a/src/mapi/glapi/gen/Makefile.am +++ b/src/mapi/glapi/gen/Makefile.am @@ -96,6 +96,7 @@ API_XML = \ ARB_depth_clamp.xml \ ARB_draw_buffers_blend.xml \ ARB_draw_elements_base_vertex.xml \ + ARB_draw_indirect.xml \ ARB_draw_instanced.xml \ ARB_ES2_compatibility.xml \ ARB_ES3_compatibility.xml \ diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml index df95924..f22fdac 100644 --- a/src/mapi/glapi/gen/gl_API.xml +++ b/src/mapi/glapi/gen/gl_API.xml @@ -8240,6 +8240,8 @@ !-- ARB extensions #86...#93 -- +xi:include href=ARB_draw_indirect.xml xmlns:xi=http://www.w3.org/2001/XInclude/ + category name=GL_ARB_transform_feedback3 number=94 enum name=MAX_TRANSFORM_FEEDBACK_BUFFERS value=0x8E70/ enum name=MAX_VERTEX_STREAMS value=0x8E71/ @@ -8317,7 +8319,7 @@ xi:include href=ARB_invalidate_subdata.xml xmlns:xi=http://www.w3.org/2001/XInclude/ -!-- ARB extensions #133...#138 -- +!-- ARB extensions #134...#138 -- xi:include href=ARB_texture_buffer_range.xml xmlns:xi=http://www.w3.org/2001/XInclude/ diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 53b0021..e875c5d 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -737,3 +737,156 @@ _mesa_validate_DrawTransformFeedback(struct gl_context *ctx, return GL_TRUE; } + +static GLboolean +valid_draw_indirect(struct gl_context *ctx, +GLenum mode, const GLvoid *indirect, +GLsizei size, const char *name) +{ + const GLsizeiptr end = (GLsizeiptr)indirect + size; + + if (!_mesa_valid_prim_mode(ctx, mode, name)) + return GL_FALSE; + + if ((GLsizeiptr)indirect (sizeof(GLuint) - 1)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + %s(indirect is not aligned), name); + return GL_FALSE; + } + + if (_mesa_is_bufferobj(ctx-DrawIndirectBuffer)) { + if (_mesa_bufferobj_mapped(ctx-DrawIndirectBuffer)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + %s(DRAW_INDIRECT_BUFFER is mapped), name); + return GL_FALSE; + } + if (ctx-DrawIndirectBuffer-Size end) { + _mesa_error(ctx, GL_INVALID_OPERATION, + %s(DRAW_INDIRECT_BUFFER too small), name); + return GL_FALSE; + } + } else { + if (ctx-API != API_OPENGL_COMPAT) { + _mesa_error(ctx, GL_INVALID_OPERATION, + %s: no buffer bound to DRAW_INDIRECT_BUFFER, name); + return GL_FALSE; + } + } + + if (!check_valid_to_render(ctx, name)) + return GL_FALSE; + + return GL_TRUE; +} + +static inline GLboolean +valid_draw_indirect_elements(struct gl_context *ctx, + GLenum mode, GLenum type, const GLvoid *indirect, + GLsizeiptr size, const char *name) +{ + if (!valid_elements_type(ctx, type, name)) + return GL_FALSE; + + /* +* Unlike regular DrawElementsInstancedBaseVertex commands, the indices +* may not come from a client array and must come from an index buffer. +* If no