summaryrefslogtreecommitdiffstats
path: root/src/compiler/nir
diff options
context:
space:
mode:
authorTimothy Arceri <[email protected]>2017-11-15 14:28:01 +1100
committerTimothy Arceri <[email protected]>2017-12-04 12:52:18 +1100
commit2bc49ac3e6a6c8f93a2f32d62555bd653faf8d3e (patch)
tree9caed5a39297aac2b94d2105331dcff72edf123a /src/compiler/nir
parentf13790c92ff1433a0fbff35788761b75df567c44 (diff)
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 <[email protected]> Reviewed-by: Marek Olšák <[email protected]>
Diffstat (limited to 'src/compiler/nir')
-rw-r--r--src/compiler/nir/nir.h1
-rw-r--r--src/compiler/nir/nir_lower_io_arrays_to_elements.c44
2 files changed, 44 insertions, 1 deletions
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) ?
@@ -340,6 +343,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)
{
struct hash_table *split_inputs =