[Mesa-dev] [PATCH 2/5] mesa: implement GL_ARB_draw_indirect and GL_ARB_multi_draw_indirect

2013-04-05 Thread Christoph Bumiller
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

2013-04-05 Thread Ian Romanick

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