From fcebb157f0eb6c2f374dee609a01b0b14856e7fc Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Wed, 27 Jun 2012 06:29:42 +0200 Subject: [PATCH] vbo: optimize validation for glMultiDrawElements 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 --- 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 ec47f1d6d87..631bceecfee 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -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. diff --git a/src/mesa/main/api_validate.h b/src/mesa/main/api_validate.h index d92fd433f3e..59f3297681e 100644 --- a/src/mesa/main/api_validate.h +++ b/src/mesa/main/api_validate.h @@ -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, diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index ab9e246b20d..d2854dd6c29 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -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); -- 2.30.2