spirv: add some tests for volatile/available/visible
[mesa.git] / src / compiler / nir / nir_split_per_member_structs.c
index f649c8f474bf26eed521fa89b7ad39a0bc81f2a0..6c9b314002e7f42551323604dbd84a5a5c816ee5 100644 (file)
@@ -50,9 +50,10 @@ member_type(const struct glsl_type *type, unsigned index)
    if (glsl_type_is_array(type)) {
       const struct glsl_type *elem =
          member_type(glsl_get_array_element(type), index);
-      return glsl_array_type(elem, glsl_get_length(type));
+      assert(glsl_get_explicit_stride(type) == 0);
+      return glsl_array_type(elem, glsl_get_length(type), 0);
    } else {
-      assert(glsl_type_is_struct(type));
+      assert(glsl_type_is_struct_or_ifc(type));
       assert(index < glsl_get_length(type));
       return glsl_get_struct_field(type, index);
    }
@@ -65,7 +66,7 @@ split_variable(struct nir_variable *var, nir_shader *shader,
    assert(var->state_slots == NULL);
 
    /* Constant initializers are currently not handled */
-   assert(var->constant_initializer == NULL);
+   assert(var->constant_initializer == NULL && var->pointer_initializer == NULL);
 
    nir_variable **members =
       ralloc_array(dead_ctx, nir_variable *, var->num_members);
@@ -102,24 +103,6 @@ split_variable(struct nir_variable *var, nir_shader *shader,
    _mesa_hash_table_insert(var_to_member_map, var, members);
 }
 
-static bool
-split_variables_in_list(struct exec_list *var_list, nir_shader *shader,
-                        struct hash_table *var_to_member_map, void *dead_ctx)
-{
-   bool progress = false;
-
-   nir_foreach_variable_safe(var, var_list) {
-      if (var->num_members == 0)
-         continue;
-
-      split_variable(var, shader, var_to_member_map, dead_ctx);
-      exec_node_remove(&var->node);
-      progress = true;
-   }
-
-   return progress;
-}
-
 static nir_deref_instr *
 build_member_deref(nir_builder *b, nir_deref_instr *deref, nir_variable *member)
 {
@@ -174,17 +157,23 @@ nir_split_per_member_structs(nir_shader *shader)
    bool progress = false;
    void *dead_ctx = ralloc_context(NULL);
    struct hash_table *var_to_member_map =
-      _mesa_hash_table_create(dead_ctx, _mesa_hash_pointer,
-                              _mesa_key_pointer_equal);
-
-   progress |= split_variables_in_list(&shader->inputs, shader,
-                                       var_to_member_map, dead_ctx);
-   progress |= split_variables_in_list(&shader->outputs, shader,
-                                       var_to_member_map, dead_ctx);
-   progress |= split_variables_in_list(&shader->system_values, shader,
-                                       var_to_member_map, dead_ctx);
-   if (!progress)
+      _mesa_pointer_hash_table_create(dead_ctx);
+
+   nir_foreach_variable_with_modes_safe(var, shader, nir_var_shader_in |
+                                                     nir_var_shader_out |
+                                                     nir_var_system_value) {
+      if (var->num_members == 0)
+         continue;
+
+      split_variable(var, shader, var_to_member_map, dead_ctx);
+      exec_node_remove(&var->node);
+      progress = true;
+   }
+
+   if (!progress) {
+      ralloc_free(dead_ctx);
       return false;
+   }
 
    nir_foreach_function(function, shader) {
       if (!function->impl)
@@ -200,6 +189,10 @@ nir_split_per_member_structs(nir_shader *shader)
             }
          }
       }
+
+      nir_metadata_preserve(function->impl,
+                            nir_metadata_block_index |
+                            nir_metadata_dominance);
    }
 
    ralloc_free(dead_ctx);