mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-04 02:40:11 +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>
This commit is contained in:
parent
85f7df81a9
commit
0f6fce1585
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