r600/sfn: Check possibility of channel switching also for trans-slot
authorGert Wollny <gert.wollny@collabora.com>
Fri, 16 Dec 2022 10:46:33 +0000 (11:46 +0100)
committerMarge Bot <emma+marge@anholt.net>
Fri, 16 Dec 2022 13:39:55 +0000 (13:39 +0000)
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7878

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20355>

src/gallium/drivers/r600/sfn/sfn_instr_alugroup.cpp

index b810b85..0be1f5b 100644 (file)
@@ -123,12 +123,29 @@ AluGroup::add_trans_instructions(AluInstr *instr)
    if (!instr->has_alu_flag(alu_is_trans) && !m_slots[instr->dest_chan()]) {
       if (instr->dest() && instr->dest()->pin() == pin_free) {
          int used_slot = 3;
-         while (!m_slots[used_slot] && used_slot >= 0)
+         auto dest = instr->dest();
+         int free_mask = 0xf;
+
+         for (auto p : dest->parents()) {
+            auto alu = p->as_alu();
+            if (alu)
+               free_mask &= alu->allowed_dest_chan_mask();
+         }
+
+         for (auto u : dest->uses()) {
+            free_mask &= u->allowed_src_chan_mask();
+            if (!free_mask)
+               return false;
+         }
+
+         while ((!m_slots[used_slot] && used_slot >= 0) || !(free_mask & (1 << used_slot)))
             --used_slot;
 
          // if we schedule a non-trans instr into the trans slot,
          // there should always be some slot that is already used
-         assert(used_slot >= 0);
+         if (used_slot < 0)
+            return false;
+
          instr->dest()->set_chan(used_slot);
       }
    }