v3d: Fix atomic cmpxchg in shaders on hardware.
authorEric Anholt <eric@anholt.net>
Wed, 17 Apr 2019 21:44:44 +0000 (14:44 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 18 Apr 2019 20:24:55 +0000 (13:24 -0700)
In what might be my first case of finding a divergence between hardware
and simpenrose for v3d 4.x, it seems that despite what the spec claims,
you actually need specific values in the TYPE field for atomic ops.

Fixes dEQP-GLES31.functional.*.compswap.*

src/broadcom/compiler/nir_to_vir.c

index 9a4705a3de6a549d239b9828d827013a5af863b6..30fd4002ef9bed7ac9fe16d10202bbda11b2423e 100644 (file)
@@ -266,14 +266,24 @@ ntq_emit_tmu_general(struct v3d_compile *c, nir_intrinsic_instr *instr,
                                                                 1 : 0]));
         }
 
+        /* The spec says that for atomics, the TYPE field is ignored, but that
+         * doesn't seem to be the case for CMPXCHG.  Just use the number of
+         * tmud writes we did to decide the type (or choose "32bit" for atomic
+         * reads, which has been fine).
+         */
+        int num_components;
+        if (tmu_op == GENERAL_TMU_WRITE_OP_ATOMIC_CMPXCHG)
+                num_components = 2;
+        else
+                num_components = instr->num_components;
+
         uint32_t config = (0xffffff00 |
                            tmu_op |
                            GENERAL_TMU_LOOKUP_PER_PIXEL);
-        if (instr->num_components == 1) {
+        if (num_components == 1) {
                 config |= GENERAL_TMU_LOOKUP_TYPE_32BIT_UI;
         } else {
-                config |= (GENERAL_TMU_LOOKUP_TYPE_VEC2 +
-                           instr->num_components - 2);
+                config |= GENERAL_TMU_LOOKUP_TYPE_VEC2 + num_components - 2;
         }
 
         if (vir_in_nonuniform_control_flow(c)) {