freedreno/ir3: legalize vs unused sam dst components
authorRob Clark <robclark@freedesktop.org>
Tue, 6 Jan 2015 21:44:26 +0000 (16:44 -0500)
committerRob Clark <robclark@freedesktop.org>
Thu, 8 Jan 2015 00:37:28 +0000 (19:37 -0500)
We probably could be more clever elsewhere and mask out components that
are not used.  But either way, legalize should realize that there is
also a write-after-write hazard with texture sample instructions.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/ir3/ir3_compiler.c
src/gallium/drivers/freedreno/ir3/ir3_legalize.c

index 5cf8656a9e7e106720de409ed09d64096ddc5d99..fe145d4ed1c38a43612426a053a1bcef7d03c4e9 100644 (file)
@@ -1374,12 +1374,13 @@ trans_samp(const struct instr_translater *t,
 
        collect = ir3_instr_create(ctx->block, -1, OPC_META_FI);
        ir3_reg_create(collect, 0, 0);
-       for (i = 0; i < 4; i++)
+       for (i = 0; i < 4; i++) {
                if (tinf.src_wrmask & (1 << i))
                        ssa_src(ctx, ir3_reg_create(collect, 0, IR3_REG_SSA),
                                        coord, src_swiz(coord, i));
                else if (tinf.src_wrmask & ~((1 << i) - 1))
                        ir3_reg_create(collect, 0, 0);
+       }
 
        /* Attach derivatives onto the end of the fan-in. Derivatives start after
         * the 4th argument, so make sure that fi is padded up to 4 first.
index 6194deda846cae3019a7647a92f75d88c844b31e..2ef11f183d7a38c79c5b4a9a21dead5436df6ad5 100644 (file)
@@ -80,7 +80,13 @@ static void legalize(struct ir3_legalize_ctx *ctx)
                        ctx->max_bary = MAX2(ctx->max_bary, inloc->iim_val);
                }
 
-               for (i = 1; i < n->regs_count; i++) {
+               /* NOTE: consider dst register too.. it could happen that
+                * texture sample instruction (for example) writes some
+                * components which are unused.  A subsequent instruction
+                * that writes the same register can race w/ the sam instr
+                * resulting in undefined results:
+                */
+               for (i = 0; i < n->regs_count; i++) {
                        reg = n->regs[i];
 
                        if (reg_gpr(reg)) {