When validating draw parameters move check for 0 draw count last (drawing with count 0 is not an error), so that other parameters (e.g.: the primitive type) are validated and the correct errors (if applicable) are generated.
>From the OpenGL 3.3 spec page 33 (page 48 of the PDF): "[Regarding DrawArraysOneInstance, in terms of which other draw operations are defined:] If count is negative, an INVALID_VALUE error is generated." This patch also changes the bahavior of MultiDrawElements to perform the draw operation if some primitive's index counts are zero. Signed-off-by: Fabian Bieler <fabianbie...@fastmail.fm> --- src/mesa/main/api_validate.c | 51 +++++++++++++++++++++++++------------------ src/mesa/vbo/vbo_exec_array.c | 12 ++++++++++ 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 7ab8e30..0770f94 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -334,9 +334,8 @@ _mesa_validate_DrawElements(struct gl_context *ctx, return GL_FALSE; } - if (count <= 0) { - if (count < 0) - _mesa_error(ctx, GL_INVALID_VALUE, "glDrawElements(count)" ); + if (count < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDrawElements(count)" ); return GL_FALSE; } @@ -368,6 +367,9 @@ _mesa_validate_DrawElements(struct gl_context *ctx, if (!check_index_bounds(ctx, count, type, indices, basevertex)) return GL_FALSE; + if (count == 0) + return GL_FALSE; + return GL_TRUE; } @@ -388,10 +390,9 @@ _mesa_validate_MultiDrawElements(struct gl_context *ctx, FLUSH_CURRENT(ctx, 0); for (i = 0; i < primcount; i++) { - if (count[i] <= 0) { - if (count[i] < 0) - _mesa_error(ctx, GL_INVALID_VALUE, - "glMultiDrawElements(count)" ); + if (count[i] < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glMultiDrawElements(count)" ); return GL_FALSE; } } @@ -463,9 +464,8 @@ _mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode, return GL_FALSE; } - if (count <= 0) { - if (count < 0) - _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(count)" ); + if (count < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(count)" ); return GL_FALSE; } @@ -502,6 +502,9 @@ _mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode, if (!check_index_bounds(ctx, count, type, indices, basevertex)) return GL_FALSE; + if (count == 0) + return GL_FALSE; + return GL_TRUE; } @@ -519,9 +522,8 @@ _mesa_validate_DrawArrays(struct gl_context *ctx, = ctx->TransformFeedback.CurrentObject; FLUSH_CURRENT(ctx, 0); - if (count <= 0) { - if (count < 0) - _mesa_error(ctx, GL_INVALID_VALUE, "glDrawArrays(count)" ); + if (count < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDrawArrays(count)" ); return GL_FALSE; } @@ -560,6 +562,9 @@ _mesa_validate_DrawArrays(struct gl_context *ctx, xfb_obj->GlesRemainingPrims -= prim_count; } + if (count == 0) + return GL_FALSE; + return GL_TRUE; } @@ -572,10 +577,9 @@ _mesa_validate_DrawArraysInstanced(struct gl_context *ctx, GLenum mode, GLint fi = ctx->TransformFeedback.CurrentObject; FLUSH_CURRENT(ctx, 0); - if (count <= 0) { - if (count < 0) - _mesa_error(ctx, GL_INVALID_VALUE, - "glDrawArraysInstanced(count=%d)", count); + if (count < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glDrawArraysInstanced(count=%d)", count); return GL_FALSE; } @@ -628,6 +632,9 @@ _mesa_validate_DrawArraysInstanced(struct gl_context *ctx, GLenum mode, GLint fi xfb_obj->GlesRemainingPrims -= prim_count; } + if (count == 0) + return GL_FALSE; + return GL_TRUE; } @@ -653,10 +660,9 @@ _mesa_validate_DrawElementsInstanced(struct gl_context *ctx, return GL_FALSE; } - if (count <= 0) { - if (count < 0) - _mesa_error(ctx, GL_INVALID_VALUE, - "glDrawElementsInstanced(count=%d)", count); + if (count < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glDrawElementsInstanced(count=%d)", count); return GL_FALSE; } @@ -693,6 +699,9 @@ _mesa_validate_DrawElementsInstanced(struct gl_context *ctx, return GL_FALSE; } + if (count == 0) + return GL_FALSE; + if (!check_index_bounds(ctx, count, type, indices, basevertex)) return GL_FALSE; diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 9dadd04..c080000 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -1298,6 +1298,16 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, } } + /* Draw primitives individually if one count is zero, so we can easily skip + * that primitive. + */ + for (i = 0; i < primcount; i++) { + if (count[i] == 0) { + fallback = GL_TRUE; + break; + } + } + /* If the index buffer isn't in a VBO, then treating the application's * subranges of the index buffer as one large index buffer may lead to * us reading unmapped memory. @@ -1334,6 +1344,8 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, } else { /* render one prim at a time */ for (i = 0; i < primcount; i++) { + if (count[i] == 0) + continue; ib.count = count[i]; ib.type = type; ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj; -- 1.8.1.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev