Fixes a bug where if an uniform array is passed to a function the accesses to the array are not propagated so later all but the first vector of the uniform array are removed in parcel_out_uniform_storage resulting in broken shaders and out of bounds access to arrays in brw::vec4_visitor::pack_uniform_registers.
Signed-off-by: Dominik Behr <db...@chromium.org> --- src/glsl/link_functions.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/glsl/link_functions.cpp b/src/glsl/link_functions.cpp index 6b3e154..32e2012 100644 --- a/src/glsl/link_functions.cpp +++ b/src/glsl/link_functions.cpp @@ -173,6 +173,32 @@ public: return visit_continue; } + virtual ir_visitor_status visit_leave(ir_call *ir) + { + /* traverse list of function parameters, and for array parameters + propagate max_array_access, do it when leaving the node + so the childen would propagate their array accesses first */ + exec_list_iterator sig_param_iter = ir->callee->parameters.iterator(); + exec_list_iterator param_iter = ir->actual_parameters.iterator(); + while (param_iter.has_next()) { + ir_variable *sig_param = (ir_variable *) sig_param_iter.get(); + ir_rvalue *param = (ir_rvalue *) param_iter.get(); + assert(sig_param); + assert(param); + if (sig_param->type->is_array()) { + ir_dereference_variable *deref = param->as_dereference_variable(); + if (deref && deref->var && deref->var->type->is_array()) { + if (sig_param->max_array_access > deref->var->max_array_access) { + deref->var->max_array_access = sig_param->max_array_access; + } + } + } + sig_param_iter.next(); + param_iter.next(); + } + return visit_continue; + } + virtual ir_visitor_status visit(ir_dereference_variable *ir) { if (hash_table_find(locals, ir->var) == NULL) { -- 1.8.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev