From 32a69677783498d9ad091cd8d945256485ccff23 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Wed, 8 Oct 2025 16:24:44 +0200 Subject: [PATCH] vkd3d-shader/dxil: Ignore ORDERING_SEQCST. More recent versions of the Vulkan/SPIR-V validation layers have started to complain about our usage of "SequentiallyConsistent" in our SPIR-V output. Specifically, VUID-StandaloneSpirv-MemorySemantics-10866 "Memory Semantics with SequentiallyConsistent memory order must not be used in the Vulkan API". The SPIR-V specification says: "If the declared memory model is Vulkan, SequentiallyConsistent must not be used." However, we're using the GLSL450 memory model with SPIR-V 1.3, and "Vulkan" is not available before SPIR-V 1.5. The Vulkan specification says "Sequentially consistent atomics and barriers are not supported and SequentiallyConsistent is treated as AcquireRelease. SequentiallyConsistent should not be used." in the "Shader Memory Access Ordering" section. Those don't quite add up to the "... must not be used in the Vulkan API", from the validation layers, but it does seem clear that SequentiallyConsistent isn't actually supported. On the DXIL side, when targetting SPIR-V with dxc, the generated SPIR-V uses the "None"/"Relaxed" memory semantics. I wasn't immediately able to find a reference for what seq_cst is supposed to mean in the context of DXIL, but "None"/"Relaxed" does seem consistent with how the HLSL atomic/interlocked intrinsics are expected to behave, as well as with our behaviour for tpf shaders. --- libs/vkd3d-shader/d3d_asm.c | 5 ----- libs/vkd3d-shader/dxil.c | 8 ++++++-- libs/vkd3d-shader/spirv.c | 9 ++------- libs/vkd3d-shader/vkd3d_shader_private.h | 3 +-- 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d-shader/d3d_asm.c index 6f8fbe84b..4573cb67f 100644 --- a/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d-shader/d3d_asm.c @@ -145,11 +145,6 @@ static void shader_dump_global_flags(struct vkd3d_d3d_asm_compiler *compiler, en static void shader_dump_atomic_op_flags(struct vkd3d_d3d_asm_compiler *compiler, uint32_t atomic_flags) { - if (atomic_flags & VKD3DARF_SEQ_CST) - { - vkd3d_string_buffer_printf(&compiler->buffer, "_seqCst"); - atomic_flags &= ~VKD3DARF_SEQ_CST; - } if (atomic_flags & VKD3DARF_VOLATILE) { vkd3d_string_buffer_printf(&compiler->buffer, "_volatile"); diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 0cdb4373d..036f4ce90 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -4467,6 +4467,8 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ /* It's currently not possible to specify an atomic ordering in HLSL, and it defaults to seq_cst. */ if ((code = record->operands[i++]) != ORDERING_SEQCST) FIXME("Unhandled atomic ordering %"PRIu64".\n", code); + else + WARN("Ignoring atomic ordering %"PRIu64".\n", code); if ((code = record->operands[i]) != 1) WARN("Ignoring synchronisation scope %"PRIu64".\n", code); @@ -4484,7 +4486,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ ins = state->ins; vsir_instruction_init(ins, &sm6->p.location, op); - ins->flags = is_volatile ? VKD3DARF_SEQ_CST | VKD3DARF_VOLATILE : VKD3DARF_SEQ_CST; + ins->flags = is_volatile ? VKD3DARF_VOLATILE : 0; if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; @@ -7326,6 +7328,8 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re /* It's currently not possible to specify an atomic ordering in HLSL, and it defaults to seq_cst. */ if (success_ordering != ORDERING_SEQCST) FIXME("Unhandled success ordering %"PRIu64".\n", success_ordering); + else + WARN("Ignoring success ordering %"PRIu64".\n", success_ordering); if (success_ordering != failure_ordering) FIXME("Unhandled failure ordering %"PRIu64".\n", failure_ordering); @@ -7333,7 +7337,7 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re FIXME("Ignoring weak cmpxchg.\n"); vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_IMM_ATOMIC_CMP_EXCH); - ins->flags = is_volatile ? VKD3DARF_SEQ_CST | VKD3DARF_VOLATILE : VKD3DARF_SEQ_CST; + ins->flags = is_volatile ? VKD3DARF_VOLATILE : 0; if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 5a400f42e..51165105b 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -9733,7 +9733,6 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil const struct vkd3d_shader_dst_param *resource; uint32_t coordinate_id, sample_id, pointer_id; struct vkd3d_shader_register_info reg_info; - SpvMemorySemanticsMask memory_semantic; struct vkd3d_shader_image image; enum vsir_data_type data_type; unsigned int structure_stride; @@ -9835,16 +9834,12 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); } - memory_semantic = (instruction->flags & VKD3DARF_SEQ_CST) - ? SpvMemorySemanticsSequentiallyConsistentMask - : SpvMemorySemanticsMaskNone; - operands[i++] = pointer_id; operands[i++] = spirv_compiler_get_constant_uint(compiler, scope); - operands[i++] = spirv_compiler_get_constant_uint(compiler, memory_semantic); + operands[i++] = spirv_compiler_get_constant_uint(compiler, SpvMemorySemanticsMaskNone); if (instruction->src_count >= 3) { - operands[i++] = spirv_compiler_get_constant_uint(compiler, memory_semantic); + operands[i++] = spirv_compiler_get_constant_uint(compiler, SpvMemorySemanticsMaskNone); operands[i++] = spirv_compiler_emit_load_src_with_type(compiler, &src[2], VKD3DSP_WRITEMASK_0, data_type); } operands[i++] = val_id; diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index e7ddab60f..77bb26f19 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -878,8 +878,7 @@ enum vkd3d_shader_uav_flags enum vkd3d_shader_atomic_rmw_flags { - VKD3DARF_SEQ_CST = 0x1, - VKD3DARF_VOLATILE = 0x2, + VKD3DARF_VOLATILE = 0x1, }; enum vkd3d_tessellator_domain