diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index cb692846104..23c61e04ea2 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -4319,6 +4319,8 @@ bool nir_lower_array_deref_of_vec(nir_shader *shader, nir_variable_mode modes, bool nir_lower_indirect_derefs(nir_shader *shader, nir_variable_mode modes, uint32_t max_lower_array_len); +bool nir_lower_indirect_builtin_uniform_derefs(nir_shader *shader); + bool nir_lower_locals_to_regs(nir_shader *shader); void nir_lower_io_to_temporaries(nir_shader *shader, diff --git a/src/compiler/nir/nir_lower_indirect_derefs.c b/src/compiler/nir/nir_lower_indirect_derefs.c index a9784355625..a4325377538 100644 --- a/src/compiler/nir/nir_lower_indirect_derefs.c +++ b/src/compiler/nir/nir_lower_indirect_derefs.c @@ -114,7 +114,8 @@ emit_load_store_deref(nir_builder *b, nir_intrinsic_instr *orig_instr, static bool lower_indirect_derefs_block(nir_block *block, nir_builder *b, nir_variable_mode modes, - uint32_t max_lower_array_len) + uint32_t max_lower_array_len, + bool builtins_only) { bool progress = false; @@ -158,6 +159,10 @@ lower_indirect_derefs_block(nir_block *block, nir_builder *b, if (!(modes & base->var->data.mode) && !base->var->data.compact) continue; + /* built-in's will always start with "gl_" */ + if (builtins_only && strncmp(base->var->name, "gl_", 3)) + continue; + b->cursor = nir_instr_remove(&intrin->instr); nir_deref_path path; @@ -185,7 +190,7 @@ lower_indirect_derefs_block(nir_block *block, nir_builder *b, static bool lower_indirects_impl(nir_function_impl *impl, nir_variable_mode modes, - uint32_t max_lower_array_len) + uint32_t max_lower_array_len, bool builtins_only) { nir_builder builder; nir_builder_init(&builder, impl); @@ -193,7 +198,7 @@ lower_indirects_impl(nir_function_impl *impl, nir_variable_mode modes, nir_foreach_block_safe(block, impl) { progress |= lower_indirect_derefs_block(block, &builder, modes, - max_lower_array_len); + max_lower_array_len, builtins_only); } if (progress) @@ -218,7 +223,28 @@ nir_lower_indirect_derefs(nir_shader *shader, nir_variable_mode modes, nir_foreach_function(function, shader) { if (function->impl) { progress = lower_indirects_impl(function->impl, modes, - max_lower_array_len) || progress; + max_lower_array_len, false) || progress; + } + } + + return progress; +} + +/** Lowers indirect variable loads/stores to direct loads/stores. + * + * The pass works by replacing any indirect load or store with an if-ladder + * that does a binary search on the array index. It only changes uniform variable builtins, + * e.g., gl_LightSource + */ +bool +nir_lower_indirect_builtin_uniform_derefs(nir_shader *shader) +{ + bool progress = false; + + nir_foreach_function(function, shader) { + if (function->impl) { + progress = lower_indirects_impl(function->impl, nir_var_uniform, + UINT_MAX, true) || progress; } }