freedreno/ir3: Add ir3_nir_lower_to_explicit_input() pass
authorKristian H. Kristensen <hoegsberg@google.com>
Tue, 28 Apr 2020 19:34:15 +0000 (12:34 -0700)
committerMarge Bot <eric+marge@anholt.net>
Fri, 1 May 2020 16:26:31 +0000 (16:26 +0000)
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>

src/freedreno/ir3/ir3_nir.c
src/freedreno/ir3/ir3_nir.h
src/freedreno/ir3/ir3_nir_lower_tess.c

index 26035501e35d3d2e6c528bd4cf56b867c400afa8..9fcc032a19b833dddbf96c30eaa2ebee4589122a 100644 (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;
index 6a0445c6cf71aced5a101592c53206e7b7dc9d23..22927b77afec309d40fbcfb04b13c7567247b038 100644 (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);
index c2bb664a8ebf168fed373252462f83dfafef3323..2a43d9aa2e45db263f0c402021d3c1c700a39c57 100644 (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;
                }