summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/api_validate.c
diff options
context:
space:
mode:
authorPaul Berry <stereotype441@gmail.com>2012-12-13 09:30:09 -0800
committerPaul Berry <stereotype441@gmail.com>2012-12-18 08:31:38 -0800
commitb87e65c3b61caeaa4f97a34d62e148e59a0dd5b8 (patch)
treed3cdac4f4cb681b525c9bae6e22865fc27b144b4 /src/mesa/main/api_validate.c
parentfebc237141ab06a478d05752dedc858c2b4b8599 (diff)
downloadexternal_mesa3d-b87e65c3b61caeaa4f97a34d62e148e59a0dd5b8.zip
external_mesa3d-b87e65c3b61caeaa4f97a34d62e148e59a0dd5b8.tar.gz
external_mesa3d-b87e65c3b61caeaa4f97a34d62e148e59a0dd5b8.tar.bz2
mesa/gles3: Generate error on draw call if transform feedback would overflow.
In desktop GL, if a draw call would cause transform feedback buffers to overflow, the draw call should succeed, and the extra primitives should simply not be recorded in the transform feedback buffers. In GLES3, however, if a draw call would cause transform feedback buffers to overflow, the draw call is supposed to produce an INVALID_OPERATION error and no drawing should occur. This patch implements the GLES3-required behaviour. Fixes GLES3 conformance test "transform_feedback_overflow.test". Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Diffstat (limited to 'src/mesa/main/api_validate.c')
-rw-r--r--src/mesa/main/api_validate.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
index 355a93c..1606282 100644
--- a/src/mesa/main/api_validate.c
+++ b/src/mesa/main/api_validate.c
@@ -516,6 +516,8 @@ GLboolean
_mesa_validate_DrawArrays(struct gl_context *ctx,
GLenum mode, GLint start, GLsizei count)
{
+ struct gl_transform_feedback_object *xfb_obj
+ = ctx->TransformFeedback.CurrentObject;
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
FLUSH_CURRENT(ctx, 0);
@@ -537,6 +539,29 @@ _mesa_validate_DrawArrays(struct gl_context *ctx,
return GL_FALSE;
}
+ /* From the GLES3 specification, section 2.14.2 (Transform Feedback
+ * Primitive Capture):
+ *
+ * The error INVALID_OPERATION is generated by DrawArrays and
+ * DrawArraysInstanced if recording the vertices of a primitive to the
+ * buffer objects being used for transform feedback purposes would result
+ * in either exceeding the limits of any buffer object’s size, or in
+ * exceeding the end position offset + size − 1, as set by
+ * BindBufferRange.
+ *
+ * This is in contrast to the behaviour of desktop GL, where the extra
+ * primitives are silently dropped from the transform feedback buffer.
+ */
+ if (_mesa_is_gles3(ctx) && xfb_obj->Active && !xfb_obj->Paused) {
+ size_t prim_count = vbo_count_tessellated_primitives(mode, count, 1);
+ if (xfb_obj->GlesRemainingPrims < prim_count) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawArrays(exceeds transform feedback size)");
+ return GL_FALSE;
+ }
+ xfb_obj->GlesRemainingPrims -= prim_count;
+ }
+
return GL_TRUE;
}
@@ -545,6 +570,8 @@ GLboolean
_mesa_validate_DrawArraysInstanced(struct gl_context *ctx, GLenum mode, GLint first,
GLsizei count, GLsizei numInstances)
{
+ struct gl_transform_feedback_object *xfb_obj
+ = ctx->TransformFeedback.CurrentObject;
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
FLUSH_CURRENT(ctx, 0);
@@ -580,6 +607,30 @@ _mesa_validate_DrawArraysInstanced(struct gl_context *ctx, GLenum mode, GLint fi
return GL_FALSE;
}
+ /* From the GLES3 specification, section 2.14.2 (Transform Feedback
+ * Primitive Capture):
+ *
+ * The error INVALID_OPERATION is generated by DrawArrays and
+ * DrawArraysInstanced if recording the vertices of a primitive to the
+ * buffer objects being used for transform feedback purposes would result
+ * in either exceeding the limits of any buffer object’s size, or in
+ * exceeding the end position offset + size − 1, as set by
+ * BindBufferRange.
+ *
+ * This is in contrast to the behaviour of desktop GL, where the extra
+ * primitives are silently dropped from the transform feedback buffer.
+ */
+ if (_mesa_is_gles3(ctx) && xfb_obj->Active && !xfb_obj->Paused) {
+ size_t prim_count
+ = vbo_count_tessellated_primitives(mode, count, numInstances);
+ if (xfb_obj->GlesRemainingPrims < prim_count) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawArraysInstanced(exceeds transform feedback size)");
+ return GL_FALSE;
+ }
+ xfb_obj->GlesRemainingPrims -= prim_count;
+ }
+
return GL_TRUE;
}