From: Vadim Girlin Date: Tue, 16 Jul 2013 08:28:52 +0000 (+0400) Subject: r600g/sb: fix handling of new multislot instructions on cayman X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ba7fa4c4c93e67fec798d837005a3041adda3d5b;p=mesa.git r600g/sb: fix handling of new multislot instructions on cayman Ex-scalar instructions that became multislot on cayman do replicate result to all channels - handle them similar to DOT4. Signed-off-by: Vadim Girlin --- diff --git a/src/gallium/drivers/r600/sb/sb_ir.cpp b/src/gallium/drivers/r600/sb/sb_ir.cpp index 382fceed08c..5226893de75 100644 --- a/src/gallium/drivers/r600/sb/sb_ir.cpp +++ b/src/gallium/drivers/r600/sb/sb_ir.cpp @@ -51,7 +51,7 @@ bool alu_packed_node::accept(vpass& p, bool enter) { return p.visit(*this, enter); } -void alu_packed_node::init_args() { +void alu_packed_node::init_args(bool repl) { alu_node *p = static_cast(first); assert(p->is_valid()); while (p) { @@ -60,8 +60,6 @@ void alu_packed_node::init_args() { p = static_cast(p->next); } - // if it's packed then it's always multislot, no need to check slot flags - bool repl = (op_ptr()->flags & AF_REPL); value *replicated_value = NULL; for (vvec::iterator I = dst.begin(), E = dst.end(); I != E; ++I) { diff --git a/src/gallium/drivers/r600/sb/sb_ir.h b/src/gallium/drivers/r600/sb/sb_ir.h index d55f4de67b8..c838f62b567 100644 --- a/src/gallium/drivers/r600/sb/sb_ir.h +++ b/src/gallium/drivers/r600/sb/sb_ir.h @@ -1014,7 +1014,7 @@ public: return static_cast(first)->bc.op_ptr; } unsigned op() { return static_cast(first)->bc.op; } - void init_args(); + void init_args(bool repl); virtual bool is_valid() { return subtype == NST_ALU_PACKED_INST; } virtual bool accept(vpass &p, bool enter); diff --git a/src/gallium/drivers/r600/sb/sb_ssa_builder.cpp b/src/gallium/drivers/r600/sb/sb_ssa_builder.cpp index 87eafaee247..3ad628bb68c 100644 --- a/src/gallium/drivers/r600/sb/sb_ssa_builder.cpp +++ b/src/gallium/drivers/r600/sb/sb_ssa_builder.cpp @@ -218,7 +218,10 @@ bool ssa_rename::visit(alu_packed_node& n, bool enter) { I->accept(*this, false); } - n.init_args(); + bool repl = (n.op_ptr()->flags & AF_REPL) || + (ctx.is_cayman() && (n.first->alu_op_slot_flags() & AF_S)); + + n.init_args(repl); } return false; }