gen7/pipeline: Actually use inputs_read from the VS for laying out inputs
[mesa.git] / src / glsl / link_varyings.h
index 057e4b219252864454219fa9d0603988166a1854..1d12978fa301b33c616852a7a35c1140bf3a4a60 100644 (file)
@@ -41,6 +41,49 @@ struct gl_shader;
 class ir_variable;
 
 
+/**
+ * Data structure describing a varying which is available for use in transform
+ * feedback.
+ *
+ * For example, if the vertex shader contains:
+ *
+ *     struct S {
+ *       vec4 foo;
+ *       float[3] bar;
+ *     };
+ *
+ *     varying S[2] v;
+ *
+ * Then there would be tfeedback_candidate objects corresponding to the
+ * following varyings:
+ *
+ *     v[0].foo
+ *     v[0].bar
+ *     v[1].foo
+ *     v[1].bar
+ */
+struct tfeedback_candidate
+{
+   /**
+    * Toplevel variable containing this varying.  In the above example, this
+    * would point to the declaration of the varying v.
+    */
+   ir_variable *toplevel_var;
+
+   /**
+    * Type of this varying.  In the above example, this would point to the
+    * glsl_type for "vec4" or "float[3]".
+    */
+   const glsl_type *type;
+
+   /**
+    * Offset within the toplevel variable where this varying occurs (counted
+    * in multiples of the size of a float).
+    */
+   unsigned offset;
+};
+
+
 /**
  * Data structure tracking information about a transform feedback declaration
  * during linking.
@@ -48,17 +91,16 @@ class ir_variable;
 class tfeedback_decl
 {
 public:
-   bool init(struct gl_context *ctx, struct gl_shader_program *prog,
-             const void *mem_ctx, const char *input);
+   void init(struct gl_context *ctx, const void *mem_ctx, const char *input);
    static bool is_same(const tfeedback_decl &x, const tfeedback_decl &y);
-   bool assign_location(struct gl_context *ctx, struct gl_shader_program *prog,
-                        ir_variable *output_var);
+   bool assign_location(struct gl_context *ctx,
+                        struct gl_shader_program *prog);
    unsigned get_num_outputs() const;
    bool store(struct gl_context *ctx, struct gl_shader_program *prog,
               struct gl_transform_feedback_info *info, unsigned buffer,
               const unsigned max_outputs) const;
-   ir_variable *find_output_var(gl_shader_program *prog,
-                                gl_shader *producer) const;
+   const tfeedback_candidate *find_candidate(gl_shader_program *prog,
+                                             hash_table *tfeedback_candidates);
 
    bool is_next_buffer_separator() const
    {
@@ -70,19 +112,57 @@ public:
       return !this->next_buffer_separator && !this->skip_components;
    }
 
+   const char *name() const
+   {
+      return this->orig_name;
+   }
+
+   unsigned get_stream_id() const
+   {
+      return this->stream_id;
+   }
+
    /**
     * The total number of varying components taken up by this variable.  Only
     * valid if assign_location() has been called.
     */
    unsigned num_components() const
    {
-      if (this->is_clip_distance_mesa)
+      if (this->lowered_builtin_array_variable)
          return this->size;
       else
-         return this->vector_elements * this->matrix_columns * this->size;
+         return this->vector_elements * this->matrix_columns * this->size *
+            (this->is_double() ? 2 : 1);
+   }
+
+   unsigned get_location() const {
+      return this->location;
    }
 
 private:
+
+   bool is_double() const
+   {
+      switch (this->type) {
+      case GL_DOUBLE:
+      case GL_DOUBLE_VEC2:
+      case GL_DOUBLE_VEC3:
+      case GL_DOUBLE_VEC4:
+      case GL_DOUBLE_MAT2:
+      case GL_DOUBLE_MAT2x3:
+      case GL_DOUBLE_MAT2x4:
+      case GL_DOUBLE_MAT3:
+      case GL_DOUBLE_MAT3x2:
+      case GL_DOUBLE_MAT3x4:
+      case GL_DOUBLE_MAT4:
+      case GL_DOUBLE_MAT4x2:
+      case GL_DOUBLE_MAT4x3:
+         return true;
+      default:
+         return false;
+      }
+   }
+
    /**
     * The name that was supplied to glTransformFeedbackVaryings.  Used for
     * error reporting and glGetTransformFeedbackVarying().
@@ -105,10 +185,15 @@ private:
    unsigned array_subscript;
 
    /**
-    * True if the variable is gl_ClipDistance and the driver lowers
-    * gl_ClipDistance to gl_ClipDistanceMESA.
+    * Non-zero if the variable is gl_ClipDistance, glTessLevelOuter or
+    * gl_TessLevelInner and the driver lowers it to gl_*MESA.
     */
-   bool is_clip_distance_mesa;
+   enum {
+      none,
+      clip_distance,
+      tess_level_outer,
+      tess_level_inner,
+   } lowered_builtin_array_variable;
 
    /**
     * The vertex shader output location that the linker assigned for this
@@ -158,10 +243,23 @@ private:
     * Whether this is gl_NextBuffer from ARB_transform_feedback3.
     */
    bool next_buffer_separator;
+
+   /**
+    * If find_candidate() has been called, pointer to the tfeedback_candidate
+    * data structure that was found.  Otherwise NULL.
+    */
+   const tfeedback_candidate *matched_candidate;
+
+   /**
+    * StreamId assigned to this varying (defaults to 0). Can only be set to
+    * values other than 0 in geometry shaders that use the stream layout
+    * modifier. Accepted values must be in the range [0, MAX_VERTEX_STREAMS-1].
+    */
+   unsigned stream_id;
 };
 
 
-bool
+void
 cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
                                 gl_shader *producer, gl_shader *consumer);
 
@@ -183,4 +281,14 @@ assign_varying_locations(struct gl_context *ctx,
                          unsigned num_tfeedback_decls,
                          tfeedback_decl *tfeedback_decls);
 
+bool
+check_against_output_limit(struct gl_context *ctx,
+                           struct gl_shader_program *prog,
+                           gl_shader *producer);
+
+bool
+check_against_input_limit(struct gl_context *ctx,
+                          struct gl_shader_program *prog,
+                          gl_shader *consumer);
+
 #endif /* GLSL_LINK_VARYINGS_H */