aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/main/api_validate.c
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/main/api_validate.c')
-rw-r--r--mesalib/src/mesa/main/api_validate.c94
1 files changed, 92 insertions, 2 deletions
diff --git a/mesalib/src/mesa/main/api_validate.c b/mesalib/src/mesa/main/api_validate.c
index e47db23e0..133fb6370 100644
--- a/mesalib/src/mesa/main/api_validate.c
+++ b/mesalib/src/mesa/main/api_validate.c
@@ -32,6 +32,7 @@
#include "mtypes.h"
#include "enums.h"
#include "vbo/vbo.h"
+#include "transformfeedback.h"
#include <stdbool.h>
@@ -252,8 +253,7 @@ _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name)
* current transform feedback state as given by table X.1.
*
*/
- if (ctx->TransformFeedback.CurrentObject->Active &&
- !ctx->TransformFeedback.CurrentObject->Paused) {
+ if (_mesa_is_xfb_active_and_unpaused(ctx)) {
GLboolean pass = GL_TRUE;
switch (mode) {
@@ -316,6 +316,19 @@ _mesa_validate_DrawElements(struct gl_context *ctx,
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
FLUSH_CURRENT(ctx, 0);
+ /* From the GLES3 specification, section 2.14.2 (Transform Feedback
+ * Primitive Capture):
+ *
+ * The error INVALID_OPERATION is also generated by DrawElements,
+ * DrawElementsInstanced, and DrawRangeElements while transform feedback
+ * is active and not paused, regardless of mode.
+ */
+ if (_mesa_is_gles3(ctx) && _mesa_is_xfb_active_and_unpaused(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawElements(transform feedback active)");
+ return GL_FALSE;
+ }
+
if (count <= 0) {
if (count < 0)
_mesa_error(ctx, GL_INVALID_VALUE, "glDrawElements(count)" );
@@ -434,6 +447,19 @@ _mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode,
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
FLUSH_CURRENT(ctx, 0);
+ /* From the GLES3 specification, section 2.14.2 (Transform Feedback
+ * Primitive Capture):
+ *
+ * The error INVALID_OPERATION is also generated by DrawElements,
+ * DrawElementsInstanced, and DrawRangeElements while transform feedback
+ * is active and not paused, regardless of mode.
+ */
+ if (_mesa_is_gles3(ctx) && _mesa_is_xfb_active_and_unpaused(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawElements(transform feedback active)");
+ return GL_FALSE;
+ }
+
if (count <= 0) {
if (count < 0)
_mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(count)" );
@@ -486,6 +512,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);
@@ -507,6 +535,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) && _mesa_is_xfb_active_and_unpaused(ctx)) {
+ 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;
}
@@ -515,6 +566,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);
@@ -550,6 +603,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) && _mesa_is_xfb_active_and_unpaused(ctx)) {
+ 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;
}
@@ -563,6 +640,19 @@ _mesa_validate_DrawElementsInstanced(struct gl_context *ctx,
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
FLUSH_CURRENT(ctx, 0);
+ /* From the GLES3 specification, section 2.14.2 (Transform Feedback
+ * Primitive Capture):
+ *
+ * The error INVALID_OPERATION is also generated by DrawElements,
+ * DrawElementsInstanced, and DrawRangeElements while transform feedback
+ * is active and not paused, regardless of mode.
+ */
+ if (_mesa_is_gles3(ctx) && _mesa_is_xfb_active_and_unpaused(ctx)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawElements(transform feedback active)");
+ return GL_FALSE;
+ }
+
if (count <= 0) {
if (count < 0)
_mesa_error(ctx, GL_INVALID_VALUE,