summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>2023-05-12 10:56:07 -0400
committerMarge Bot <emma+marge@anholt.net>2023-05-12 20:39:46 +0000
commitfa1962681e8e39e3299c2249bbaea3743e218f78 (patch)
treede1276a3b35a2dc3472abbd79f988146696e301c /src/compiler
parent55f7fd6d0d36e560b55fc12c4baf785f9d0c04ed (diff)
downloadmesa-fa1962681e8e39e3299c2249bbaea3743e218f78.tar.gz
nir/validate: Handle unified atomics
nir_validate checks that the format of an atomic (if specified) is compatible with the atomic operation. For example, we can't fadd R64_UINT texels. The logic can't be extended as-is to unified atomics because it's split across different switch cases for different atomic-op intrinsics. So we add our own validation case, porting over the logic from the separate existing cases below. (The redundant logic will be deleted once we delete legacy atomics.) Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Reviewed-by: Jesse Natalie <jenatali@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22914>
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/nir/nir_validate.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c
index f2ecb8b6b29..71219d3ad5e 100644
--- a/src/compiler/nir/nir_validate.c
+++ b/src/compiler/nir/nir_validate.c
@@ -714,6 +714,44 @@ validate_intrinsic_instr(nir_intrinsic_instr *instr, validate_state *state)
util_bitcount(nir_intrinsic_memory_modes(instr)) == 1);
break;
+ case nir_intrinsic_image_deref_atomic:
+ case nir_intrinsic_image_deref_atomic_swap:
+ case nir_intrinsic_bindless_image_atomic:
+ case nir_intrinsic_bindless_image_atomic_swap:
+ case nir_intrinsic_image_atomic:
+ case nir_intrinsic_image_atomic_swap: {
+ nir_atomic_op op = nir_intrinsic_atomic_op(instr);
+
+ enum pipe_format format = image_intrin_format(instr);
+ if (format != PIPE_FORMAT_COUNT) {
+ bool allowed = false;
+ bool is_float = (nir_atomic_op_type(op) == nir_type_float);
+
+ switch (format) {
+ case PIPE_FORMAT_R32_FLOAT:
+ allowed = is_float || op == nir_atomic_op_xchg;
+ break;
+ case PIPE_FORMAT_R16_FLOAT:
+ case PIPE_FORMAT_R64_FLOAT:
+ allowed = op == nir_atomic_op_fmin || op == nir_atomic_op_fmax;
+ break;
+ case PIPE_FORMAT_R32_UINT:
+ case PIPE_FORMAT_R32_SINT:
+ case PIPE_FORMAT_R64_UINT:
+ case PIPE_FORMAT_R64_SINT:
+ allowed = !is_float;
+ break;
+ default:
+ break;
+ }
+
+ validate_assert(state, allowed);
+ validate_assert(state, nir_dest_bit_size(instr->dest) ==
+ util_format_get_blocksizebits(format));
+ }
+ break;
+ }
+
case nir_intrinsic_image_deref_atomic_add:
case nir_intrinsic_image_deref_atomic_imin:
case nir_intrinsic_image_deref_atomic_umin: