From d570b2b05b49453881c54069c417410e454d4850 Mon Sep 17 00:00:00 2001 From: Graeme Leese Date: Tue, 4 Oct 2022 16:16:52 +0100 Subject: [PATCH] Change Volatile generation for HelperInvocation For SPIR-V 1.6 HelperInvocation accesses need to be volatile to avoid undefined values when shaders execute 'demote'. Previously this was always decorated on the gl_HelperInvocation variable, but this is not valid when the Vulkan memory model is in use. When the memory model is enabled, stop decorating the variable declaration and apply the memory semantic to access chain loads instead. Fixes #3042 --- SPIRV/GlslangToSpv.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index ccb4602b..74053c17 100644 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -4741,6 +4741,16 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type) spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags; coherentFlags |= TranslateCoherent(type); + spv::MemoryAccessMask accessMask = spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask); + // If the value being loaded is HelperInvocation, SPIR-V 1.6 is being generated (so that + // SPV_EXT_demote_to_helper_invocation is in core) and the memory model is in use, add + // the Volatile MemoryAccess semantic. + if (type.getQualifier().builtIn == glslang::EbvHelperInvocation && + glslangIntermediate->usingVulkanMemoryModel() && + glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) { + accessMask = spv::MemoryAccessMask(accessMask | spv::MemoryAccessVolatileMask); + } + unsigned int alignment = builder.getAccessChain().alignment; alignment |= type.getBufferReferenceAlignment(); @@ -4748,7 +4758,7 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type) TranslateNonUniformDecoration(builder.getAccessChain().coherentFlags), TranslateNonUniformDecoration(type.getQualifier()), nominalTypeId, - spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask), + accessMask, TranslateMemoryScope(coherentFlags), alignment); @@ -8968,6 +8978,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol // Add volatile decoration to HelperInvocation for spirv1.6 and beyond if (builtIn == spv::BuiltInHelperInvocation && + !glslangIntermediate->usingVulkanMemoryModel() && glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) { builder.addDecoration(id, spv::DecorationVolatile); }