[Mesa-dev] [PATCH 4/4] vbo: optimize validation for glMultiDrawElements

Marek Olšák maraeo at gmail.com
Tue Jun 26 22:18:41 PDT 2012


Some parameters need to be checked only once.
check_valid_to_render needs to be called only once.

The validate function is based on the one for DrawElements.
---
 src/mesa/main/api_validate.c  |   70 +++++++++++++++++++++++++++++++++++++++++
 src/mesa/main/api_validate.h  |    6 ++++
 src/mesa/vbo/vbo_exec_array.c |   18 ++++-------
 3 files changed, 82 insertions(+), 12 deletions(-)

diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
index ec47f1d..d139dd3 100644
--- a/src/mesa/main/api_validate.c
+++ b/src/mesa/main/api_validate.c
@@ -318,6 +318,76 @@ _mesa_validate_DrawElements(struct gl_context *ctx,
 
 
 /**
+ * Error checking for glMultiDrawElements().  Includes parameter checking
+ * and VBO bounds checking.
+ * \return GL_TRUE if OK to render, GL_FALSE if error found
+ */
+GLboolean
+_mesa_validate_MultiDrawElements(struct gl_context *ctx,
+                                 GLenum mode, const GLsizei *count,
+                                 GLenum type, const GLvoid **indices,
+                                 GLuint primcount, const GLint *basevertex)
+{
+   unsigned i;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, GL_FALSE);
+
+   for (i = 0; i < primcount; i++) {
+      if (count[i] <= 0) {
+         if (count[i] < 0)
+            _mesa_error(ctx, GL_INVALID_VALUE,
+                        "glMultiDrawElements(count)" );
+         return GL_FALSE;
+      }
+   }
+
+   if (!_mesa_valid_prim_mode(ctx, mode, "glMultiDrawElements")) {
+      return GL_FALSE;
+   }
+
+   if (type != GL_UNSIGNED_INT &&
+       type != GL_UNSIGNED_BYTE &&
+       type != GL_UNSIGNED_SHORT)
+   {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glMultiDrawElements(type)" );
+      return GL_FALSE;
+   }
+
+   if (!check_valid_to_render(ctx, "glMultiDrawElements"))
+      return GL_FALSE;
+
+   /* Vertex buffer object tests */
+   if (_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj)) {
+      /* use indices in the buffer object */
+      /* make sure count doesn't go outside buffer bounds */
+      for (i = 0; i < primcount; i++) {
+         if (index_bytes(type, count[i]) >
+             ctx->Array.ArrayObj->ElementArrayBufferObj->Size) {
+            _mesa_warning(ctx,
+                          "glMultiDrawElements index out of buffer bounds");
+            return GL_FALSE;
+         }
+      }
+   }
+   else {
+      /* not using a VBO */
+      for (i = 0; i < primcount; i++) {
+         if (!indices[i])
+            return GL_FALSE;
+      }
+   }
+
+   for (i = 0; i < primcount; i++) {
+      if (!check_index_bounds(ctx, count[i], type, indices[i],
+                              basevertex ? basevertex[i] : 0))
+         return GL_FALSE;
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
  * Error checking for glDrawRangeElements().  Includes parameter checking
  * and VBO bounds checking.
  * \return GL_TRUE if OK to render, GL_FALSE if error found
diff --git a/src/mesa/main/api_validate.h b/src/mesa/main/api_validate.h
index d92fd43..50294ca 100644
--- a/src/mesa/main/api_validate.h
+++ b/src/mesa/main/api_validate.h
@@ -56,6 +56,12 @@ _mesa_validate_DrawElements(struct gl_context *ctx,
 			    const GLvoid *indices, GLint basevertex);
 
 extern GLboolean
+_mesa_validate_MultiDrawElements(struct gl_context *ctx,
+                                 GLenum mode, const GLsizei *count,
+                                 GLenum type, const GLvoid **indices,
+                                 GLuint primcount, const GLint *basevertex);
+
+extern GLboolean
 _mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode,
 				 GLuint start, GLuint end,
 				 GLsizei count, GLenum type,
diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index 0058f87..b318eb5 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -1253,13 +1253,10 @@ vbo_exec_MultiDrawElements(GLenum mode,
 			   GLsizei primcount)
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLint i;
 
-   for (i = 0; i < primcount; i++) {
-      if (!_mesa_validate_DrawElements(ctx, mode, count[i], type, indices[i],
-				       0))
-	 return;
-   }
+   if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
+                                         primcount, NULL))
+      return;
 
    vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
 				   NULL);
@@ -1274,13 +1271,10 @@ vbo_exec_MultiDrawElementsBaseVertex(GLenum mode,
 				     const GLsizei *basevertex)
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLint i;
 
-   for (i = 0; i < primcount; i++) {
-      if (!_mesa_validate_DrawElements(ctx, mode, count[i], type, indices[i],
-				       basevertex[i]))
-	 return;
-   }
+   if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
+                                         primcount, basevertex))
+      return;
 
    vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
 				   basevertex);
-- 
1.7.9.5



More information about the mesa-dev mailing list