From: Timothy Arceri Date: Wed, 15 Nov 2017 03:28:01 +0000 (+1100) Subject: nir: add array lowering function that assumes there are no indirects X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2bc49ac3e6a6c8f93a2f32d62555bd653faf8d3e;p=mesa.git nir: add array lowering function that assumes there are no indirects The gallium glsl->nir pass currently lowers away all indirects on both inputs and outputs. This fuction allows us to lower vs inputs and fs outputs and also lower things one stage at a time as we don't need to worry about indirects on the other side of the shaders interface. Reviewed-by: Nicolai Hähnle Reviewed-by: Marek Olšák --- diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 83858afe148..189c17d1625 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -2496,6 +2496,7 @@ bool nir_lower_load_const_to_scalar(nir_shader *shader); bool nir_lower_read_invocation_to_scalar(nir_shader *shader); bool nir_lower_phis_to_scalar(nir_shader *shader); void nir_lower_io_arrays_to_elements(nir_shader *producer, nir_shader *consumer); +void nir_lower_io_arrays_to_elements_no_indirects(nir_shader *shader); void nir_lower_io_to_scalar(nir_shader *shader, nir_variable_mode mask); void nir_lower_io_to_scalar_early(nir_shader *shader, nir_variable_mode mask); diff --git a/src/compiler/nir/nir_lower_io_arrays_to_elements.c b/src/compiler/nir/nir_lower_io_arrays_to_elements.c index 94b93e3ec91..c785e22b0ea 100644 --- a/src/compiler/nir/nir_lower_io_arrays_to_elements.c +++ b/src/compiler/nir/nir_lower_io_arrays_to_elements.c @@ -35,6 +35,9 @@ static unsigned get_io_offset(nir_builder *b, nir_deref_var *deref, nir_variable *var, unsigned *element_index) { + bool vs_in = (b->shader->info.stage == MESA_SHADER_VERTEX) && + (var->data.mode == nir_var_shader_in); + nir_deref *tail = &deref->deref; /* For per-vertex input arrays (i.e. geometry shader inputs), skip the @@ -52,7 +55,7 @@ get_io_offset(nir_builder *b, nir_deref_var *deref, nir_variable *var, nir_deref_array *deref_array = nir_deref_as_array(tail); assert(deref_array->deref_array_type != nir_deref_array_type_indirect); - unsigned size = glsl_count_attribute_slots(tail->type, false); + unsigned size = glsl_count_attribute_slots(tail->type, vs_in); offset += size * deref_array->base_offset; unsigned num_elements = glsl_type_is_array(tail->type) ? @@ -339,6 +342,45 @@ lower_io_arrays_to_elements(nir_shader *shader, nir_variable_mode mask, } } +void +nir_lower_io_arrays_to_elements_no_indirects(nir_shader *shader) +{ + struct hash_table *split_inputs = + _mesa_hash_table_create(NULL, _mesa_hash_pointer, + _mesa_key_pointer_equal); + struct hash_table *split_outputs = + _mesa_hash_table_create(NULL, _mesa_hash_pointer, + _mesa_key_pointer_equal); + + uint64_t indirects[4] = {0}, patch_indirects[4] = {0}; + + lower_io_arrays_to_elements(shader, nir_var_shader_out, indirects, + patch_indirects, split_outputs); + + lower_io_arrays_to_elements(shader, nir_var_shader_in, indirects, + patch_indirects, split_inputs); + + /* Remove old input from the shaders inputs list */ + struct hash_entry *entry; + hash_table_foreach(split_inputs, entry) { + nir_variable *var = (nir_variable *) entry->key; + exec_node_remove(&var->node); + + free(entry->data); + } + + /* Remove old output from the shaders outputs list */ + hash_table_foreach(split_outputs, entry) { + nir_variable *var = (nir_variable *) entry->key; + exec_node_remove(&var->node); + + free(entry->data); + } + + _mesa_hash_table_destroy(split_inputs, NULL); + _mesa_hash_table_destroy(split_outputs, NULL); +} + void nir_lower_io_arrays_to_elements(nir_shader *producer, nir_shader *consumer) {