diff options
Diffstat (limited to 'mesalib/src/mesa/main/transformfeedback.c')
-rw-r--r-- | mesalib/src/mesa/main/transformfeedback.c | 58 |
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; |