split_var_list_structs(nir_shader *shader,
nir_function_impl *impl,
struct exec_list *vars,
+ nir_variable_mode mode,
struct hash_table *var_field_map,
struct set **complex_vars,
void *mem_ctx)
* pull all of the variables we plan to split off of the list
*/
nir_foreach_variable_safe(var, vars) {
+ if (var->data.mode != mode)
+ continue;
+
if (!glsl_type_is_struct_or_ifc(glsl_without_array(var->type)))
continue;
if (modes & nir_var_shader_temp) {
has_global_splits = split_var_list_structs(shader, NULL,
&shader->globals,
+ nir_var_shader_temp,
var_field_map,
&complex_vars,
mem_ctx);
if (modes & nir_var_function_temp) {
has_local_splits = split_var_list_structs(shader, function->impl,
&function->impl->locals,
+ nir_var_function_temp,
var_field_map,
&complex_vars,
mem_ctx);
nir_metadata_preserve(function->impl, nir_metadata_block_index |
nir_metadata_dominance);
progress = true;
+ } else {
+ nir_metadata_preserve(function->impl, nir_metadata_all);
}
}
static bool
init_var_list_array_infos(nir_shader *shader,
struct exec_list *vars,
+ nir_variable_mode mode,
struct hash_table *var_info_map,
struct set **complex_vars,
void *mem_ctx)
bool has_array = false;
nir_foreach_variable(var, vars) {
+ if (var->data.mode != mode)
+ continue;
+
int num_levels = num_array_levels_in_array_of_vector_type(var->type);
if (num_levels <= 0)
continue;
if (!(deref->mode & modes))
return NULL;
- return get_array_var_info(nir_deref_instr_get_variable(deref),
- var_info_map);
+ nir_variable *var = nir_deref_instr_get_variable(deref);
+ if (var == NULL)
+ return NULL;
+
+ return get_array_var_info(var, var_info_map);
}
static void
split_var_list_arrays(nir_shader *shader,
nir_function_impl *impl,
struct exec_list *vars,
+ nir_variable_mode mode,
struct hash_table *var_info_map,
void *mem_ctx)
{
exec_list_make_empty(&split_vars);
nir_foreach_variable_safe(var, vars) {
+ if (var->data.mode != mode)
+ continue;
+
struct array_var_info *info = get_array_var_info(var, var_info_map);
if (!info)
continue;
if (modes & nir_var_shader_temp) {
has_global_array = init_var_list_array_infos(shader,
&shader->globals,
+ nir_var_shader_temp,
var_info_map,
&complex_vars,
mem_ctx);
if (modes & nir_var_function_temp) {
has_local_array = init_var_list_array_infos(shader,
&function->impl->locals,
+ nir_var_function_temp,
var_info_map,
&complex_vars,
mem_ctx);
/* If we failed to find any arrays of arrays, bail early. */
if (!has_any_array) {
ralloc_free(mem_ctx);
+ nir_shader_preserve_all_metadata(shader);
return false;
}
if (modes & nir_var_shader_temp) {
has_global_splits = split_var_list_arrays(shader, NULL,
&shader->globals,
+ nir_var_shader_temp,
var_info_map, mem_ctx);
}
if (modes & nir_var_function_temp) {
has_local_splits = split_var_list_arrays(shader, function->impl,
&function->impl->locals,
+ nir_var_function_temp,
var_info_map, mem_ctx);
}
nir_metadata_preserve(function->impl, nir_metadata_block_index |
nir_metadata_dominance);
progress = true;
+ } else {
+ nir_metadata_preserve(function->impl, nir_metadata_all);
}
}
comps &= ~(1u << i);
}
}
- } else if (src_alu->op == nir_op_vec2 ||
- src_alu->op == nir_op_vec3 ||
- src_alu->op == nir_op_vec4) {
+ } else if (nir_op_is_vec(src_alu->op)) {
/* If it's a vec, discount any channels that are just loads from the
* same deref put in the same spot.
*/
static bool
shrink_vec_var_list(struct exec_list *vars,
+ nir_variable_mode mode,
struct hash_table *var_usage_map)
{
/* Initialize the components kept field of each variable. This is the
* to leave components and array_len of any wildcards alone.
*/
nir_foreach_variable(var, vars) {
+ if (var->data.mode != mode)
+ continue;
+
struct vec_var_usage *usage =
get_vec_var_usage(var, var_usage_map, false, NULL);
if (!usage)
do {
fp_progress = false;
nir_foreach_variable(var, vars) {
+ if (var->data.mode != mode)
+ continue;
+
struct vec_var_usage *var_usage =
get_vec_var_usage(var, var_usage_map, false, NULL);
if (!var_usage || !var_usage->vars_copied)
bool vars_shrunk = false;
nir_foreach_variable_safe(var, vars) {
+ if (var->data.mode != mode)
+ continue;
+
struct vec_var_usage *usage =
get_vec_var_usage(var, var_usage_map, false, NULL);
if (!usage)
}
if (!has_vars_to_shrink) {
ralloc_free(mem_ctx);
+ nir_shader_preserve_all_metadata(shader);
return false;
}
bool globals_shrunk = false;
- if (modes & nir_var_shader_temp)
- globals_shrunk = shrink_vec_var_list(&shader->globals, var_usage_map);
+ if (modes & nir_var_shader_temp) {
+ globals_shrunk = shrink_vec_var_list(&shader->globals,
+ nir_var_shader_temp,
+ var_usage_map);
+ }
bool progress = false;
nir_foreach_function(function, shader) {
bool locals_shrunk = false;
if (modes & nir_var_function_temp) {
locals_shrunk = shrink_vec_var_list(&function->impl->locals,
+ nir_var_function_temp,
var_usage_map);
}
nir_metadata_preserve(function->impl, nir_metadata_block_index |
nir_metadata_dominance);
progress = true;
+ } else {
+ nir_metadata_preserve(function->impl, nir_metadata_all);
}
}