Fix interactions between 'volatile' and the Vulkan memory model
Last year we changed 'volatile' to also act as 'coherent', but when I
resolved the memory model changes against that change I missed handling
volatile in a couple places that we check for coherent. There was also
a place in post-processing that acted as if the volatile memory access
flag has a literal number associated with it, when it doesn't.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 7dc0b94..5b753ce 100644
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -565,14 +565,15 @@
flags.workgroupcoherent = type.getQualifier().workgroupcoherent ||
type.getQualifier().storage == glslang::EvqShared;
flags.subgroupcoherent = type.getQualifier().subgroupcoherent;
+ flags.volatil = type.getQualifier().volatil;
// *coherent variables are implicitly nonprivate in GLSL
flags.nonprivate = type.getQualifier().nonprivate ||
flags.subgroupcoherent ||
flags.workgroupcoherent ||
flags.queuefamilycoherent ||
flags.devicecoherent ||
- flags.coherent;
- flags.volatil = type.getQualifier().volatil;
+ flags.coherent ||
+ flags.volatil;
flags.isImage = type.getBasicType() == glslang::EbtSampler;
return flags;
}
@@ -580,7 +581,7 @@
spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope(const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
{
spv::Scope scope;
- if (coherentFlags.coherent) {
+ if (coherentFlags.volatil || coherentFlags.coherent) {
// coherent defaults to Device scope in the old model, QueueFamilyKHR scope in the new model
scope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice;
} else if (coherentFlags.devicecoherent) {
diff --git a/SPIRV/SpvPostProcess.cpp b/SPIRV/SpvPostProcess.cpp
old mode 100755
new mode 100644
index d4924f6..05f5455
--- a/SPIRV/SpvPostProcess.cpp
+++ b/SPIRV/SpvPostProcess.cpp
@@ -260,8 +260,6 @@
assert(memoryAccess & MemoryAccessAlignedMask);
// Compute the index of the alignment operand.
int alignmentIdx = 2;
- if (memoryAccess & MemoryAccessVolatileMask)
- alignmentIdx++;
if (inst.getOpCode() == OpStore)
alignmentIdx++;
// Merge new and old (mis)alignment
diff --git a/Test/baseResults/spv.bufferhandle10.frag.out b/Test/baseResults/spv.bufferhandle10.frag.out
index bfaa2d8..72777f9 100644
--- a/Test/baseResults/spv.bufferhandle10.frag.out
+++ b/Test/baseResults/spv.bufferhandle10.frag.out
@@ -1,7 +1,7 @@
spv.bufferhandle10.frag
// Module Version 10000
// Generated by (magic number): 80007
-// Id's are bound by 34
+// Id's are bound by 40
Capability Shader
Capability CapabilityVulkanMemoryModelKHR
@@ -24,6 +24,7 @@
Name 12 "t"
Name 19 "i"
Name 28 "b"
+ Name 34 "b2"
MemberDecorate 7(t2) 0 Offset 0
Decorate 7(t2) Block
Decorate 9 ArrayStride 4
@@ -34,6 +35,7 @@
Decorate 19(i) Flat
Decorate 19(i) Location 0
Decorate 28(b) DecorationAliasedPointerEXT
+ Decorate 34(b2) DecorationAliasedPointerEXT
2: TypeVoid
3: TypeFunction 2
TypeForwardPointer 6 PhysicalStorageBufferEXT
@@ -55,9 +57,11 @@
25: 8(int) Constant 0
27: TypePointer Function 6(ptr)
32: 8(int) Constant 2
+ 38: 8(int) Constant 3
4(main): 2 Function None 3
5: Label
28(b): 27(ptr) Variable Function
+ 34(b2): 27(ptr) Variable Function
16: 15(ptr) AccessChain 12(t) 14
17: 6(ptr) Load 16
20: 8(int) Load 19(i)
@@ -69,5 +73,11 @@
31: 6(ptr) Load 28(b)
33: 21(ptr) AccessChain 31 14 14
Store 33 32 Aligned MakePointerAvailableKHR NonPrivatePointerKHR 4 24
+ 35: 15(ptr) AccessChain 12(t) 14
+ 36: 6(ptr) Load 35
+ Store 34(b2) 36 Volatile
+ 37: 6(ptr) Load 34(b2) Volatile
+ 39: 21(ptr) AccessChain 37 14 14
+ Store 39 38 Volatile Aligned MakePointerAvailableKHR NonPrivatePointerKHR 4 24
Return
FunctionEnd
diff --git a/Test/baseResults/spv.memoryScopeSemantics.comp.out b/Test/baseResults/spv.memoryScopeSemantics.comp.out
index 4c79a10..0de15ef 100644
--- a/Test/baseResults/spv.memoryScopeSemantics.comp.out
+++ b/Test/baseResults/spv.memoryScopeSemantics.comp.out
@@ -1,7 +1,7 @@
spv.memoryScopeSemantics.comp
// Module Version 10300
// Generated by (magic number): 80007
-// Id's are bound by 143
+// Id's are bound by 148
Capability Shader
Capability Int64
@@ -43,6 +43,9 @@
Name 122 "samp"
Name 133 "atomu64"
Name 138 "atomi64"
+ Name 143 "BufferL"
+ MemberName 143(BufferL) 0 "x"
+ Name 145 "bufferl"
Decorate 36(imagei) DescriptorSet 0
Decorate 36(imagei) Binding 1
Decorate 45(imageu) DescriptorSet 0
@@ -69,6 +72,10 @@
Decorate 110(imagej) Binding 5
Decorate 122(samp) DescriptorSet 0
Decorate 122(samp) Binding 6
+ MemberDecorate 143(BufferL) 0 Offset 0
+ Decorate 143(BufferL) Block
+ Decorate 145(bufferl) DescriptorSet 0
+ Decorate 145(bufferl) Binding 8
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
@@ -152,6 +159,9 @@
137: TypePointer Workgroup 136(int64_t)
138(atomi64): 137(ptr) Variable Workgroup
139:136(int64_t) Constant 10 0
+ 143(BufferL): TypeStruct 15(int)
+ 144: TypePointer StorageBuffer 143(BufferL)
+ 145(bufferl): 144(ptr) Variable StorageBuffer
4(main): 2 Function None 3
5: Label
8(origi): 7(ptr) Variable Function
@@ -204,18 +214,18 @@
81: 15(int) Load 80 MakePointerVisibleKHR NonPrivatePointerKHR 16
Store 72(y) 81
88: 68(ptr) AccessChain 87(bufferj) 38 38 38 12
- 89: 15(int) Load 88 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 46
+ 89: 15(int) Load 88 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 16
Store 72(y) 89
90: 15(int) Load 72(y)
91: 68(ptr) AccessChain 79(bufferi) 38
Store 91 90 MakePointerAvailableKHR NonPrivatePointerKHR 16
92: 15(int) Load 72(y)
93: 68(ptr) AccessChain 87(bufferj) 38 38 38 12
- Store 93 92 Volatile MakePointerAvailableKHR NonPrivatePointerKHR 46
+ Store 93 92 Volatile MakePointerAvailableKHR NonPrivatePointerKHR 16
95: 94(ptr) AccessChain 87(bufferj) 12 38
- 96: 83(A) Load 95 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 46
+ 96: 83(A) Load 95 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 16
97: 94(ptr) AccessChain 87(bufferj) 38 38
- Store 97 96 Volatile MakePointerAvailableKHR NonPrivatePointerKHR 46
+ Store 97 96 Volatile MakePointerAvailableKHR NonPrivatePointerKHR 16
102: 101(ptr) AccessChain 100(bufferk) 38
103: 15(int) Load 102 NonPrivatePointerKHR
104: 68(ptr) AccessChain 79(bufferi) 38
@@ -236,5 +246,8 @@
140:131(int64_t) Load 133(atomu64) MakePointerVisibleKHR NonPrivatePointerKHR 26
141:136(int64_t) Bitcast 140
142:136(int64_t) AtomicCompareExchange 138(atomi64) 12 63 63 141 139
+ 146: 68(ptr) AccessChain 145(bufferl) 38
+ 147: 15(int) Load 146 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 16
+ Store 72(y) 147
Return
FunctionEnd
diff --git a/Test/spv.bufferhandle10.frag b/Test/spv.bufferhandle10.frag
index 1d537e4..d720563 100644
--- a/Test/spv.bufferhandle10.frag
+++ b/Test/spv.bufferhandle10.frag
@@ -20,4 +20,6 @@
coherent blockType b = t.f;
b.x[0] = 2;
+ volatile blockType b2 = t.f;
+ b2.x[0] = 3;
}
diff --git a/Test/spv.memoryScopeSemantics.comp b/Test/spv.memoryScopeSemantics.comp
index c03c123..88f5481 100644
--- a/Test/spv.memoryScopeSemantics.comp
+++ b/Test/spv.memoryScopeSemantics.comp
@@ -18,6 +18,7 @@
layout (binding = 7) nonprivate uniform BufferK { uint x; } bufferk;
shared uint64_t atomu64;
shared int64_t atomi64;
+layout (binding = 8) volatile buffer BufferL { uint x; } bufferl;
void main()
@@ -57,5 +58,7 @@
atomu64 = atomicMax(atomu64, uint64_t(7), gl_ScopeDevice, 0, 0);
atomicCompSwap(atomi64, int64_t(10), int64_t(atomu64), gl_ScopeDevice, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire);
+
+ y = bufferl.x;
}