On 17 January 2012 09:31, Christoph Bumiller <span dir="ltr">&lt;<a href="mailto:e0425955@student.tuwien.ac.at">e0425955@student.tuwien.ac.at</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The nvc0 gallium driver is advertising 128 MAX_INTERLEAVED_COMPS<br>
which made it always assert in the linker when TFB was used since<br>
the Outputs array was smaller than that maximum.<br>
<br>
NOTE: This is a candidate for the 8.0 branch.<br>
---<br>
 src/glsl/linker.cpp    |   57 +++++++++++++++++++++++++++++------------------<br>
 src/mesa/main/mtypes.h |   32 ++++++++++++++------------<br>
 2 files changed, 52 insertions(+), 37 deletions(-)<br>
<br>
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp<br>
index 0d85aee..1a986ef 100644<br>
--- a/src/glsl/linker.cpp<br>
+++ b/src/glsl/linker.cpp<br>
@@ -1388,6 +1388,7 @@ public:<br>
    static bool is_same(const tfeedback_decl &amp;x, const tfeedback_decl &amp;y);<br>
    bool assign_location(struct gl_context *ctx, struct gl_shader_program *prog,<br>
                         ir_variable *output_var);<br>
+   bool accumulate_num_outputs(struct gl_shader_program *prog, unsigned *count);<br>
    bool store(struct gl_context *ctx, struct gl_shader_program *prog,<br>
               struct gl_transform_feedback_info *info, unsigned buffer,<br>
              unsigned varying) const;<br>
@@ -1624,16 +1625,9 @@ tfeedback_decl::assign_location(struct gl_context *ctx,<br>
 }<br>
<br>
<br>
-/**<br>
- * Update gl_transform_feedback_info to reflect this tfeedback_decl.<br>
- *<br>
- * If an error occurs, the error is reported through linker_error() and false<br>
- * is returned.<br>
- */<br>
 bool<br>
-tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,<br>
-                      struct gl_transform_feedback_info *info,<br>
-                      unsigned buffer, unsigned varying) const<br>
+tfeedback_decl::accumulate_num_outputs(struct gl_shader_program *prog,<br>
+                                       unsigned *count)<br>
 {<br>
    if (!this-&gt;is_assigned()) {<br>
       /* From GL_EXT_transform_feedback:<br>
@@ -1648,6 +1642,27 @@ tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,<br>
       return false;<br>
    }<br>
<br>
+   unsigned translated_size = this-&gt;size;<br>
+   if (this-&gt;is_clip_distance_mesa)<br>
+      translated_size = (translated_size + 3) / 4;<br>
+<br>
+   *count += translated_size * this-&gt;matrix_columns;<br>
+<br>
+   return true;<br>
+}<br>
+<br>
+<br>
+/**<br>
+ * Update gl_transform_feedback_info to reflect this tfeedback_decl.<br>
+ *<br>
+ * If an error occurs, the error is reported through linker_error() and false<br>
+ * is returned.<br>
+ */<br>
+bool<br>
+tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,<br>
+                      struct gl_transform_feedback_info *info,<br>
+                      unsigned buffer, unsigned varying) const<br>
+{<br>
    /* From GL_EXT_transform_feedback:<br>
     *   A program will fail to link if:<br>
     *<br>
@@ -1663,19 +1678,6 @@ tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,<br>
       return false;<br>
    }<br>
<br>
-   /* Verify that the checks on MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS<br>
-    * and MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS are sufficient to prevent<br>
-    * overflow of info-&gt;Outputs[].  In worst case we generate one entry in<br>
-    * Outputs[] per component so a conservative check is to verify that the<br>
-    * size of the array is greater than or equal to both<br>
-    * MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS and<br>
-    * MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS.<br>
-    */<br>
-   assert(Elements(info-&gt;Outputs) &gt;=<br>
-          ctx-&gt;Const.MaxTransformFeedbackInterleavedComponents);<br>
-   assert(Elements(info-&gt;Outputs) &gt;=<br>
-          ctx-&gt;Const.MaxTransformFeedbackSeparateComponents);<br>
-<br>
    unsigned translated_size = this-&gt;size;<br>
    if (this-&gt;is_clip_distance_mesa)<br>
       translated_size = (translated_size + 3) / 4;<br>
@@ -1976,6 +1978,7 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,<br>
       prog-&gt;TransformFeedback.BufferMode == GL_SEPARATE_ATTRIBS;<br>
<br>
    ralloc_free(prog-&gt;LinkedTransformFeedback.Varyings);<br>
+   ralloc_free(prog-&gt;LinkedTransformFeedback.Outputs);<br>
<br>
    memset(&amp;prog-&gt;LinkedTransformFeedback, 0,<br>
           sizeof(prog-&gt;LinkedTransformFeedback));<br>
@@ -1988,6 +1991,16 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,<br>
                    struct gl_transform_feedback_varying_info,<br>
                    num_tfeedback_decls);<br>
<br>
+   unsigned num_outputs = 0;<br>
+   for (unsigned i = 0; i &lt; num_tfeedback_decls; ++i)<br>
+      if (!tfeedback_decls[i].accumulate_num_outputs(prog, &amp;num_outputs))<br>
+         return false;<br>
+<br>
+   prog-&gt;LinkedTransformFeedback.Outputs =<br>
+      rzalloc_array(prog-&gt;LinkedTransformFeedback.Outputs,<br>
+                    struct gl_transform_feedback_output,<br>
+                    num_outputs);<br>
+<br></blockquote><div><br>Can we add an assertion to the bottom of store_tfeedback_info to verify that num_outputs == prog-&gt;LinkedTransformFeedback.NumOutputs?  That would give me a lot more confidence in this patch.<br>
<br>With that change, this patch is:<br><br>Reviewed-by: Paul Berry &lt;<a href="mailto:stereotype441@gmail.com">stereotype441@gmail.com</a>&gt;<br></div></div>