diff options
author | Rhys Perry <[email protected]> | 2019-04-09 20:18:11 +0100 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2019-08-08 12:10:39 -0500 |
commit | fd73ed1bd7e4d5a6af05d29908d6c4e2cca868b5 (patch) | |
tree | e1b02f6eb96ba121eb2ad116362f0197dfba79e9 /src/compiler/nir | |
parent | 8bd2e138f5db8ab6f82ec7597edb946d84edd3bf (diff) |
nir: add nir_lower_to_explicit()
v2: use glsl_type_size_align_func
v2: move get_explicit_type() to glsl_types.cpp/nir_types.cpp
v2: use align() instead of util_align_npot()
v2: pack arrays a bit tighter
v2: rename mem_* to field_*
v2: don't attempt to handle when struct offsets are already set
v2: use column_type() instead of recreating it
v2: use a branch instead of |= in nir_lower_to_explicit_impl()
v2: assign locations to variables and update shared_size and num_shared
v2: allow the pass to be used with nir_var_{shader_temp,function_temp}
v4: rebase
v5: add TODO
v5: small formatting changes
v5: remove incorrect assert in get_explicit_type()
v5: rename to nir_lower_vars_to_explicit_types
v5: correctly update progress when only variables are updated
v5: rename get_explicit_type() to get_explicit_shared_type()
v5: add comment explaining how get_explicit_shared_type() is different
v5: update cast strides
v6: update progress when lowering nir_var_function_temp variables
v6: formatting changes
v6: add more detailed documentation comment for get_explicit_shared_type
v6: rename get_explicit_shared_type to get_explicit_type_for_size_align
v7: fix comment in nir_lower_vars_to_explicit_types_impl()
Signed-off-by: Rhys Perry <[email protected]>
Reviewed-by: Caio Marcelo de Oliveira Filho <[email protected]> (v5)
Reviewed-by: Jason Ekstrand <[email protected]>
Diffstat (limited to 'src/compiler/nir')
-rw-r--r-- | src/compiler/nir/nir.h | 5 | ||||
-rw-r--r-- | src/compiler/nir/nir_lower_io.c | 107 |
2 files changed, 112 insertions, 0 deletions
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 06acfc6c562..8bec9760767 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -3464,6 +3464,11 @@ bool nir_lower_io(nir_shader *shader, bool nir_io_add_const_offset_to_base(nir_shader *nir, nir_variable_mode mode); +bool +nir_lower_vars_to_explicit_types(nir_shader *shader, + nir_variable_mode modes, + glsl_type_size_align_func type_info); + typedef enum { /** * An address format which is a simple 32-bit global GPU address. diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c index f8bcf4420e0..271c2a895f1 100644 --- a/src/compiler/nir/nir_lower_io.c +++ b/src/compiler/nir/nir_lower_io.c @@ -35,6 +35,8 @@ #include "nir_builder.h" #include "nir_deref.h" +#include "util/u_math.h" + struct lower_io_state { void *dead_ctx; nir_builder builder; @@ -1332,6 +1334,111 @@ nir_lower_explicit_io(nir_shader *shader, nir_variable_mode modes, return progress; } +static bool +nir_lower_vars_to_explicit_types_impl(nir_function_impl *impl, + nir_variable_mode modes, + glsl_type_size_align_func type_info) +{ + bool progress = false; + + nir_foreach_block(block, impl) { + nir_foreach_instr(instr, block) { + if (instr->type != nir_instr_type_deref) + continue; + + nir_deref_instr *deref = nir_instr_as_deref(instr); + if (!(deref->mode & modes)) + continue; + + unsigned size, alignment; + const struct glsl_type *new_type = + glsl_get_explicit_type_for_size_align(deref->type, type_info, &size, &alignment); + if (new_type != deref->type) { + progress = true; + deref->type = new_type; + } + if (deref->deref_type == nir_deref_type_cast) { + /* See also glsl_type::get_explicit_type_for_size_align() */ + unsigned new_stride = align(size, alignment); + if (new_stride != deref->cast.ptr_stride) { + deref->cast.ptr_stride = new_stride; + progress = true; + } + } + } + } + + if (progress) { + nir_metadata_preserve(impl, nir_metadata_block_index | + nir_metadata_dominance | + nir_metadata_live_ssa_defs | + nir_metadata_loop_analysis); + } + + return progress; +} + +static bool +lower_vars_to_explicit(nir_shader *shader, + struct exec_list *vars, nir_variable_mode mode, + glsl_type_size_align_func type_info) +{ + bool progress = false; + unsigned offset = 0; + nir_foreach_variable(var, vars) { + unsigned size, align; + const struct glsl_type *explicit_type = + glsl_get_explicit_type_for_size_align(var->type, type_info, &size, &align); + + if (explicit_type != var->type) { + progress = true; + var->type = explicit_type; + } + + var->data.driver_location = ALIGN_POT(offset, align); + offset = var->data.driver_location + size; + } + + if (mode == nir_var_mem_shared) { + shader->info.cs.shared_size = offset; + shader->num_shared = offset; + } + + return progress; +} + +bool +nir_lower_vars_to_explicit_types(nir_shader *shader, + nir_variable_mode modes, + glsl_type_size_align_func type_info) +{ + /* TODO: Situations which need to be handled to support more modes: + * - row-major matrices + * - compact shader inputs/outputs + * - interface types + */ + nir_variable_mode supported = nir_var_mem_shared | nir_var_shader_temp | nir_var_function_temp; + assert(!(modes & ~supported) && "unsupported"); + + bool progress = false; + + if (modes & nir_var_mem_shared) + progress |= lower_vars_to_explicit(shader, &shader->shared, nir_var_mem_shared, type_info); + if (modes & nir_var_shader_temp) + progress |= lower_vars_to_explicit(shader, &shader->globals, nir_var_shader_temp, type_info); + + nir_foreach_function(function, shader) { + if (function->impl) { + if (modes & nir_var_function_temp) + progress |= lower_vars_to_explicit(shader, &function->impl->locals, nir_var_function_temp, type_info); + + progress |= nir_lower_vars_to_explicit_types_impl(function->impl, modes, type_info); + } + } + + return progress; +} + /** * Return the offset source for a load/store intrinsic. */ |