diff options
author | Alyssa Rosenzweig <alyssa@rosenzweig.io> | 2023-05-08 15:29:31 -0400 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2023-05-12 20:39:46 +0000 |
commit | d51bc95837620a774f6d2b04228f340dfc536fc6 (patch) | |
tree | 731a32a59c52116d9cd772f840184d9eb3095d8e /src/compiler/nir/nir_print.c | |
parent | 88f6d7f4bdf90bcfdb17e4aadddec3c855a12b13 (diff) | |
download | mesa-d51bc95837620a774f6d2b04228f340dfc536fc6.tar.gz |
nir: Add unified atomics
Currently, we have an atomic intrinsic for each combination of memory type
(global, shared, image, etc) and atomic operation (add, sub, etc). So for m
types of memory supported by the driver and n atomic opcodes, the driver has to
handle O(mn) intrinsics. This makes a total mess in every single backend I've
looked at, without fail.
It would be a lot nicer to unify the intrinsics. There are two obvious ways:
1. Make the memory type a constant index, keep different intrinsics for
different operations. The problem with this is that different memory types
imply different intrinsic signatures (number of sources, etc). As an
example, it doesn't make sense to unify global_atomic_amd with
global_atomic_2x32, as an example. The first takes 3 scalar sources, the
second takes 1 vector and 1 scalar. Also, in any single backend, there are a
lot more operations than there are memory types.
2. Make the opcode a constant index, keep different intrinsics for different
operations. This works well, with one exception: compswap and fcompswap
take an extra argument that other atomics don't, so there's an extra axis of
variation for the intrinsic signatures.
So, the solution is to have 2 intrinsics for each memory type -- for atomics
taking 1 argument and atomics taking 2 respectively. Both of these intrinsics
take an nir_atomic_op enum to describe its operation. We don't use a nir_op for
this purpose, as there are some atomics (cmpxchg, inc_wrap, etc) that don't
cleanly map to any ALU op and it would be weird to force it.
The plan is to transition to these new opcodes gradually. This series adds a
lowering pass producing these opcodes from the existing opcodes, so that
backends can opt-in to the new forms one-by-one. Then we can convert backends
separately without any cross-tree flag day. Once everything is converted, we can
convert the producers and core NIR as a flag day, but we have far fewer
producers than backends so this should be fine. Finally we can drop the old
stuff.
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Rob Clark <robclark@freedesktop.org>
Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22914>
Diffstat (limited to 'src/compiler/nir/nir_print.c')
-rw-r--r-- | src/compiler/nir/nir_print.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c index 3c00171da04..ed6e299dc5b 100644 --- a/src/compiler/nir/nir_print.c +++ b/src/compiler/nir/nir_print.c @@ -953,6 +953,32 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, print_state *state) break; } + case NIR_INTRINSIC_ATOMIC_OP: { + nir_atomic_op atomic_op = nir_intrinsic_atomic_op(instr); + fprintf(fp, "atomic_op="); + print_raw = false; + + switch (atomic_op) { + case nir_atomic_op_iadd: fprintf(fp, "iadd"); break; + case nir_atomic_op_imin: fprintf(fp, "imin"); break; + case nir_atomic_op_umin: fprintf(fp, "umin"); break; + case nir_atomic_op_imax: fprintf(fp, "imax"); break; + case nir_atomic_op_umax: fprintf(fp, "umax"); break; + case nir_atomic_op_iand: fprintf(fp, "iand"); break; + case nir_atomic_op_ior: fprintf(fp, "ior"); break; + case nir_atomic_op_ixor: fprintf(fp, "ixor"); break; + case nir_atomic_op_xchg: fprintf(fp, "xchg"); break; + case nir_atomic_op_fadd: fprintf(fp, "fadd"); break; + case nir_atomic_op_fmin: fprintf(fp, "fmin"); break; + case nir_atomic_op_fmax: fprintf(fp, "fmax"); break; + case nir_atomic_op_cmpxchg: fprintf(fp, "cmpxchg"); break; + case nir_atomic_op_fcmpxchg: fprintf(fp, "fcmpxchg"); break; + case nir_atomic_op_inc_wrap: fprintf(fp, "inc_wrap"); break; + case nir_atomic_op_dec_wrap: fprintf(fp, "dec_wrap"); break; + } + break; + } + case NIR_INTRINSIC_IMAGE_DIM: { static const char *dim_name[] = { [GLSL_SAMPLER_DIM_1D] = "1D", |