aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/main/transformfeedback.c
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/main/transformfeedback.c')
-rw-r--r--mesalib/src/mesa/main/transformfeedback.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/mesalib/src/mesa/main/transformfeedback.c b/mesalib/src/mesa/main/transformfeedback.c
index 3f8a7f48d..bc9b52ab9 100644
--- a/mesalib/src/mesa/main/transformfeedback.c
+++ b/mesalib/src/mesa/main/transformfeedback.c
@@ -44,6 +44,41 @@
#include "program/prog_parameter.h"
+struct using_program_tuple
+{
+ struct gl_shader_program *shProg;
+ bool found;
+};
+
+static void
+active_xfb_object_references_program(GLuint key, void *data, void *user_data)
+{
+ struct using_program_tuple *callback_data = user_data;
+ struct gl_transform_feedback_object *obj = data;
+ if (obj->Active && obj->shader_program == callback_data->shProg)
+ callback_data->found = true;
+}
+
+/**
+ * Return true if any active transform feedback object is using a program.
+ */
+bool
+_mesa_transform_feedback_is_using_program(struct gl_context *ctx,
+ struct gl_shader_program *shProg)
+{
+ struct using_program_tuple callback_data;
+ callback_data.shProg = shProg;
+ callback_data.found = false;
+
+ _mesa_HashWalk(ctx->TransformFeedback.Objects,
+ active_xfb_object_references_program, &callback_data);
+
+ /* Also check DefaultObject, as it's not in the Objects hash table. */
+ active_xfb_object_references_program(0, ctx->TransformFeedback.DefaultObject,
+ &callback_data);
+
+ return callback_data.found;
+}
/**
* Do reference counting of transform feedback buffers.
@@ -406,6 +441,8 @@ _mesa_BeginTransformFeedback(GLenum mode)
obj->GlesRemainingPrims = max_vertices / vertices_per_prim;
}
+ obj->shader_program = ctx->Shader.CurrentVertexProgram;
+
assert(ctx->Driver.BeginTransformFeedback);
ctx->Driver.BeginTransformFeedback(ctx, mode, obj);
}
@@ -611,6 +648,16 @@ _mesa_TransformFeedbackVaryings(GLuint program, GLsizei count,
GLint i;
GET_CURRENT_CONTEXT(ctx);
+ /* From the ARB_transform_feedback2 specification:
+ * "The error INVALID_OPERATION is generated by TransformFeedbackVaryings
+ * if the current transform feedback object is active, even if paused."
+ */
+ if (ctx->TransformFeedback.CurrentObject->Active) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTransformFeedbackVaryings(current object is active)");
+ return;
+ }
+
switch (bufferMode) {
case GL_INTERLEAVED_ATTRIBS:
break;
@@ -931,6 +978,17 @@ _mesa_ResumeTransformFeedback(void)
return;
}
+ /* From the ARB_transform_feedback2 specification:
+ * "The error INVALID_OPERATION is generated by ResumeTransformFeedback if
+ * the program object being used by the current transform feedback object
+ * is not active."
+ */
+ if (obj->shader_program != ctx->Shader.CurrentVertexProgram) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glResumeTransformFeedback(wrong vertex program bound)");
+ return;
+ }
+
FLUSH_VERTICES(ctx, 0);
ctx->NewDriverState |= ctx->DriverFlags.NewTransformFeedback;