From b447fdce516f2230dbf2cb2036a450cac38bf5b1 Mon Sep 17 00:00:00 2001 From: Shaun Ren Date: Thu, 16 Jan 2025 16:16:42 -0500 Subject: [PATCH] vkd3d-shader/hlsl: Implement the InterlockedExchange() intrinsic. --- libs/vkd3d-shader/hlsl.c | 1 + libs/vkd3d-shader/hlsl.h | 1 + libs/vkd3d-shader/hlsl.y | 10 +++++++++- libs/vkd3d-shader/hlsl_codegen.c | 1 + libs/vkd3d-shader/tpf.c | 1 + tests/hlsl/uav-atomics.shader_test | 4 ++-- 6 files changed, 15 insertions(+), 3 deletions(-) diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 2d70feff..6d1626cb 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -3509,6 +3509,7 @@ static void dump_ir_interlocked(struct vkd3d_string_buffer *buffer, const struct [HLSL_INTERLOCKED_ADD] = "add", [HLSL_INTERLOCKED_AND] = "and", [HLSL_INTERLOCKED_CMP_EXCH] = "cmp_exch", + [HLSL_INTERLOCKED_EXCH] = "exch", }; VKD3D_ASSERT(interlocked->op < ARRAY_SIZE(op_names)); diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 280b695b..0c02a2e2 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -956,6 +956,7 @@ enum hlsl_interlocked_op HLSL_INTERLOCKED_ADD, HLSL_INTERLOCKED_AND, HLSL_INTERLOCKED_CMP_EXCH, + HLSL_INTERLOCKED_EXCH, }; /* Represents an interlocked operation. diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 8df61cba..5486e785 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -5388,7 +5388,8 @@ static bool intrinsic_interlocked(struct hlsl_ctx *ctx, enum hlsl_interlocked_op hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, "Interlocked functions can only be used in shader model 5.0 or higher."); - if (op != HLSL_INTERLOCKED_CMP_EXCH && params->args_count != 2 && params->args_count != 3) + if (op != HLSL_INTERLOCKED_CMP_EXCH && op != HLSL_INTERLOCKED_EXCH + && params->args_count != 2 && params->args_count != 3) { hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, "Unexpected number of arguments to function '%s': expected 2 or 3, but got %u.", @@ -5509,6 +5510,12 @@ static bool intrinsic_InterlockedCompareStore(struct hlsl_ctx *ctx, return intrinsic_interlocked(ctx, HLSL_INTERLOCKED_CMP_EXCH, params, loc, "InterlockedCompareStore"); } +static bool intrinsic_InterlockedExchange(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + return intrinsic_interlocked(ctx, HLSL_INTERLOCKED_EXCH, params, loc, "InterlockedExchange"); +} + static const struct intrinsic_function { const char *name; @@ -5526,6 +5533,7 @@ intrinsic_functions[] = {"InterlockedAnd", -1, true, intrinsic_InterlockedAnd}, {"InterlockedCompareExchange", 4, true, intrinsic_InterlockedCompareExchange}, {"InterlockedCompareStore", 3, true, intrinsic_InterlockedCompareStore}, + {"InterlockedExchange", 3, true, intrinsic_InterlockedExchange}, {"abs", 1, true, intrinsic_abs}, {"acos", 1, true, intrinsic_acos}, {"all", 1, true, intrinsic_all}, diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 0c57ce04..ff563e0e 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -10010,6 +10010,7 @@ static bool sm4_generate_vsir_instr_interlocked(struct hlsl_ctx *ctx, [HLSL_INTERLOCKED_ADD] = VKD3DSIH_IMM_ATOMIC_IADD, [HLSL_INTERLOCKED_AND] = VKD3DSIH_IMM_ATOMIC_AND, [HLSL_INTERLOCKED_CMP_EXCH] = VKD3DSIH_IMM_ATOMIC_CMP_EXCH, + [HLSL_INTERLOCKED_EXCH] = VKD3DSIH_IMM_ATOMIC_EXCH, }; struct hlsl_ir_node *cmp_value = interlocked->cmp_value.node, *value = interlocked->value.node; diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 34977933..9b66770e 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -4073,6 +4073,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ case VKD3DSIH_IMIN: case VKD3DSIH_IMM_ATOMIC_AND: case VKD3DSIH_IMM_ATOMIC_CMP_EXCH: + case VKD3DSIH_IMM_ATOMIC_EXCH: case VKD3DSIH_IMM_ATOMIC_IADD: case VKD3DSIH_IMUL: case VKD3DSIH_INE: diff --git a/tests/hlsl/uav-atomics.shader_test b/tests/hlsl/uav-atomics.shader_test index eeef299b..1746ae40 100644 --- a/tests/hlsl/uav-atomics.shader_test +++ b/tests/hlsl/uav-atomics.shader_test @@ -217,7 +217,7 @@ size (buffer, 5) % The value fields of other Interlocked functions are always uint. -[compute shader fail(sm<5) todo(sm>=5)] +[compute shader fail(sm<5)] RWBuffer u : register(u1); RWBuffer s : register(u2); @@ -245,7 +245,7 @@ void main() [test] uniform 0 uint 0xffffffff uniform 1 float -1 -todo(sm<6) dispatch 1 1 1 +todo(glsl | msl) dispatch 1 1 1 if(sm<6) probe uav 1 (0) rui (0xffffffff) if(sm>=6) probe uav 1 (0) rui (0xfffffffd) probe uav 1 (1) rui (0)