summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorVadim Girlin <[email protected]>2011-11-17 03:33:57 +0400
committerAlex Deucher <[email protected]>2011-11-17 09:10:37 -0500
commit0cddea37b2d79e4353347621cd2849cde682084a (patch)
tree7deb1af968fe72dbce69f8df31c8f1f87010d163 /src/gallium/drivers
parent4b1205d53b26dadba13578cf875feeeaa2018f74 (diff)
r600g: don't change the order of writes in merge_inst_group
Merge may produce incorrect order of operations for r600-eg: x: inst1 R0.x, ... ; //from current group ... t: inst0 R0.x, ... ; //from previous group, same destination Result of inst1 will be lost. So compare destinations and don't allow this. Signed-off-by: Vadim Girlin <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/r600/r600_asm.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index 6b1ad65b60f..1ab16f28821 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -1010,6 +1010,11 @@ static int merge_inst_groups(struct r600_bytecode *bc, struct r600_bytecode_alu
result[i] = prev[i];
result[4] = slots[i];
} else if (is_alu_any_unit_inst(bc, prev[i])) {
+ if (slots[i]->dst.sel == prev[i]->dst.sel &&
+ (slots[i]->dst.write == 1 || slots[i]->is_op3) &&
+ (prev[i]->dst.write == 1 || prev[i]->is_op3))
+ return 0;
+
result[i] = slots[i];
result[4] = prev[i];
} else
@@ -1018,8 +1023,16 @@ static int merge_inst_groups(struct r600_bytecode *bc, struct r600_bytecode_alu
return 0;
} else if(!slots[i]) {
continue;
- } else
+ } else {
+ if (max_slots == 5 && slots[i] && prev[4] &&
+ slots[i]->dst.sel == prev[4]->dst.sel &&
+ slots[i]->dst.chan == prev[4]->dst.chan &&
+ (slots[i]->dst.write == 1 || slots[i]->is_op3) &&
+ (prev[4]->dst.write == 1 || prev[4]->is_op3))
+ return 0;
+
result[i] = slots[i];
+ }
alu = slots[i];
num_once_inst += is_alu_once_inst(bc, alu);