From 070f56237f727e821c9a8c554f03217f1a3ae73e Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Fri, 3 May 2024 23:22:54 +0200 Subject: [PATCH] r600/sfn: Fix update readports method - If a readport reservation is not successful then we have to reset the readport reservation. - Since the scheduler can add instructions in any order, we have to update the readports in the same order the slots were filled when re-evaluating. Signed-off-by: Gert Wollny Part-of: --- .../drivers/r600/sfn/sfn_instr_alugroup.cpp | 83 ++++++++++++++----- .../drivers/r600/sfn/sfn_instr_alugroup.h | 5 ++ 2 files changed, 66 insertions(+), 22 deletions(-) diff --git a/src/gallium/drivers/r600/sfn/sfn_instr_alugroup.cpp b/src/gallium/drivers/r600/sfn/sfn_instr_alugroup.cpp index c063f82caff..811abe4fe24 100644 --- a/src/gallium/drivers/r600/sfn/sfn_instr_alugroup.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_instr_alugroup.cpp @@ -7,9 +7,8 @@ #include "sfn_instr_alugroup.h" #include "sfn_debug.h" -#include "sfn_instr_export.h" -#include "sfn_instr_mem.h" -#include "sfn_instr_tex.h" + +#include "util/macros.h" #include @@ -125,6 +124,7 @@ AluGroup::add_trans_instructions(AluInstr *instr) * make sure the corresponding vector channel is used */ assert(instr->has_alu_flag(alu_is_trans) || m_slots[instr->dest_chan()]); m_has_kill_op |= instr->is_kill(); + m_slot_assignemnt_order[m_next_slot_assignemnt++] = 4; return true; } } @@ -156,12 +156,14 @@ AluGroup::add_vec_instructions(AluInstr *instr) if (instr->bank_swizzle() != alu_vec_unknown) { if (try_readport(instr, instr->bank_swizzle())) { m_has_kill_op |= instr->is_kill(); + m_slot_assignemnt_order[m_next_slot_assignemnt++] = preferred_chan; return true; } } else { for (AluBankSwizzle i = alu_vec_012; i != alu_vec_unknown; ++i) { if (try_readport(instr, i)) { m_has_kill_op |= instr->is_kill(); + m_slot_assignemnt_order[m_next_slot_assignemnt++] = preferred_chan; return true; } } @@ -194,12 +196,14 @@ AluGroup::add_vec_instructions(AluInstr *instr) if (instr->bank_swizzle() != alu_vec_unknown) { if (try_readport(instr, instr->bank_swizzle())) { m_has_kill_op |= instr->is_kill(); + m_slot_assignemnt_order[m_next_slot_assignemnt++] = free_chan; return true; } } else { for (AluBankSwizzle i = alu_vec_012; i != alu_vec_unknown; ++i) { if (try_readport(instr, i)) { m_has_kill_op |= instr->is_kill(); + m_slot_assignemnt_order[m_next_slot_assignemnt++] = free_chan; return true; } } @@ -210,39 +214,74 @@ AluGroup::add_vec_instructions(AluInstr *instr) return false; } -void AluGroup::update_readport_reserver() +void +AluGroup::update_readport_reserver() { AluReadportReservation readports_evaluator; - for (int i = 0; i < 4; ++i) { - if (!m_slots[i]) - continue; + for (int k = 0; k < m_next_slot_assignemnt; ++k) { + int i = m_slot_assignemnt_order[k]; + if (i < 4) { + if (!update_readport_reserver_vec(i, readports_evaluator)) { + sfn_log << SfnLog::err << *this << "\n"; + UNREACHABLE("Redport reserver update failed when it shouldn't"); + } + } else { + if (!update_readport_reserver_trans(readports_evaluator)) { + sfn_log << SfnLog::err << *this << "\n"; + UNREACHABLE("Redport reserver update failed when it shouldn't"); + } + } + } + + m_readports_reserver = readports_evaluator; +} + +bool +AluGroup::update_readport_reserver_vec(int i, AluReadportReservation& readports_evaluator) +{ + assert(m_slots[i]); + + if (m_slots[i]->bank_swizzle() != alu_vec_unknown) { AluReadportReservation re = readports_evaluator; + if (re.schedule_vec_instruction(*m_slots[i], m_slots[i]->bank_swizzle())) { + readports_evaluator = re; + } else { + return false; + } + } else { AluBankSwizzle bs = alu_vec_012; while (bs != alu_vec_unknown) { + AluReadportReservation re = readports_evaluator; if (re.schedule_vec_instruction(*m_slots[i], bs)) { readports_evaluator = re; break; } ++bs; } - if (bs == alu_vec_unknown) - UNREACHABLE("Bank swizzle should have been checked before"); - } - - if (s_max_slots == 5 && m_slots[4]) { - AluReadportReservation re = readports_evaluator; - AluBankSwizzle bs = sq_alu_scl_201; - while (bs != sq_alu_scl_unknown) { - if (re.schedule_vec_instruction(*m_slots[4], bs)) { - readports_evaluator = re; - break; - } - ++bs; + if (bs == alu_vec_unknown) { + return false; } - if (bs == sq_alu_scl_unknown) - UNREACHABLE("Bank swizzle should have been checked before"); } + return true; +} + +bool +AluGroup::update_readport_reserver_trans(AluReadportReservation& readports_evaluator) +{ + AluBankSwizzle bs = sq_alu_scl_201; + while (bs != sq_alu_scl_unknown) { + AluReadportReservation re = readports_evaluator; + if (re.schedule_trans_instruction(*m_slots[4], bs)) { + readports_evaluator = re; + break; + } + ++bs; + } + if (bs == sq_alu_scl_unknown) { + return false; + } + return true; } bool diff --git a/src/gallium/drivers/r600/sfn/sfn_instr_alugroup.h b/src/gallium/drivers/r600/sfn/sfn_instr_alugroup.h index 88326f337b4..4d9e81c37b7 100644 --- a/src/gallium/drivers/r600/sfn/sfn_instr_alugroup.h +++ b/src/gallium/drivers/r600/sfn/sfn_instr_alugroup.h @@ -86,6 +86,9 @@ public: AluGroup *as_alu_group() override { return this;} private: + bool update_readport_reserver_vec(int i, AluReadportReservation& readports_evaluator); + bool update_readport_reserver_trans(AluReadportReservation& readports_evaluator); + void forward_set_blockid(int id, int index) override; bool do_ready() const override; void do_print(std::ostream& os) const override; @@ -94,6 +97,8 @@ private: bool try_readport(AluInstr *instr, AluBankSwizzle cycle); Slots m_slots; + uint8_t m_next_slot_assignemnt{0}; + std::array m_slot_assignemnt_order{-1, -1, -1, -1, -1}; AluReadportReservation m_readports_reserver;