mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 22:49:13 +02:00
mesa/main: Check for 0 size draws after validation.
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 <fabianbieler@fastmail.fm> Reviewed-by: Brian Paul <brianp@vmware.com> Reviewed-by: Paul Berry <stereotype441@gmail.com>
This commit is contained in:
parent
ac74de3710
commit
cd18269705
2 changed files with 42 additions and 21 deletions
|
|
@ -402,9 +402,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;
|
||||
}
|
||||
|
||||
|
|
@ -436,6 +435,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;
|
||||
}
|
||||
|
||||
|
|
@ -456,10 +458,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -531,9 +532,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;
|
||||
}
|
||||
|
||||
|
|
@ -570,6 +570,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;
|
||||
}
|
||||
|
||||
|
|
@ -587,9 +590,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;
|
||||
}
|
||||
|
||||
|
|
@ -628,6 +630,9 @@ _mesa_validate_DrawArrays(struct gl_context *ctx,
|
|||
xfb_obj->GlesRemainingPrims -= prim_count;
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
return GL_FALSE;
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -640,10 +645,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;
|
||||
}
|
||||
|
||||
|
|
@ -696,6 +700,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;
|
||||
}
|
||||
|
||||
|
|
@ -721,10 +728,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;
|
||||
}
|
||||
|
||||
|
|
@ -761,6 +767,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;
|
||||
|
||||
|
|
|
|||
|
|
@ -1334,6 +1334,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.
|
||||
|
|
@ -1370,6 +1380,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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue