vbo: optimize validation for glMultiDrawElements
authorMarek Olšák <maraeo@gmail.com>
Wed, 27 Jun 2012 04:29:42 +0000 (06:29 +0200)
committerMarek Olšák <maraeo@gmail.com>
Thu, 28 Jun 2012 20:46:51 +0000 (22:46 +0200)
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.

Reviewed-by: Brian Paul <brianp@vmware.com>
src/mesa/main/api_validate.c
src/mesa/main/api_validate.h
src/mesa/vbo/vbo_exec_array.c

index ec47f1d6d87355f0fa3b9853c924d8ad7fae2141..631bceecfee2b0b3749b648ae9e082a43a83f78c 100644 (file)
@@ -317,6 +317,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 * const *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.
index d92fd433f3ef168244330af20fdb70499b708603..59f3297681e537f36d63f0d13a4d14a480d4cbb3 100644 (file)
@@ -55,6 +55,12 @@ _mesa_validate_DrawElements(struct gl_context *ctx,
                            GLenum mode, GLsizei count, GLenum type,
                            const GLvoid *indices, GLint basevertex);
 
+extern GLboolean
+_mesa_validate_MultiDrawElements(struct gl_context *ctx,
+                                 GLenum mode, const GLsizei *count,
+                                 GLenum type, const GLvoid * const *indices,
+                                 GLuint primcount, const GLint *basevertex);
+
 extern GLboolean
 _mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode,
                                 GLuint start, GLuint end,
index ab9e246b20d3e6c80ae2a6e967c9838ebe6f6364..d2854dd6c29d4fcba616bcfac823d729e74539b3 100644 (file)
@@ -1254,13 +1254,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);
@@ -1275,13 +1272,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);