+ /* 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_stage == MESA_SHADER_GEOMETRY &&
+ deref_var->var->data.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_stage == MESA_SHADER_GEOMETRY &&
+ deref_var->var->data.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;
+ }