nir: expose reusable linking helpers for cloning uniform loads

for the new varying optimizer

Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25394>
This commit is contained in:
Marek Olšák 2023-04-05 06:40:59 -04:00 committed by Marge Bot
parent b1bbe4e190
commit b47b8d16d9
2 changed files with 23 additions and 12 deletions

View file

@ -4965,6 +4965,11 @@ void nir_compact_varyings(nir_shader *producer, nir_shader *consumer,
void nir_link_xfb_varyings(nir_shader *producer, nir_shader *consumer);
bool nir_link_opt_varyings(nir_shader *producer, nir_shader *consumer);
void nir_link_varying_precision(nir_shader *producer, nir_shader *consumer);
nir_variable *nir_clone_uniform_variable(nir_shader *nir,
nir_variable *uniform);
nir_deref_instr *nir_clone_deref_instr(struct nir_builder *b,
nir_variable *var,
nir_deref_instr *deref);
bool nir_slot_is_sysval_output(gl_varying_slot slot,
gl_shader_stage next_shader);

View file

@ -1166,14 +1166,19 @@ is_direct_uniform_load(nir_def *def, nir_scalar *s)
return !nir_deref_instr_has_indirect(deref);
}
static nir_variable *
get_uniform_var_in_consumer(nir_shader *consumer,
nir_variable *var_in_producer)
/**
* Add a uniform variable from one shader to a different shader.
*
* \param nir The shader where to add the uniform
* \param uniform The uniform that's declared in another shader.
*/
nir_variable *
nir_clone_uniform_variable(nir_shader *nir, nir_variable *uniform)
{
/* Find if uniform already exists in consumer. */
nir_variable *new_var = NULL;
nir_foreach_uniform_variable(v, consumer) {
if (!strcmp(var_in_producer->name, v->name)) {
nir_foreach_uniform_variable(v, nir) {
if (!strcmp(uniform->name, v->name)) {
new_var = v;
break;
}
@ -1181,21 +1186,22 @@ get_uniform_var_in_consumer(nir_shader *consumer,
/* Create a variable if not exist. */
if (!new_var) {
new_var = nir_variable_clone(var_in_producer, consumer);
nir_shader_add_variable(consumer, new_var);
new_var = nir_variable_clone(uniform, nir);
nir_shader_add_variable(nir, new_var);
}
return new_var;
}
static nir_deref_instr *
clone_deref_instr(nir_builder *b, nir_variable *var, nir_deref_instr *deref)
nir_deref_instr *
nir_clone_deref_instr(nir_builder *b, nir_variable *var,
nir_deref_instr *deref)
{
if (deref->deref_type == nir_deref_type_var)
return nir_build_deref_var(b, var);
nir_deref_instr *parent_deref = nir_deref_instr_parent(deref);
nir_deref_instr *parent = clone_deref_instr(b, var, parent_deref);
nir_deref_instr *parent = nir_clone_deref_instr(b, var, parent_deref);
/* Build array and struct deref instruction.
* "deref" instr is sure to be direct (see is_direct_uniform_load()).
@ -1235,7 +1241,7 @@ replace_varying_input_by_uniform_load(nir_shader *shader,
nir_intrinsic_instr *load = nir_instr_as_intrinsic(scalar->def->parent_instr);
nir_deref_instr *deref = nir_src_as_deref(load->src[0]);
nir_variable *uni_var = nir_deref_instr_get_variable(deref);
uni_var = get_uniform_var_in_consumer(shader, uni_var);
uni_var = nir_clone_uniform_variable(shader, uni_var);
bool progress = false;
nir_foreach_block(block, impl) {
@ -1259,7 +1265,7 @@ replace_varying_input_by_uniform_load(nir_shader *shader,
b.cursor = nir_before_instr(instr);
/* Clone instructions start from deref load to variable deref. */
nir_deref_instr *uni_deref = clone_deref_instr(&b, uni_var, deref);
nir_deref_instr *uni_deref = nir_clone_deref_instr(&b, uni_var, deref);
nir_def *uni_def = nir_load_deref(&b, uni_deref);
/* Add a vector to scalar move if uniform is a vector. */