From 79355fd9010888fefd1ce74b88aa1d000a302754 Mon Sep 17 00:00:00 2001 From: "Kristian H. Kristensen" Date: Tue, 28 Apr 2020 12:34:15 -0700 Subject: [PATCH] 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: --- src/freedreno/ir3/ir3_nir.c | 2 + src/freedreno/ir3/ir3_nir.h | 1 + src/freedreno/ir3/ir3_nir_lower_tess.c | 108 ++++++++++++++----------- 3 files changed, 65 insertions(+), 46 deletions(-) diff --git a/src/freedreno/ir3/ir3_nir.c b/src/freedreno/ir3/ir3_nir.c index 26035501e35..9fcc032a19b 100644 --- a/src/freedreno/ir3/ir3_nir.c +++ b/src/freedreno/ir3/ir3_nir.c @@ -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; diff --git a/src/freedreno/ir3/ir3_nir.h b/src/freedreno/ir3/ir3_nir.h index 6a0445c6cf7..22927b77afe 100644 --- a/src/freedreno/ir3/ir3_nir.h +++ b/src/freedreno/ir3/ir3_nir.h @@ -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); diff --git a/src/freedreno/ir3/ir3_nir_lower_tess.c b/src/freedreno/ir3/ir3_nir_lower_tess.c index c2bb664a8eb..2a43d9aa2e4 100644 --- a/src/freedreno/ir3/ir3_nir_lower_tess.c +++ b/src/freedreno/ir3/ir3_nir_lower_tess.c @@ -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; } -- 2.30.2