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 2603550..9fcc032 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 6a0445c..22927b7 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 c2bb664..2a43d9a 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;
                }