vc4: Prevent copy propagating out the MOVs from r4.
authorEric Anholt <eric@anholt.net>
Thu, 9 Oct 2014 14:36:45 +0000 (16:36 +0200)
committerEric Anholt <eric@anholt.net>
Thu, 9 Oct 2014 19:47:06 +0000 (21:47 +0200)
Copy propagating these might result in reading the r4 after some other
instruction has written r4.  Just prevent all copy propagation of this for
now.

Fixes bad rendering with upcoming indirect register access support, where
the copy propagation was consistently happening across another read.

src/gallium/drivers/vc4/vc4_opt_copy_propagation.c

index 0cffb284e44eff5fd7d55f46d67e45d90a388b70..9cf1352514c84e259a10ce378df7d2ac307fd3d6 100644 (file)
@@ -41,10 +41,14 @@ qir_opt_copy_propagation(struct vc4_compile *c)
         struct simple_node *node;
         bool debug = false;
         struct qreg *movs = calloc(c->num_temps, sizeof(struct qreg));
+        struct qinst **defs = calloc(c->num_temps, sizeof(struct qreg));
 
         foreach(node, &c->instructions) {
                 struct qinst *inst = (struct qinst *)node;
 
+                if (inst->dst.file == QFILE_TEMP)
+                        defs[inst->dst.index] = inst;
+
                 /* A single instruction can only read one uniform value.  (It
                  * could maybe read the same uniform value in two operands,
                  * but that doesn't seem important to do).
@@ -81,10 +85,16 @@ qir_opt_copy_propagation(struct vc4_compile *c)
                         }
                 }
 
-                if (inst->op == QOP_MOV && inst->dst.file == QFILE_TEMP)
+                if (inst->op == QOP_MOV &&
+                    inst->dst.file == QFILE_TEMP &&
+                    (inst->src[0].file != QFILE_TEMP ||
+                     (defs[inst->src[0].index]->op != QOP_TEX_RESULT &&
+                      defs[inst->dst.index]->op != QOP_TLB_COLOR_READ))) {
                         movs[inst->dst.index] = inst->src[0];
+                }
         }
 
         free(movs);
+        free(defs);
         return progress;
 }