From: Michael Tretter <m.tret...@pengutronix.de>

The hardware does not allow two different uniform registers to be used
as sources in the same ALU instruction. Emit mov instructions to
temporary registers for all but one uniform register in this case.

Signed-off-by: Michael Tretter <m.tret...@pengutronix.de>
Signed-off-by: Philipp Zabel <p.za...@pengutronix.de>
---
 src/gallium/drivers/etnaviv/etnaviv_nir.c | 36 +++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/src/gallium/drivers/etnaviv/etnaviv_nir.c 
b/src/gallium/drivers/etnaviv/etnaviv_nir.c
index 988b4bd62b6e..36ec21fbd623 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_nir.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_nir.c
@@ -942,6 +942,41 @@ etna_add_mov_for_uniform_output(nir_shader *shader)
    }
 }
 
+/* Accessing two different uniforms from one alu instruction is illegal.
+ * Insert a mov for all but one uniform before alu instructions.
+ */
+static void
+etna_fix_alu_uniform_src(nir_shader *shader)
+{
+   nir_foreach_function(function, shader) {
+      nir_foreach_block(block, function->impl) {
+         nir_foreach_instr_safe(instr, block) {
+            if (instr->type != nir_instr_type_alu)
+               continue;
+            nir_alu_instr *alu = nir_instr_as_alu(instr);
+
+            unsigned i;
+            bool needs_fixup = false;
+
+            for (i = 0; i < nir_op_infos[alu->op].num_inputs; i++) {
+               nir_src *src = &alu->src[i].src;
+               if (!src->is_ssa || !nir_src_is_dynamically_uniform(*src))
+                  continue;
+
+               /* FIXME The fixup unnecessarily fixes instructions where the
+                * same uniform is used twice, which is allowed.
+                */
+               if (needs_fixup) {
+                  insert_mov(&alu->instr, src, shader);
+               } else
+                  needs_fixup = true;
+            }
+         }
+      }
+      nir_metadata_preserve(function->impl, nir_metadata_block_index);
+   }
+}
+
 /* Remove input_load and output_store intrinsics after global register
  * allocation. After the SSA destinations are replaced, these contain no useful
  * information anymore.
@@ -1024,6 +1059,7 @@ etna_optimize_nir(struct etna_shader *shader,
 
    NIR_PASS_V(s, nir_convert_from_ssa, true);
    NIR_PASS_V(s, etna_fixup_tex);
+   NIR_PASS_V(s, etna_fix_alu_uniform_src);
    NIR_PASS_V(s, etna_add_mov_for_uniform_output);
    NIR_PASS_V(s, etna_assign_registers);
    NIR_PASS_V(s, etna_remove_io_intrinsics);
-- 
2.17.1

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to