ir_visitor_status ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir) { /* Note: for geometry shader inputs, lower_named_interface_blocks may * create 2D arrays, so we need to be able to handle those. 2D arrays * shouldn't be able to crop up for any other reason. */ if (ir_dereference_array * const inner_array = ir->array->as_dereference_array()) { /* ir => foo[i][j] * inner_array => foo[i] */ if (ir_dereference_variable * const deref_var = inner_array->array->as_dereference_variable()) { if (this->shader_type == GL_GEOMETRY_SHADER && deref_var->var->mode == ir_var_shader_in) { /* foo is a geometry shader input, so i is the vertex, and j the * part of the input we're accessing. */ if (try_mark_partial_variable(deref_var->var, ir->array_index)) { /* We've now taken care of foo and j, but i might contain a * subexpression that accesses shader inputs. So manually * visit i and then continue with the parent. */ inner_array->array_index->accept(this); return visit_continue_with_parent; } } } } else if (ir_dereference_variable * const deref_var = ir->array->as_dereference_variable()) { /* ir => foo[i], where foo is a variable. */ if (this->shader_type == GL_GEOMETRY_SHADER && deref_var->var->mode == ir_var_shader_in) { /* foo is a geometry shader input, so i is the vertex, and we're * accessing the entire input. */ mark_whole_variable(deref_var->var); /* We've now taken care of foo, but i might contain a subexpression * that accesses shader inputs. So manually visit i and then * continue with the parent. */ ir->array_index->accept(this); return visit_continue_with_parent; } else if (is_shader_inout(deref_var->var)) { /* foo is a shader input/output, but not a geometry shader input, * so i is the part of the input we're accessing. */ if (try_mark_partial_variable(deref_var->var, ir->array_index)) return visit_continue_with_parent; } } /* The expression is something we don't recognize. Just visit its * subexpressions. */ return visit_continue; }
/* Default handler: Mark all the locations in the variable as used. */ ir_visitor_status ir_set_program_inouts_visitor::visit(ir_dereference_variable *ir) { if (!is_shader_inout(ir->var)) return visit_continue; mark_whole_variable(ir->var); return visit_continue; }