panfrost: add atomic ops infrastructure
[mesa.git] / src / panfrost / midgard / midgard_emit.c
index a0fbe20c7740dc08d5ceaef2f50b146f03b5dcb4..213b7024e814a13e8dccf47502b423f785d0f55c 100644 (file)
@@ -499,6 +499,15 @@ load_store_from_instr(midgard_instruction *ins)
                 ldst.reg = SSA_REG_FROM_FIXED(ins->dest);
         }
 
+        /* Atomic opcode swizzles have a special meaning:
+         *   - The first two bits say which component of the implicit register should be used
+         *   - The next two bits say if the implicit register is r26 or r27 */
+        if (OP_IS_ATOMIC(ins->op)) {
+                ldst.swizzle = 0;
+                ldst.swizzle |= ins->swizzle[3][0] & 3;
+                ldst.swizzle |= (SSA_REG_FROM_FIXED(ins->src[3]) & 1 ? 1 : 0) << 2;
+        }
+
         if (ins->src[1] != ~0) {
                 unsigned src = SSA_REG_FROM_FIXED(ins->src[1]);
                 unsigned sz = nir_alu_type_get_type_size(ins->src_types[1]);
@@ -855,7 +864,9 @@ emit_binary_bundle(compiler_context *ctx,
                 for (unsigned i = 0; i < bundle->instruction_count; ++i) {
                         mir_pack_ldst_mask(bundle->instructions[i]);
 
-                        mir_pack_swizzle_ldst(bundle->instructions[i]);
+                        /* Atomic ops don't use this swizzle the same way as other ops */
+                        if (!OP_IS_ATOMIC(bundle->instructions[i]->op))
+                                mir_pack_swizzle_ldst(bundle->instructions[i]);
 
                         /* Apply a constant offset */
                         unsigned offset = bundle->instructions[i]->constants.u32[0];