<div dir="ltr">Updated patch. Previous one would reference NULL pointer if the list of formal parameters was empty.</div><div class="gmail_extra"><br clear="all"><div><div dir="ltr"><div>--</div>Dominik<br></div></div>
<br><br><div class="gmail_quote">On Wed, Sep 4, 2013 at 2:40 PM, Dominik Behr <span dir="ltr"><<a href="mailto:dbehr@chromium.org" target="_blank">dbehr@chromium.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Fixes a bug where if an uniform array is passed to a function the accesses<br>
to the array are not propagated so later all but the first vector of the<br>
uniform array are removed in parcel_out_uniform_storage resulting in<br>
broken shaders and out of bounds access to arrays in<br>
brw::vec4_visitor::pack_uniform_registers.<br>
<br>
Signed-off-by: Dominik Behr <<a href="mailto:dbehr@chromium.org">dbehr@chromium.org</a>><br>
---<br>
 src/glsl/link_functions.cpp | 31 +++++++++++++++++++++++++++++++<br>
 1 file changed, 31 insertions(+)<br>
<br>
diff --git a/src/glsl/link_functions.cpp b/src/glsl/link_functions.cpp<br>
index 6b3e154..547a963 100644<br>
--- a/src/glsl/link_functions.cpp<br>
+++ b/src/glsl/link_functions.cpp<br>
@@ -173,6 +173,37 @@ public:<br>
       return visit_continue;<br>
    }<br>
<br>
+   virtual ir_visitor_status visit_leave(ir_call *ir)<br>
+   {<br>
+      /* Traverse list of function parameters, and for array parameters<br>
+         propagate max_array_access, Otherwise arrays that are only referenced<br>
+         from inside functions via function parameters will be incorrectly<br>
+         optimized. This will lead to incorrect code being generated (or worse).<br>
+         Do it when leaving the node so the childen would propagate their<br>
+         array accesses first */<br>
+<br>
+      const exec_node *formal_param_node = ir->callee->parameters.get_head();<br>
+      if (formal_param_node) {<br>
+         const exec_node *actual_param_node = ir->actual_parameters.get_head();<br>
+         while (!actual_param_node->is_tail_sentinel()) {<br>
+            ir_variable *formal_param = (ir_variable *) formal_param_node;<br>
+            ir_rvalue *actual_param = (ir_rvalue *) actual_param_node;<br>
+<br>
+            formal_param_node = formal_param_node->get_next();<br>
+            actual_param_node = actual_param_node->get_next();<br>
+<br>
+            if (formal_param->type->is_array()) {<br>
+               ir_dereference_variable *deref = actual_param->as_dereference_variable();<br>
+               if (deref && deref->var && deref->var->type->is_array()) {<br>
+                  deref->var->max_array_access =<br>
+                     MAX2(formal_param->max_array_access, deref->var->max_array_access);<br>
+               }<br>
+            }<br>
+         }<br>
+      }<br>
+      return visit_continue;<br>
+   }<br>
+<br>
    virtual ir_visitor_status visit(ir_dereference_variable *ir)<br>
    {<br>
       if (hash_table_find(locals, ir->var) == NULL) {<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.4<br>
<br>
</font></span></blockquote></div><br></div>