Mesa (9.2): glsl: propagate max_array_access through function calls

Carl Worth cworth at kemper.freedesktop.org
Fri Sep 27 23:03:18 UTC 2013


Module: Mesa
Branch: 9.2
Commit: 4fbbf49cc577feb9357455590c6f8d7283525e60
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=4fbbf49cc577feb9357455590c6f8d7283525e60

Author: Dominik Behr <dbehr at chromium.org>
Date:   Wed Sep  4 14:40:48 2013 -0700

glsl: propagate max_array_access through function calls

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.

Cc: mesa-stable at lists.freedesktop.org
Reviewed-and-Tested-by: Matt Turner <mattst88 at gmail.com>
Signed-off-by: Dominik Behr <dbehr at chromium.org>
(cherry picked from commit 0f6fce15852d3d6fb5251e42394332a62788ef67)

---

 src/glsl/link_functions.cpp |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/src/glsl/link_functions.cpp b/src/glsl/link_functions.cpp
index 6b3e154..dd6f247 100644
--- a/src/glsl/link_functions.cpp
+++ b/src/glsl/link_functions.cpp
@@ -173,6 +173,38 @@ 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. Otherwise arrays that are only referenced
+       * from inside functions via function parameters will be incorrectly
+       * optimized. This will lead to incorrect code being generated (or worse).
+       * Do it when leaving the node so the children would propagate their
+       * array accesses first.
+       */
+
+      const exec_node *formal_param_node = ir->callee->parameters.get_head();
+      if (formal_param_node) {
+         const exec_node *actual_param_node = ir->actual_parameters.get_head();
+         while (!actual_param_node->is_tail_sentinel()) {
+            ir_variable *formal_param = (ir_variable *) formal_param_node;
+            ir_rvalue *actual_param = (ir_rvalue *) actual_param_node;
+
+            formal_param_node = formal_param_node->get_next();
+            actual_param_node = actual_param_node->get_next();
+
+            if (formal_param->type->is_array()) {
+               ir_dereference_variable *deref = actual_param->as_dereference_variable();
+               if (deref && deref->var && deref->var->type->is_array()) {
+                  deref->var->max_array_access =
+                     MAX2(formal_param->max_array_access, deref->var->max_array_access);
+               }
+            }
+         }
+      }
+      return visit_continue;
+   }
+
    virtual ir_visitor_status visit(ir_dereference_variable *ir)
    {
       if (hash_table_find(locals, ir->var) == NULL) {




More information about the mesa-commit mailing list