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; }