From 8ad6b10a015490d0d670b52a27b9a8bfbb096336 Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Thu, 29 Dec 2022 12:14:23 +0100 Subject: [PATCH] r600: Don't merge alu groups with variable length dot using t-slot Since the variable length dot must stay in its slot configuration do not try to merge the group with the previous group when an op may be moved to the t slot, because this may lead to breaking the multi-slot operation. Fixes: 357e5fac9953b26eedc8819ab528b981be6e1b69 r600/sfn: Use variable length DOT on Evergreen and Cayman Signed-off-by: Gert Wollny Part-of: --- src/gallium/drivers/r600/r600_asm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index bcc2435799f..82e411a7995 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -818,6 +818,8 @@ static int merge_inst_groups(struct r600_bytecode *bc, struct r600_bytecode_alu int have_mova = 0, have_rel = 0; int max_slots = bc->gfx_level == CAYMAN ? 4 : 5; + bool has_dot = false; + r = assign_alu_units(bc, alu_prev, prev); if (r) return r; @@ -828,6 +830,8 @@ static int merge_inst_groups(struct r600_bytecode *bc, struct r600_bytecode_alu return 0; if (is_alu_once_inst(prev[i])) return 0; + has_dot |= prev[i]->op == ALU_OP2_DOT || prev[i]->op == ALU_OP2_DOT_IEEE; + if (prev[i]->op == ALU_OP1_INTERP_LOAD_P0) interp_xz |= 3; @@ -841,6 +845,8 @@ static int merge_inst_groups(struct r600_bytecode *bc, struct r600_bytecode_alu return 0; if (is_alu_once_inst(slots[i])) return 0; + has_dot |= slots[i]->op == ALU_OP2_DOT || slots[i]->op == ALU_OP2_DOT_IEEE; + return 0; if (slots[i]->op == ALU_OP1_INTERP_LOAD_P0) interp_xz |= 3; if (slots[i]->op == ALU_OP2_INTERP_X) @@ -889,7 +895,7 @@ static int merge_inst_groups(struct r600_bytecode *bc, struct r600_bytecode_alu result[i] = prev[i]; continue; } else if (prev[i] && slots[i]) { - if (max_slots == 5 && result[4] == NULL && prev[4] == NULL && slots[4] == NULL) { + if (max_slots == 5 && !has_dot && result[4] == NULL && prev[4] == NULL && slots[4] == NULL) { /* Trans unit is still free try to use it. */ if (is_alu_any_unit_inst(bc, slots[i]) && !alu_uses_lds(slots[i])) { result[i] = prev[i];