mesa/st: enable carry/borrow lowering pass
[mesa.git] / src / mesa / main / transformfeedback.c
index 76d213b16aaf4f2984a932154bd057d805c8b99f..a73746335fe50d402a8c3edc6bb925a0aabddb33 100644 (file)
@@ -24,7 +24,7 @@
 
 
 /*
- * Vertex transform feedback support.
+ * Transform feedback support.
  *
  * Authors:
  *   Brian Paul
@@ -32,7 +32,6 @@
 
 
 #include "buffers.h"
-#include "bufferobj.h"
 #include "context.h"
 #include "hash.h"
 #include "macros.h"
@@ -376,24 +375,48 @@ _mesa_compute_max_transform_feedback_vertices(
  **/
 
 
+/**
+ * Figure out which stage of the pipeline is the source of transform feedback
+ * data given the current context state, and return its gl_shader_program.
+ *
+ * If no active program can generate transform feedback data (i.e. no vertex
+ * shader is active), returns NULL.
+ */
+static struct gl_shader_program *
+get_xfb_source(struct gl_context *ctx)
+{
+   int i;
+   for (i = MESA_SHADER_GEOMETRY; i >= MESA_SHADER_VERTEX; i--) {
+      if (ctx->_Shader->CurrentProgram[i] != NULL)
+         return ctx->_Shader->CurrentProgram[i];
+   }
+   return NULL;
+}
+
+
 void GLAPIENTRY
 _mesa_BeginTransformFeedback(GLenum mode)
 {
    struct gl_transform_feedback_object *obj;
-   struct gl_transform_feedback_info *info;
+   struct gl_transform_feedback_info *info = NULL;
+   struct gl_shader_program *source;
    GLuint i;
    unsigned vertices_per_prim;
    GET_CURRENT_CONTEXT(ctx);
 
    obj = ctx->TransformFeedback.CurrentObject;
 
-   if (ctx->Shader.CurrentVertexProgram == NULL) {
+   /* Figure out what pipeline stage is the source of data for transform
+    * feedback.
+    */
+   source = get_xfb_source(ctx);
+   if (source == NULL) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glBeginTransformFeedback(no program active)");
       return;
    }
 
-   info = &ctx->Shader.CurrentVertexProgram->LinkedTransformFeedback;
+   info = &source->LinkedTransformFeedback;
 
    if (info->NumOutputs == 0) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
@@ -451,7 +474,10 @@ _mesa_BeginTransformFeedback(GLenum mode)
       obj->GlesRemainingPrims = max_vertices / vertices_per_prim;
    }
 
-   obj->shader_program = ctx->Shader.CurrentVertexProgram;
+   if (obj->shader_program != source) {
+      ctx->NewDriverState |= ctx->DriverFlags.NewTransformFeedbackProg;
+      obj->shader_program = source;
+   }
 
    assert(ctx->Driver.BeginTransformFeedback);
    ctx->Driver.BeginTransformFeedback(ctx, mode, obj);
@@ -506,19 +532,12 @@ bind_buffer_range(struct gl_context *ctx, GLuint index,
                                  bufObj);
 
    /* The per-attribute binding point */
-   _mesa_reference_buffer_object(ctx,
-                                 &obj->Buffers[index],
-                                 bufObj);
-
-   obj->BufferNames[index] = bufObj->Name;
-
-   obj->Offset[index] = offset;
-   obj->RequestedSize[index] = size;
+   _mesa_set_transform_feedback_binding(ctx, obj, index, bufObj, offset, size);
 }
 
 
 /**
- * Specify a buffer object to receive vertex shader results.  Plus,
+ * Specify a buffer object to receive transform feedback results.  Plus,
  * specify the starting offset to place the results, and max size.
  * Called from the glBindBufferRange() function.
  */
@@ -562,7 +581,7 @@ _mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,
 
 
 /**
- * Specify a buffer object to receive vertex shader results.
+ * Specify a buffer object to receive transform feedback results.
  * As above, but start at offset = 0.
  * Called from the glBindBufferBase() function.
  */
@@ -591,7 +610,7 @@ _mesa_bind_buffer_base_transform_feedback(struct gl_context *ctx,
 
 
 /**
- * Specify a buffer object to receive vertex shader results, plus the
+ * Specify a buffer object to receive transform feedback results, plus the
  * offset in the buffer to start placing results.
  * This function is part of GL_EXT_transform_feedback, but not GL3.
  */
@@ -646,7 +665,7 @@ _mesa_BindBufferOffsetEXT(GLenum target, GLuint index, GLuint buffer,
 
 
 /**
- * This function specifies the vertex shader outputs to be written
+ * This function specifies the transform feedback outputs to be written
  * to the feedback buffer(s), and in what order.
  */
 void GLAPIENTRY
@@ -756,7 +775,7 @@ _mesa_TransformFeedbackVaryings(GLuint program, GLsizei count,
 
 
 /**
- * Get info about the vertex shader's outputs which are to be written
+ * Get info about the transform feedback outputs which are to be written
  * to the feedback buffer(s).
  */
 void GLAPIENTRY
@@ -993,9 +1012,9 @@ _mesa_ResumeTransformFeedback(void)
     *  the program object being used by the current transform feedback object
     *  is not active."
     */
-   if (obj->shader_program != ctx->Shader.CurrentVertexProgram) {
+   if (obj->shader_program != get_xfb_source(ctx)) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glResumeTransformFeedback(wrong vertex program bound)");
+                  "glResumeTransformFeedback(wrong program bound)");
       return;
    }