summaryrefslogtreecommitdiff
path: root/src/freedreno/ir3/ir3_a6xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/freedreno/ir3/ir3_a6xx.c')
-rw-r--r--src/freedreno/ir3/ir3_a6xx.c151
1 files changed, 55 insertions, 96 deletions
diff --git a/src/freedreno/ir3/ir3_a6xx.c b/src/freedreno/ir3/ir3_a6xx.c
index d5314c54ef5..c45f6108a32 100644
--- a/src/freedreno/ir3/ir3_a6xx.c
+++ b/src/freedreno/ir3/ir3_a6xx.c
@@ -89,6 +89,39 @@ emit_intrinsic_store_ssbo(struct ir3_context *ctx, nir_intrinsic_instr *intr)
array_insert(b, b->keeps, stib);
}
+static struct ir3_instruction *
+emit_atomic(struct ir3_block *b,
+ nir_atomic_op op,
+ struct ir3_instruction *ibo,
+ struct ir3_instruction *src0,
+ struct ir3_instruction *src1)
+{
+ switch (op) {
+ case nir_atomic_op_iadd:
+ return ir3_ATOMIC_B_ADD(b, ibo, 0, src0, 0, src1, 0);
+ case nir_atomic_op_imin:
+ return ir3_ATOMIC_B_MIN(b, ibo, 0, src0, 0, src1, 0);
+ case nir_atomic_op_umin:
+ return ir3_ATOMIC_B_MIN(b, ibo, 0, src0, 0, src1, 0);
+ case nir_atomic_op_imax:
+ return ir3_ATOMIC_B_MAX(b, ibo, 0, src0, 0, src1, 0);
+ case nir_atomic_op_umax:
+ return ir3_ATOMIC_B_MAX(b, ibo, 0, src0, 0, src1, 0);
+ case nir_atomic_op_iand:
+ return ir3_ATOMIC_B_AND(b, ibo, 0, src0, 0, src1, 0);
+ case nir_atomic_op_ior:
+ return ir3_ATOMIC_B_OR(b, ibo, 0, src0, 0, src1, 0);
+ case nir_atomic_op_ixor:
+ return ir3_ATOMIC_B_XOR(b, ibo, 0, src0, 0, src1, 0);
+ case nir_atomic_op_xchg:
+ return ir3_ATOMIC_B_XCHG(b, ibo, 0, src0, 0, src1, 0);
+ case nir_atomic_op_cmpxchg:
+ return ir3_ATOMIC_B_CMPXCHG(b, ibo, 0, src0, 0, src1, 0);
+ default:
+ unreachable("boo");
+ }
+}
+
/*
* SSBO atomic intrinsics
*
@@ -103,7 +136,7 @@ emit_intrinsic_store_ssbo(struct ir3_context *ctx, nir_intrinsic_instr *intr)
* 1: The offset into the SSBO buffer of the variable that the atomic
* operation will operate on.
* 2: The data parameter to the atomic function (i.e. the value to add
- * in ssbo_atomic_add, etc).
+ * in, etc).
* 3: For CompSwap only: the second data parameter.
*/
static struct ir3_instruction *
@@ -111,7 +144,8 @@ emit_intrinsic_atomic_ssbo(struct ir3_context *ctx, nir_intrinsic_instr *intr)
{
struct ir3_block *b = ctx->block;
struct ir3_instruction *atomic, *ibo, *src0, *src1, *data, *dummy;
- type_t type = TYPE_U32;
+ nir_atomic_op op = nir_intrinsic_atomic_op(intr);
+ type_t type = nir_atomic_op_type(op) == nir_type_int ? TYPE_S32 : TYPE_U32;
ibo = ir3_ssbo_to_ibo(ctx, intr->src[0]);
@@ -133,7 +167,7 @@ emit_intrinsic_atomic_ssbo(struct ir3_context *ctx, nir_intrinsic_instr *intr)
*/
dummy = create_immed(b, 0);
- if (intr->intrinsic == nir_intrinsic_ssbo_atomic_comp_swap_ir3) {
+ if (op == nir_atomic_op_cmpxchg) {
src0 = ir3_get_src(ctx, &intr->src[4])[0];
struct ir3_instruction *compare = ir3_get_src(ctx, &intr->src[3])[0];
src1 = ir3_collect(b, dummy, compare, data);
@@ -142,43 +176,7 @@ emit_intrinsic_atomic_ssbo(struct ir3_context *ctx, nir_intrinsic_instr *intr)
src1 = ir3_collect(b, dummy, data);
}
- switch (intr->intrinsic) {
- case nir_intrinsic_ssbo_atomic_add_ir3:
- atomic = ir3_ATOMIC_B_ADD(b, ibo, 0, src0, 0, src1, 0);
- break;
- case nir_intrinsic_ssbo_atomic_imin_ir3:
- atomic = ir3_ATOMIC_B_MIN(b, ibo, 0, src0, 0, src1, 0);
- type = TYPE_S32;
- break;
- case nir_intrinsic_ssbo_atomic_umin_ir3:
- atomic = ir3_ATOMIC_B_MIN(b, ibo, 0, src0, 0, src1, 0);
- break;
- case nir_intrinsic_ssbo_atomic_imax_ir3:
- atomic = ir3_ATOMIC_B_MAX(b, ibo, 0, src0, 0, src1, 0);
- type = TYPE_S32;
- break;
- case nir_intrinsic_ssbo_atomic_umax_ir3:
- atomic = ir3_ATOMIC_B_MAX(b, ibo, 0, src0, 0, src1, 0);
- break;
- case nir_intrinsic_ssbo_atomic_and_ir3:
- atomic = ir3_ATOMIC_B_AND(b, ibo, 0, src0, 0, src1, 0);
- break;
- case nir_intrinsic_ssbo_atomic_or_ir3:
- atomic = ir3_ATOMIC_B_OR(b, ibo, 0, src0, 0, src1, 0);
- break;
- case nir_intrinsic_ssbo_atomic_xor_ir3:
- atomic = ir3_ATOMIC_B_XOR(b, ibo, 0, src0, 0, src1, 0);
- break;
- case nir_intrinsic_ssbo_atomic_exchange_ir3:
- atomic = ir3_ATOMIC_B_XCHG(b, ibo, 0, src0, 0, src1, 0);
- break;
- case nir_intrinsic_ssbo_atomic_comp_swap_ir3:
- atomic = ir3_ATOMIC_B_CMPXCHG(b, ibo, 0, src0, 0, src1, 0);
- break;
- default:
- unreachable("boo");
- }
-
+ atomic = emit_atomic(b, op, ibo, src0, src1);
atomic->cat6.iim_val = 1;
atomic->cat6.d = 1;
atomic->cat6.type = type;
@@ -259,6 +257,7 @@ emit_intrinsic_atomic_image(struct ir3_context *ctx, nir_intrinsic_instr *intr)
struct ir3_instruction *const *coords = ir3_get_src(ctx, &intr->src[1]);
struct ir3_instruction *value = ir3_get_src(ctx, &intr->src[3])[0];
unsigned ncoords = ir3_get_image_coords(intr, NULL);
+ nir_atomic_op op = nir_intrinsic_atomic_op(intr);
ibo = ir3_image_to_ibo(ctx, intr->src[0]);
@@ -277,55 +276,14 @@ emit_intrinsic_atomic_image(struct ir3_context *ctx, nir_intrinsic_instr *intr)
dummy = create_immed(b, 0);
src0 = ir3_create_collect(b, coords, ncoords);
- if (intr->intrinsic == nir_intrinsic_image_atomic_comp_swap ||
- intr->intrinsic == nir_intrinsic_bindless_image_atomic_comp_swap) {
+ if (op == nir_atomic_op_cmpxchg) {
struct ir3_instruction *compare = ir3_get_src(ctx, &intr->src[4])[0];
src1 = ir3_collect(b, dummy, compare, value);
} else {
src1 = ir3_collect(b, dummy, value);
}
- switch (intr->intrinsic) {
- case nir_intrinsic_image_atomic_add:
- case nir_intrinsic_bindless_image_atomic_add:
- atomic = ir3_ATOMIC_B_ADD(b, ibo, 0, src0, 0, src1, 0);
- break;
- case nir_intrinsic_image_atomic_imin:
- case nir_intrinsic_image_atomic_umin:
- case nir_intrinsic_bindless_image_atomic_imin:
- case nir_intrinsic_bindless_image_atomic_umin:
- atomic = ir3_ATOMIC_B_MIN(b, ibo, 0, src0, 0, src1, 0);
- break;
- case nir_intrinsic_image_atomic_imax:
- case nir_intrinsic_image_atomic_umax:
- case nir_intrinsic_bindless_image_atomic_imax:
- case nir_intrinsic_bindless_image_atomic_umax:
- atomic = ir3_ATOMIC_B_MAX(b, ibo, 0, src0, 0, src1, 0);
- break;
- case nir_intrinsic_image_atomic_and:
- case nir_intrinsic_bindless_image_atomic_and:
- atomic = ir3_ATOMIC_B_AND(b, ibo, 0, src0, 0, src1, 0);
- break;
- case nir_intrinsic_image_atomic_or:
- case nir_intrinsic_bindless_image_atomic_or:
- atomic = ir3_ATOMIC_B_OR(b, ibo, 0, src0, 0, src1, 0);
- break;
- case nir_intrinsic_image_atomic_xor:
- case nir_intrinsic_bindless_image_atomic_xor:
- atomic = ir3_ATOMIC_B_XOR(b, ibo, 0, src0, 0, src1, 0);
- break;
- case nir_intrinsic_image_atomic_exchange:
- case nir_intrinsic_bindless_image_atomic_exchange:
- atomic = ir3_ATOMIC_B_XCHG(b, ibo, 0, src0, 0, src1, 0);
- break;
- case nir_intrinsic_image_atomic_comp_swap:
- case nir_intrinsic_bindless_image_atomic_comp_swap:
- atomic = ir3_ATOMIC_B_CMPXCHG(b, ibo, 0, src0, 0, src1, 0);
- break;
- default:
- unreachable("boo");
- }
-
+ atomic = emit_atomic(b, op, ibo, src0, src1);
atomic->cat6.iim_val = 1;
atomic->cat6.d = ncoords;
atomic->cat6.type = ir3_get_type_for_image_intrinsic(intr);
@@ -447,49 +405,50 @@ emit_intrinsic_atomic_global(struct ir3_context *ctx, nir_intrinsic_instr *intr)
struct ir3_block *b = ctx->block;
struct ir3_instruction *addr, *atomic, *src1;
struct ir3_instruction *value = ir3_get_src(ctx, &intr->src[1])[0];
- type_t type = TYPE_U32;
+ nir_atomic_op op = nir_intrinsic_atomic_op(intr);
+ type_t type = nir_atomic_op_type(op) == nir_type_int ? TYPE_S32 : TYPE_U32;
addr = ir3_collect(b, ir3_get_src(ctx, &intr->src[0])[0],
ir3_get_src(ctx, &intr->src[0])[1]);
- if (intr->intrinsic == nir_intrinsic_global_atomic_comp_swap_ir3) {
+ if (op == nir_atomic_op_cmpxchg) {
struct ir3_instruction *compare = ir3_get_src(ctx, &intr->src[2])[0];
src1 = ir3_collect(b, compare, value);
} else {
src1 = value;
}
- switch (intr->intrinsic) {
- case nir_intrinsic_global_atomic_add_ir3:
+ switch (op) {
+ case nir_atomic_op_iadd:
atomic = ir3_ATOMIC_G_ADD(b, addr, 0, src1, 0);
break;
- case nir_intrinsic_global_atomic_imin_ir3:
+ case nir_atomic_op_imin:
atomic = ir3_ATOMIC_G_MIN(b, addr, 0, src1, 0);
type = TYPE_S32;
break;
- case nir_intrinsic_global_atomic_umin_ir3:
+ case nir_atomic_op_umin:
atomic = ir3_ATOMIC_G_MIN(b, addr, 0, src1, 0);
break;
- case nir_intrinsic_global_atomic_imax_ir3:
+ case nir_atomic_op_imax:
atomic = ir3_ATOMIC_G_MAX(b, addr, 0, src1, 0);
type = TYPE_S32;
break;
- case nir_intrinsic_global_atomic_umax_ir3:
+ case nir_atomic_op_umax:
atomic = ir3_ATOMIC_G_MAX(b, addr, 0, src1, 0);
break;
- case nir_intrinsic_global_atomic_and_ir3:
+ case nir_atomic_op_iand:
atomic = ir3_ATOMIC_G_AND(b, addr, 0, src1, 0);
break;
- case nir_intrinsic_global_atomic_or_ir3:
+ case nir_atomic_op_ior:
atomic = ir3_ATOMIC_G_OR(b, addr, 0, src1, 0);
break;
- case nir_intrinsic_global_atomic_xor_ir3:
+ case nir_atomic_op_ixor:
atomic = ir3_ATOMIC_G_XOR(b, addr, 0, src1, 0);
break;
- case nir_intrinsic_global_atomic_exchange_ir3:
+ case nir_atomic_op_xchg:
atomic = ir3_ATOMIC_G_XCHG(b, addr, 0, src1, 0);
break;
- case nir_intrinsic_global_atomic_comp_swap_ir3:
+ case nir_atomic_op_cmpxchg:
atomic = ir3_ATOMIC_G_CMPXCHG(b, addr, 0, src1, 0);
break;
default: