From db0752a809075a029f16a273809e16a3686bdc8f Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Sat, 28 Jan 2023 17:53:03 +0100 Subject: [PATCH] r600/sfn: don't allow more than one AR per instruction Signed-off-by: Gert Wollny Part-of: --- src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp | 46 ++++++++++++++------------ 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp b/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp index 022384d..a566874 100644 --- a/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp @@ -31,6 +31,7 @@ #include "sfn_instr_alugroup.h" #include "sfn_instr_tex.h" #include "sfn_shader.h" +#include "sfn_virtualvalues.h" #include #include @@ -427,32 +428,33 @@ bool AluInstr::can_replace_source(PRegister old_src, PVirtualValue new_src) if (old_src->pin() == pin_array) return false; - if (new_src->get_addr()) { - for (auto& s : m_src) { - auto addr = s->get_addr(); - /* can't have two different indirect addresses in the same instr */ - if (addr && !addr->equal_to(*new_src->get_addr())) + auto [addr, dummy, index] = indirect_addr(); + auto addr_reg = addr ? addr->as_register() : nullptr; + auto index_reg = index ? index->as_register() : nullptr; + + if (auto u = new_src->as_uniform()) { + if (u && u->buf_addr()) { + + /* Don't mix indirect buffer and indirect registers, because the + * scheduler can't handle it yet. */ + if (addr_reg) + return false; + + /* Don't allow two different index registers, can't deal with that yet */ + if (index_reg && !index_reg->equal_to(*u->buf_addr())) return false; } } - if (m_dest) { - /* We don't allow src and dst with rel and different indirect register - * addresses */ - if (m_dest->pin() == pin_array) { - auto dav = static_cast(m_dest)->addr(); - if (new_src->pin() == pin_array) { - auto sav = static_cast(new_src)->addr(); - if (dav && sav && dav->as_register() && !dav->equal_to(*sav)) - return false; - } else if (dav && dav->as_register()) { - /* don't support resolving a buffer address and an register address - * at the same time. It could be done, but it's currently a mess - * to schedule */ - auto u = new_src->as_uniform(); - if (u && u->buf_addr()) - return false; - } + if (auto new_addr = new_src->get_addr()) { + auto new_addr_reg = new_addr->as_register(); + bool new_addr_lowered = new_addr_reg && + new_addr_reg->has_flag(Register::addr_or_idx); + + if (addr_reg) { + if (!addr_reg->equal_to(*new_addr) || new_addr_lowered || + addr_reg->has_flag(Register::addr_or_idx)) + return false; } } return true; -- 2.7.4