summaryrefslogtreecommitdiffstats
path: root/src/compiler/nir
diff options
context:
space:
mode:
authorRhys Perry <[email protected]>2019-04-09 20:18:11 +0100
committerJason Ekstrand <[email protected]>2019-08-08 12:10:39 -0500
commitfd73ed1bd7e4d5a6af05d29908d6c4e2cca868b5 (patch)
treee1b02f6eb96ba121eb2ad116362f0197dfba79e9 /src/compiler/nir
parent8bd2e138f5db8ab6f82ec7597edb946d84edd3bf (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.h5
-rw-r--r--src/compiler/nir/nir_lower_io.c107
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.
*/