mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-27 01:10:25 +01:00
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@lists.freedesktop.org
Reviewed-and-Tested-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Dominik Behr <dbehr@chromium.org>
(cherry picked from commit 0f6fce1585)
This commit is contained in:
parent
130fda3d3b
commit
4fbbf49cc5
1 changed files with 32 additions and 0 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue