summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2014-10-09 16:36:45 +0200
committerEric Anholt <[email protected]>2014-10-09 21:47:06 +0200
commit93cac2637ba5a7cd5c79a0e74b87298fae807135 (patch)
tree40b4a73b8ee4b7437cd237d18ffdced7173a88a3 /src
parentc4b0dd53568fa276079f6b6bf7ba4b857ddd65a5 (diff)
vc4: Prevent copy propagating out the MOVs from r4.
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.
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/vc4/vc4_opt_copy_propagation.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/gallium/drivers/vc4/vc4_opt_copy_propagation.c b/src/gallium/drivers/vc4/vc4_opt_copy_propagation.c
index 0cffb284e44..9cf1352514c 100644
--- a/src/gallium/drivers/vc4/vc4_opt_copy_propagation.c
+++ b/src/gallium/drivers/vc4/vc4_opt_copy_propagation.c
@@ -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;
}