freedreno/ir3: Add ir3_nir_lower_to_explicit_input() pass

This pass lowers per-vertex input intrinsics to load_shared_ir3. This
was open coded in the TCS and GS lowering passes before - this way we
can share it. Furthermore, we'll need to run the rest of the GS
lowering earlier (before lowering IO) so we need to split off this
part that operates on the IO intrinsics first.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4562>
This commit is contained in:
Kristian H. Kristensen
2020-04-28 12:34:15 -07:00
committed by Marge Bot
parent b7bfccf085
commit 79355fd901
3 changed files with 65 additions and 46 deletions
+2
View File
@@ -226,6 +226,7 @@ ir3_optimize_nir(struct ir3_shader *shader, nir_shader *s,
break;
case MESA_SHADER_TESS_CTRL:
NIR_PASS_V(s, ir3_nir_lower_tess_ctrl, shader, key->tessellation);
NIR_PASS_V(s, ir3_nir_lower_to_explicit_input);
break;
case MESA_SHADER_TESS_EVAL:
NIR_PASS_V(s, ir3_nir_lower_tess_eval, key->tessellation);
@@ -234,6 +235,7 @@ ir3_optimize_nir(struct ir3_shader *shader, nir_shader *s,
break;
case MESA_SHADER_GEOMETRY:
NIR_PASS_V(s, ir3_nir_lower_gs, shader);
NIR_PASS_V(s, ir3_nir_lower_to_explicit_input);
break;
default:
break;
+1
View File
@@ -46,6 +46,7 @@ bool ir3_nir_lower_tex_prefetch(nir_shader *shader);
void ir3_nir_lower_to_explicit_output(nir_shader *shader,
struct ir3_shader *s, unsigned topology);
void ir3_nir_lower_to_explicit_input(nir_shader *shader);
void ir3_nir_lower_tess_ctrl(nir_shader *shader, struct ir3_shader *s, unsigned topology);
void ir3_nir_lower_tess_eval(nir_shader *shader, unsigned topology);
void ir3_nir_lower_gs(nir_shader *shader, struct ir3_shader *s);
+62 -46
View File
@@ -250,6 +250,68 @@ ir3_nir_lower_to_explicit_output(nir_shader *shader, struct ir3_shader *s, unsig
s->output_size = state.map.stride;
}
static void
lower_block_to_explicit_input(nir_block *block, nir_builder *b, struct state *state)
{
nir_foreach_instr_safe (instr, block) {
if (instr->type != nir_instr_type_intrinsic)
continue;
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
switch (intr->intrinsic) {
case nir_intrinsic_load_per_vertex_input: {
// src[] = { vertex, offset }.
b->cursor = nir_before_instr(&intr->instr);
nir_ssa_def *offset = build_local_offset(b, state,
intr->src[0].ssa, // this is typically gl_InvocationID
nir_intrinsic_base(intr),
intr->src[1].ssa);
replace_intrinsic(b, intr, nir_intrinsic_load_shared_ir3, offset, NULL, NULL);
break;
}
case nir_intrinsic_load_invocation_id: {
b->cursor = nir_before_instr(&intr->instr);
nir_ssa_def *iid = build_invocation_id(b, state);
nir_ssa_def_rewrite_uses(&intr->dest.ssa, nir_src_for_ssa(iid));
nir_instr_remove(&intr->instr);
break;
}
default:
break;
}
}
}
void
ir3_nir_lower_to_explicit_input(nir_shader *shader)
{
struct state state = { };
nir_function_impl *impl = nir_shader_get_entrypoint(shader);
assert(impl);
nir_builder b;
nir_builder_init(&b, impl);
b.cursor = nir_before_cf_list(&impl->body);
if (shader->info.stage == MESA_SHADER_GEOMETRY)
state.header = nir_load_gs_header_ir3(&b);
else
state.header = nir_load_tcs_header_ir3(&b);
nir_foreach_block_safe (block, impl)
lower_block_to_explicit_input(block, &b, &state);
}
static nir_ssa_def *
build_per_vertex_offset(nir_builder *b, struct state *state,
nir_ssa_def *vertex, nir_ssa_def *offset, nir_variable *var)
@@ -339,15 +401,6 @@ lower_tess_ctrl_block(nir_block *block, nir_builder *b, struct state *state)
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
switch (intr->intrinsic) {
case nir_intrinsic_load_invocation_id:
b->cursor = nir_before_instr(&intr->instr);
nir_ssa_def *invocation_id = build_invocation_id(b, state);
nir_ssa_def_rewrite_uses(&intr->dest.ssa,
nir_src_for_ssa(invocation_id));
nir_instr_remove(&intr->instr);
break;
case nir_intrinsic_control_barrier:
case nir_intrinsic_memory_barrier_tcs_patch:
/* Hull shaders dispatch 32 wide so an entire patch will always
@@ -393,20 +446,6 @@ lower_tess_ctrl_block(nir_block *block, nir_builder *b, struct state *state)
break;
}
case nir_intrinsic_load_per_vertex_input: {
// src[] = { vertex, offset }.
b->cursor = nir_before_instr(&intr->instr);
nir_ssa_def *offset = build_local_offset(b, state,
intr->src[0].ssa, // this is typically gl_InvocationID
nir_intrinsic_base(intr),
intr->src[1].ssa);
replace_intrinsic(b, intr, nir_intrinsic_load_shared_ir3, offset, NULL, NULL);
break;
}
case nir_intrinsic_load_tess_level_inner:
case nir_intrinsic_load_tess_level_outer: {
b->cursor = nir_before_instr(&intr->instr);
@@ -804,29 +843,6 @@ lower_gs_block(nir_block *block, nir_builder *b, struct state *state)
break;
}
case nir_intrinsic_load_per_vertex_input: {
// src[] = { vertex, offset }.
b->cursor = nir_before_instr(&intr->instr);
nir_ssa_def *offset = build_local_offset(b, state,
intr->src[0].ssa, // this is typically gl_InvocationID
nir_intrinsic_base(intr),
intr->src[1].ssa);
replace_intrinsic(b, intr, nir_intrinsic_load_shared_ir3, offset, NULL, NULL);
break;
}
case nir_intrinsic_load_invocation_id: {
b->cursor = nir_before_instr(&intr->instr);
nir_ssa_def *iid = build_invocation_id(b, state);
nir_ssa_def_rewrite_uses(&intr->dest.ssa, nir_src_for_ssa(iid));
nir_instr_remove(&intr->instr);
break;
}
default:
break;
}