v3d: Use nir_remove_unused_io_vars to handle binner shader output DCE
authorEric Anholt <eric@anholt.net>
Wed, 26 Sep 2018 16:22:51 +0000 (09:22 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 30 Oct 2018 17:46:52 +0000 (10:46 -0700)
We were doing this late after nir_lower_io, but we can just reuse the core
code.  By doing it at this stage, we won't even set up the VS attributes
as inputs, reducing our VPM size.

src/broadcom/compiler/v3d_nir_lower_io.c
src/broadcom/compiler/vir.c
src/gallium/drivers/v3d/v3d_program.c

index 9cdcc02195c6229832f4ae1dd4f9ed3aa13df7de..10bc25811a85cba3a65b523dcdce2d09105c883b 100644 (file)
@@ -51,44 +51,6 @@ replace_intrinsic_with_vec(nir_builder *b, nir_intrinsic_instr *intr,
         nir_instr_remove(&intr->instr);
 }
 
-static void
-v3d_nir_lower_output(struct v3d_compile *c, nir_builder *b,
-                     nir_intrinsic_instr *intr)
-{
-        nir_variable *output_var = NULL;
-        nir_foreach_variable(var, &c->s->outputs) {
-                if (var->data.driver_location == nir_intrinsic_base(intr)) {
-                        output_var = var;
-                        break;
-                }
-        }
-        assert(output_var);
-
-        if (c->vs_key) {
-                int slot = output_var->data.location;
-                bool used = false;
-
-                switch (slot) {
-                case VARYING_SLOT_PSIZ:
-                case VARYING_SLOT_POS:
-                        used = true;
-                        break;
-
-                default:
-                        for (int i = 0; i < c->vs_key->num_fs_inputs; i++) {
-                                if (v3d_slot_get_slot(c->vs_key->fs_inputs[i]) == slot) {
-                                        used = true;
-                                        break;
-                                }
-                        }
-                        break;
-                }
-
-                if (!used)
-                        nir_instr_remove(&intr->instr);
-        }
-}
-
 static void
 v3d_nir_lower_uniform(struct v3d_compile *c, nir_builder *b,
                       nir_intrinsic_instr *intr)
@@ -135,10 +97,6 @@ v3d_nir_lower_io_instr(struct v3d_compile *c, nir_builder *b,
         case nir_intrinsic_load_input:
                 break;
 
-        case nir_intrinsic_store_output:
-                v3d_nir_lower_output(c, b, intr);
-                break;
-
         case nir_intrinsic_load_uniform:
                 v3d_nir_lower_uniform(c, b, intr);
                 break;
index faad65411515f43351a9c1b98ec777aa9e973d11..3f5a28d1be0b07ece86a1763a15dd192af0978f4 100644 (file)
@@ -719,13 +719,23 @@ uint64_t *v3d_compile_vs(const struct v3d_compiler *compiler,
 
         c->vs_key = key;
 
-        /* Split our input vars and dead code eliminate the unused
+        /* Split our I/O vars and dead code eliminate the unused
          * components.
          */
-        NIR_PASS_V(c->s, nir_lower_io_to_scalar_early, nir_var_shader_in);
+        NIR_PASS_V(c->s, nir_lower_io_to_scalar_early,
+                   nir_var_shader_in | nir_var_shader_out);
+        uint64_t used_outputs[4] = {0};
+        for (int i = 0; i < c->vs_key->num_fs_inputs; i++) {
+                int slot = v3d_slot_get_slot(c->vs_key->fs_inputs[i]);
+                int comp = v3d_slot_get_component(c->vs_key->fs_inputs[i]);
+                used_outputs[comp] |= 1ull << slot;
+        }
+        NIR_PASS_V(c->s, nir_remove_unused_io_vars,
+                   &c->s->outputs, used_outputs, NULL); /* demotes to globals */
+        NIR_PASS_V(c->s, nir_lower_global_vars_to_local);
         v3d_optimize_nir(c->s);
         NIR_PASS_V(c->s, nir_remove_dead_variables, nir_var_shader_in);
-        NIR_PASS_V(c->s, nir_lower_io, nir_var_shader_in,
+        NIR_PASS_V(c->s, nir_lower_io, nir_var_shader_in | nir_var_shader_out,
                    type_size_vec4,
                    (nir_lower_io_options)0);
 
index 17ded7571c43ff11f7cbc46de7ec847e24b779e1..1dceade950a36843ee3349dbcec740570d36a45f 100644 (file)
@@ -212,7 +212,7 @@ v3d_shader_state_create(struct pipe_context *pctx,
 
         nir_variable_mode lower_mode = nir_var_all & ~nir_var_uniform;
         if (s->info.stage == MESA_SHADER_VERTEX)
-                lower_mode &= ~nir_var_shader_in;
+                lower_mode &= ~(nir_var_shader_in | nir_var_shader_out);
         NIR_PASS_V(s, nir_lower_io, lower_mode,
                    type_size,
                    (nir_lower_io_options)0);