mesa: Validate the drawing primitive against the transform feedback mode.
authorEric Anholt <eric@anholt.net>
Wed, 14 Mar 2012 21:44:22 +0000 (14:44 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 20 Mar 2012 05:01:53 +0000 (22:01 -0700)
Fixes piglit GL_EXT_transform_feedback/negative-prims.

Reviewed-by: Brian Paul <brianp@vmware.com>
src/mesa/main/api_validate.c
src/mesa/main/transformfeedback.c
src/mesa/main/transformfeedback.h

index 17da5d0..02495a1 100644 (file)
@@ -29,6 +29,7 @@
 #include "imports.h"
 #include "mfeatures.h"
 #include "mtypes.h"
+#include "enums.h"
 #include "vbo/vbo.h"
 
 
@@ -215,9 +216,49 @@ _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name)
       _mesa_error(ctx, GL_INVALID_ENUM, "%s(mode=%x)", name, mode);
       return GL_FALSE;
    }
-   else {
-      return GL_TRUE;
+
+   /* From the GL_EXT_transform_feedback spec:
+    *
+    *     "The error INVALID_OPERATION is generated if Begin, or any command
+    *      that performs an explicit Begin, is called when:
+    *
+    *      * a geometry shader is not active and <mode> does not match the
+    *        allowed begin modes for the current transform feedback state as
+    *        given by table X.1.
+    *
+    *      * a geometry shader is active and the output primitive type of the
+    *        geometry shader does not match the allowed begin modes for the
+    *        current transform feedback state as given by table X.1.
+    *
+    */
+   if (ctx->TransformFeedback.CurrentObject->Active &&
+       !ctx->TransformFeedback.CurrentObject->Paused) {
+      GLboolean pass = GL_TRUE;
+
+      switch (mode) {
+      case GL_POINTS:
+         pass = ctx->TransformFeedback.Mode == GL_POINTS;
+        break;
+      case GL_LINES:
+      case GL_LINE_STRIP:
+      case GL_LINE_LOOP:
+         pass = ctx->TransformFeedback.Mode == GL_LINES;
+        break;
+      default:
+         pass = ctx->TransformFeedback.Mode == GL_TRIANGLES;
+        break;
+      }
+      if (!pass) {
+        _mesa_error(ctx, GL_INVALID_OPERATION,
+                    "%s(mode=%s vs transform feedback %s)",
+                    name,
+                    _mesa_lookup_prim_by_nr(mode),
+                    _mesa_lookup_prim_by_nr(ctx->TransformFeedback.Mode));
+        return GL_FALSE;
+      }
    }
+
+   return GL_TRUE;
 }
 
 
index c2114c2..f2c1435 100644 (file)
@@ -89,33 +89,6 @@ reference_transform_feedback_object(struct gl_transform_feedback_object **ptr,
 
 
 /**
- * Check if the given primitive mode (as in glBegin(mode)) is compatible
- * with the current transform feedback mode (if it's enabled).
- * This is to be called from glBegin(), glDrawArrays(), glDrawElements(), etc.
- *
- * \return GL_TRUE if the mode is OK, GL_FALSE otherwise.
- */
-GLboolean
-_mesa_validate_primitive_mode(struct gl_context *ctx, GLenum mode)
-{
-   if (ctx->TransformFeedback.CurrentObject->Active &&
-       !ctx->TransformFeedback.CurrentObject->Paused) {
-      switch (mode) {
-      case GL_POINTS:
-         return ctx->TransformFeedback.Mode == GL_POINTS;
-      case GL_LINES:
-      case GL_LINE_STRIP:
-      case GL_LINE_LOOP:
-         return ctx->TransformFeedback.Mode == GL_LINES;
-      default:
-         return ctx->TransformFeedback.Mode == GL_TRIANGLES;
-      }
-   }
-   return GL_TRUE;
-}
-
-
-/**
  * Check that all the buffer objects currently bound for transform
  * feedback actually exist.  Raise a GL_INVALID_OPERATION error if
  * any buffers are missing.
index 8a6672d..7d63de0 100644 (file)
@@ -42,9 +42,6 @@ _mesa_free_transform_feedback(struct gl_context *ctx);
 #if FEATURE_EXT_transform_feedback
 
 extern GLboolean
-_mesa_validate_primitive_mode(struct gl_context *ctx, GLenum mode);
-
-extern GLboolean
 _mesa_validate_transform_feedback_buffers(struct gl_context *ctx);