r600/sfn: cayman fix int trans op2
authorDave Airlie <airlied@redhat.com>
Mon, 18 May 2020 06:28:10 +0000 (16:28 +1000)
committerMarge Bot <eric+marge@anholt.net>
Mon, 18 May 2020 21:56:29 +0000 (21:56 +0000)
Fix integer multiplies

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

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

index ba84e57ac1a1328e81ffcd782f4a49c2d23bc5e4..566e253bcb59e2216369d242efc6e9f4398b8013 100644 (file)
@@ -710,15 +710,35 @@ bool EmitAluInstruction::emit_alu_trans_op2(const nir_alu_instr& instr, EAluOp o
    const nir_alu_src& src1 = instr.src[1];
 
    AluInstruction *ir = nullptr;
-   for (int i = 0; i < 4 ; ++i) {
-      if (instr.dest.write_mask & (1 << i)){
-         ir = new AluInstruction(opcode, from_nir(instr.dest, i), from_nir(src0, i), from_nir(src1, i), last_write);
-         if (src0.negate) ir->set_flag(alu_src0_neg);
-         if (src0.abs) ir->set_flag(alu_src0_abs);
-         if (src1.negate) ir->set_flag(alu_src1_neg);
-         if (src1.abs) ir->set_flag(alu_src1_abs);
-         if (instr.dest.saturate) ir->set_flag(alu_dst_clamp);
-         emit_instruction(ir);
+
+   if (get_chip_class() == CAYMAN) {
+      int lasti = util_last_bit(instr.dest.write_mask);
+      for (int k = 0; k < lasti ; ++k) {
+         if (instr.dest.write_mask & (1 << k)) {
+
+            for (int i = 0; i < 4; i++) {
+               ir = new AluInstruction(opcode, from_nir(instr.dest, i), from_nir(src0, k), from_nir(src1, k), (i == k) ? write : empty);
+               if (src0.negate) ir->set_flag(alu_src0_neg);
+            if (src0.abs) ir->set_flag(alu_src0_abs);
+            if (src1.negate) ir->set_flag(alu_src1_neg);
+            if (src1.abs) ir->set_flag(alu_src1_abs);
+            if (instr.dest.saturate) ir->set_flag(alu_dst_clamp);
+            if (i == 3) ir->set_flag(alu_last_instr);
+            emit_instruction(ir);
+            }
+         }
+      }
+   } else {
+      for (int i = 0; i < 4 ; ++i) {
+         if (instr.dest.write_mask & (1 << i)){
+            ir = new AluInstruction(opcode, from_nir(instr.dest, i), from_nir(src0, i), from_nir(src1, i), last_write);
+            if (src0.negate) ir->set_flag(alu_src0_neg);
+            if (src0.abs) ir->set_flag(alu_src0_abs);
+            if (src1.negate) ir->set_flag(alu_src1_neg);
+            if (src1.abs) ir->set_flag(alu_src1_abs);
+            if (instr.dest.saturate) ir->set_flag(alu_dst_clamp);
+            emit_instruction(ir);
+         }
       }
    }
    return true;