radeonsi: add support for nir atomic_inc_wrap/atomic_dec_wrap
authorPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Wed, 24 Jul 2019 10:07:50 +0000 (12:07 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Tue, 6 Aug 2019 21:41:06 +0000 (17:41 -0400)
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/amd/common/ac_nir_to_llvm.c
src/gallium/drivers/radeonsi/si_shader_nir.c

index 879d32f50d61e3cd1cfbdf5c91c2e0bdb591325c..42ca6a41df812fd74d1d68916f7a70c5b118d0e9 100644 (file)
@@ -2677,6 +2677,27 @@ static LLVMValueRef visit_image_atomic(struct ac_nir_context *ctx,
                atomic_name = "cmpswap";
                atomic_subop = 0; /* not used */
                break;
+       case nir_intrinsic_bindless_image_atomic_inc_wrap:
+       case nir_intrinsic_image_deref_atomic_inc_wrap: {
+               atomic_name = "inc";
+               atomic_subop = ac_atomic_inc_wrap;
+               /* ATOMIC_INC instruction does:
+                *      value = (value + 1) % (data + 1)
+                * but we want:
+                *      value = (value + 1) % data
+                * So replace 'data' by 'data - 1'.
+                */
+               ctx->ssa_defs[instr->src[3].ssa->index] =
+                       LLVMBuildSub(ctx->ac.builder,
+                                    ctx->ssa_defs[instr->src[3].ssa->index],
+                                    ctx->ac.i32_1, "");
+               break;
+       }
+       case nir_intrinsic_bindless_image_atomic_dec_wrap:
+       case nir_intrinsic_image_deref_atomic_dec_wrap:
+               atomic_name = "dec";
+               atomic_subop = ac_atomic_dec_wrap;
+               break;
        default:
                abort();
        }
@@ -3384,6 +3405,8 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
        case nir_intrinsic_bindless_image_atomic_xor:
        case nir_intrinsic_bindless_image_atomic_exchange:
        case nir_intrinsic_bindless_image_atomic_comp_swap:
+       case nir_intrinsic_bindless_image_atomic_inc_wrap:
+       case nir_intrinsic_bindless_image_atomic_dec_wrap:
                result = visit_image_atomic(ctx, instr, true);
                break;
        case nir_intrinsic_image_deref_atomic_add:
@@ -3394,6 +3417,8 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
        case nir_intrinsic_image_deref_atomic_xor:
        case nir_intrinsic_image_deref_atomic_exchange:
        case nir_intrinsic_image_deref_atomic_comp_swap:
+       case nir_intrinsic_image_deref_atomic_inc_wrap:
+       case nir_intrinsic_image_deref_atomic_dec_wrap:
                result = visit_image_atomic(ctx, instr, false);
                break;
        case nir_intrinsic_bindless_image_size:
index f0a9e8f620b4a1af8cdad8fc4ab136250142d94e..ebeaa631e8a7365c15dab62917a4e360ebc1395a 100644 (file)
@@ -306,6 +306,8 @@ static void scan_instruction(const struct nir_shader *nir,
                case nir_intrinsic_image_deref_atomic_xor:
                case nir_intrinsic_image_deref_atomic_exchange:
                case nir_intrinsic_image_deref_atomic_comp_swap:
+               case nir_intrinsic_image_deref_atomic_inc_wrap:
+               case nir_intrinsic_image_deref_atomic_dec_wrap:
                        info->writes_memory = true;
                        info->num_memory_instructions++; /* we only care about stores */
                        break;