On 04/07/2017 10:30 AM, Nicolai Hähnle wrote:
From: Nicolai Hähnle <nicolai.haeh...@amd.com>

When any count[i] is negative, we must skip all draws.

Moving to vbo makes the subsequent change easier.
---
  src/mapi/glapi/gen/gl_API.xml |  2 +-
  src/mesa/main/api_validate.c  | 38 ++++++++++++++++++++++++++++++++++++++
  src/mesa/main/api_validate.h  |  4 ++++
  src/mesa/main/varray.c        | 18 ------------------
  src/mesa/vbo/vbo_exec_array.c | 33 +++++++++++++++++++++++++++++++++
  src/mesa/vbo/vbo_save_api.c   | 35 +++++++++++++++++++++++++++++++++++
  6 files changed, 111 insertions(+), 19 deletions(-)

diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index c0ee2f2..522d2e5 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -10212,21 +10212,21 @@
      </function>
  </category>

  <category name="GL_EXT_texture_perturb_normal" number="147">
      <function name="TextureNormalEXT" exec="skip">
          <param name="mode" type="GLenum"/>
      </function>
  </category>

  <category name="GL_EXT_multi_draw_arrays" number="148">
-    <function name="MultiDrawArraysEXT" es1="1.0" es2="2.0" 
alias="MultiDrawArrays">
+    <function name="MultiDrawArraysEXT" es1="1.0" es2="2.0" exec="dynamic" 
alias="MultiDrawArrays">
          <param name="mode" type="GLenum"/>
          <param name="first" type="const GLint *"/>
          <param name="count" type="const GLsizei *"/>
          <param name="primcount" type="GLsizei"/>
      </function>

      <function name="MultiDrawElementsEXT" es1="1.0" es2="2.0" exec="dynamic" 
marshal="draw"
                marshal_fail="_mesa_glthread_is_non_vbo_draw_elements(ctx)">
          <param name="mode" type="GLenum"/>
          <param name="count" type="const GLsizei *"/>

Does the xml change have anything to do with the code movement? If not, split the patch?

-Brian

diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
index af4f7cb..2f0e159 100644
--- a/src/mesa/main/api_validate.c
+++ b/src/mesa/main/api_validate.c
@@ -906,20 +906,58 @@ _mesa_validate_DrawArraysInstanced(struct gl_context 
*ctx, GLenum mode, GLint fi
        if (numInstances < 0)
           _mesa_error(ctx, GL_INVALID_VALUE,
                       "glDrawArraysInstanced(numInstances=%d)", numInstances);
        return GL_FALSE;
     }

     return validate_draw_arrays(ctx, "glDrawArraysInstanced", mode, count, 1);
  }


+/**
+ * Called to error check the function parameters.
+ *
+ * Note that glMultiDrawArrays is not part of GLES, so there's limited scope
+ * for sharing code with the validation of glDrawArrays.
+ */
+bool
+_mesa_validate_MultiDrawArrays(struct gl_context *ctx, GLenum mode,
+                               const GLsizei *count, GLsizei primcount)
+{
+   int i;
+
+   FLUSH_CURRENT(ctx, 0);
+
+   if (primcount < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glMultiDrawArrays(primcount=%d)",
+                  primcount);
+      return false;
+   }
+
+   if (!_mesa_valid_prim_mode(ctx, mode, "glMultiDrawArrays"))
+      return false;
+
+   if (!check_valid_to_render(ctx, "glMultiDrawArrays"))
+      return false;
+
+   for (i = 0; i < primcount; ++i) {
+      if (count[i] < 0) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glMultiDrawArrays(count[%d]=%d)",
+                     i, count[i]);
+         return false;
+      }
+   }
+
+   return true;
+}
+
+
  GLboolean
  _mesa_validate_DrawElementsInstanced(struct gl_context *ctx,
                                       GLenum mode, GLsizei count, GLenum type,
                                       const GLvoid *indices, GLsizei 
numInstances)
  {
     FLUSH_CURRENT(ctx, 0);

     if (numInstances < 0) {
        _mesa_error(ctx, GL_INVALID_VALUE,
                    "glDrawElementsInstanced(numInstances=%d)", numInstances);
diff --git a/src/mesa/main/api_validate.h b/src/mesa/main/api_validate.h
index de520c9..93ec93d 100644
--- a/src/mesa/main/api_validate.h
+++ b/src/mesa/main/api_validate.h
@@ -41,20 +41,24 @@ _mesa_valid_to_render(struct gl_context *ctx, const char 
*where);
  extern bool
  _mesa_is_valid_prim_mode(struct gl_context *ctx, GLenum mode);

  extern GLboolean
  _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name);


  extern GLboolean
  _mesa_validate_DrawArrays(struct gl_context *ctx, GLenum mode, GLsizei count);

+extern bool
+_mesa_validate_MultiDrawArrays(struct gl_context *ctx, GLenum mode,
+                               const GLsizei *count, GLsizei primcount);
+
  extern GLboolean
  _mesa_validate_DrawElements(struct gl_context *ctx,
                            GLenum mode, GLsizei count, GLenum type,
                            const GLvoid *indices);

  extern GLboolean
  _mesa_validate_MultiDrawElements(struct gl_context *ctx,
                                   GLenum mode, const GLsizei *count,
                                   GLenum type, const GLvoid * const *indices,
                                   GLsizei primcount);
diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c
index af5abc8..07959a2 100644
--- a/src/mesa/main/varray.c
+++ b/src/mesa/main/varray.c
@@ -1534,38 +1534,20 @@ _mesa_UnlockArraysEXT( void )
        _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" );
        return;
     }

     ctx->Array.LockFirst = 0;
     ctx->Array.LockCount = 0;
     ctx->NewState |= _NEW_ARRAY;
  }


-/* GL_EXT_multi_draw_arrays */
-void GLAPIENTRY
-_mesa_MultiDrawArrays( GLenum mode, const GLint *first,
-                          const GLsizei *count, GLsizei primcount )
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLint i;
-
-   FLUSH_VERTICES(ctx, 0);
-
-   for (i = 0; i < primcount; i++) {
-      if (count[i] > 0) {
-         CALL_DrawArrays(ctx->CurrentClientDispatch, (mode, first[i], 
count[i]));
-      }
-   }
-}
-
-
  /* GL_IBM_multimode_draw_arrays */
  void GLAPIENTRY
  _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
                              const GLsizei * count,
                              GLsizei primcount, GLint modestride )
  {
     GET_CURRENT_CONTEXT(ctx);
     GLint i;

     FLUSH_VERTICES(ctx, 0);
diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index 30c52d5..bc4a18f 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -630,20 +630,52 @@ vbo_exec_DrawArraysInstancedBaseInstance(GLenum mode, 
GLint first,
     if (0)
        check_draw_arrays_data(ctx, first, count);

     vbo_draw_arrays(ctx, mode, first, count, numInstances, baseInstance);

     if (0)
        print_draw_arrays(ctx, mode, first, count);
  }


+/**
+ * Called from glMultiDrawArrays when in immediate mode.
+ */
+static void GLAPIENTRY
+vbo_exec_MultiDrawArrays(GLenum mode, const GLint *first,
+                         const GLsizei *count, GLsizei primcount)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLint i;
+
+   if (MESA_VERBOSE & VERBOSE_DRAW)
+      _mesa_debug(ctx,
+                  "glMultiDrawArrays(%s, %p, %p, %d)\n",
+                  _mesa_enum_to_string(mode), first, count, primcount);
+
+   if (!_mesa_validate_MultiDrawArrays(ctx, mode, count, primcount))
+      return;
+
+   for (i = 0; i < primcount; i++) {
+      if (count[i] > 0) {
+         if (0)
+            check_draw_arrays_data(ctx, first[i], count[i]);
+
+         vbo_draw_arrays(ctx, mode, first[i], count[i], 1, 0);
+
+         if (0)
+            print_draw_arrays(ctx, mode, first[i], count[i]);
+      }
+   }
+}
+
+

  /**
   * Map GL_ELEMENT_ARRAY_BUFFER and print contents.
   * For debugging.
   */
  #if 0
  static void
  dump_element_buffer(struct gl_context *ctx, GLenum type)
  {
     const GLvoid *map =
@@ -1685,20 +1717,21 @@ vbo_initialize_exec_dispatch(const struct gl_context 
*ctx,
        SET_MultiDrawElementsIndirectCountARB(exec,
                                              
vbo_exec_MultiDrawElementsIndirectCount);
     }

     if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
        SET_DrawArraysInstancedARB(exec, vbo_exec_DrawArraysInstanced);
        SET_DrawElementsInstancedARB(exec, vbo_exec_DrawElementsInstanced);
     }

     if (_mesa_is_desktop_gl(ctx)) {
+      SET_MultiDrawArrays(exec, vbo_exec_MultiDrawArrays);
        SET_DrawTransformFeedback(exec, vbo_exec_DrawTransformFeedback);
        SET_DrawTransformFeedbackStream(exec,
                                        vbo_exec_DrawTransformFeedbackStream);
        SET_DrawTransformFeedbackInstanced(exec,
                                           
vbo_exec_DrawTransformFeedbackInstanced);
        SET_DrawTransformFeedbackStreamInstanced(exec,
                                                 
vbo_exec_DrawTransformFeedbackStreamInstanced);
     }
  }

diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c
index f8dab0c..ad54c3b 100644
--- a/src/mesa/vbo/vbo_save_api.c
+++ b/src/mesa/vbo/vbo_save_api.c
@@ -1169,20 +1169,54 @@ _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei 
count)
                                | VBO_SAVE_PRIM_NO_CURRENT_UPDATE));

     for (i = 0; i < count; i++)
        CALL_ArrayElement(GET_DISPATCH(), (start + i));
     CALL_End(GET_DISPATCH(), ());

     _ae_unmap_vbos(ctx);
  }


+static void GLAPIENTRY
+_save_OBE_MultiDrawArrays(GLenum mode, const GLint *first,
+                          const GLsizei *count, GLsizei primcount)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLint i;
+
+   if (!_mesa_is_valid_prim_mode(ctx, mode)) {
+      _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMultiDrawArrays(mode)");
+      return;
+   }
+
+   if (primcount < 0) {
+      _mesa_compile_error(ctx, GL_INVALID_VALUE,
+                          "glMultiDrawArrays(primcount<0)");
+      return;
+   }
+
+   for (i = 0; i < primcount; i++) {
+      if (count[i] < 0) {
+         _mesa_compile_error(ctx, GL_INVALID_VALUE,
+                             "glMultiDrawArrays(count[i]<0)");
+         return;
+      }
+   }
+
+   for (i = 0; i < primcount; i++) {
+      if (count[i] > 0) {
+         _save_OBE_DrawArrays(mode, first[i], count[i]);
+      }
+   }
+}
+
+
  /* Could do better by copying the arrays and element list intact and
   * then emitting an indexed prim at runtime.
   */
  static void GLAPIENTRY
  _save_OBE_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
                                   const GLvoid * indices, GLint basevertex)
  {
     GET_CURRENT_CONTEXT(ctx);
     struct vbo_save_context *save = &vbo_context(ctx)->save;
     struct gl_buffer_object *indexbuf = ctx->Array.VAO->IndexBufferObj;
@@ -1477,20 +1511,21 @@ _save_vtxfmt_init(struct gl_context *ctx)

  /**
   * Initialize the dispatch table with the VBO functions for display
   * list compilation.
   */
  void
  vbo_initialize_save_dispatch(const struct gl_context *ctx,
                               struct _glapi_table *exec)
  {
     SET_DrawArrays(exec, _save_OBE_DrawArrays);
+   SET_MultiDrawArrays(exec, _save_OBE_MultiDrawArrays);
     SET_DrawElements(exec, _save_OBE_DrawElements);
     SET_DrawElementsBaseVertex(exec, _save_OBE_DrawElementsBaseVertex);
     SET_DrawRangeElements(exec, _save_OBE_DrawRangeElements);
     SET_MultiDrawElementsEXT(exec, _save_OBE_MultiDrawElements);
     SET_MultiDrawElementsBaseVertex(exec, 
_save_OBE_MultiDrawElementsBaseVertex);
     SET_Rectf(exec, _save_OBE_Rectf);
     /* Note: other glDraw functins aren't compiled into display lists */
  }




_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to