vc4: Validate QPU uniform pointer updates.
authorEric Anholt <eric@anholt.net>
Tue, 3 May 2016 18:30:32 +0000 (11:30 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 13 Jul 2016 00:42:42 +0000 (17:42 -0700)
src/gallium/drivers/vc4/vc4_qpu_validate.c

index fade360e8a64ee1a5e100d35fcd12081cc02ddb3..10bb84dd0397c045f400ee9635b3a7a2bd8944c1 100644 (file)
@@ -308,4 +308,26 @@ vc4_qpu_validate(uint64_t *insts, uint32_t num_inst)
                 if (qpu_num_sf_accesses(inst) > 1)
                         fail_instr(inst, "Single instruction writes SFU twice");
         }
+
+        /* "The uniform base pointer can be written (from SIMD element 0) by
+         *  the processor to reset the stream, there must be at least two
+         *  nonuniform-accessing instructions following a pointer change
+         *  before uniforms can be accessed once more."
+         */
+        int last_unif_pointer_update = -3;
+        for (int i = 0; i < num_inst; i++) {
+                uint64_t inst = insts[i];
+                uint32_t waddr_add = QPU_GET_FIELD(inst, QPU_WADDR_ADD);
+                uint32_t waddr_mul = QPU_GET_FIELD(inst, QPU_WADDR_MUL);
+
+                if (reads_reg(inst, QPU_R_UNIF) &&
+                    i - last_unif_pointer_update <= 2) {
+                        fail_instr(inst,
+                                   "uniform read too soon after pointer update");
+                }
+
+                if (waddr_add == QPU_W_UNIFORMS_ADDRESS ||
+                    waddr_mul == QPU_W_UNIFORMS_ADDRESS)
+                        last_unif_pointer_update = i;
+        }
 }