Name Strings
SPV_KHR_vulkan_memory_model
Contact
To report problems with this extension, please open a new issue at:
Contributors
-
Jeff Bolz, NVIDIA
Status
-
Complete
-
Approved by the SPIR Working Group: 2018-07-13
-
Approved by the Khronos Board of Promoters: 2018-08-24
Version
Last Modified Date |
2019-06-13 |
Revision |
4 |
Dependencies
This extension is written against the SPIR-V Specification, Version 1.3 Revision 1.
This extension requires SPIR-V 1.3.
Overview
This extension adds new functionality related to the Vulkan memory model. The definitions of the new semantics are left intentionally brief, with more thorough specifications left to the Vulkan SPIR-V environment and Vulkan Memory Model appendix.
New Memory Semantics Bits:
MakeAvailableKHR and MakeVisibleKHR make memory barriers and atomics perform availability and visibility operations for an entire storage class, as defined in the memory model.
OutputMemoryKHR is a new memory semantics bit that indicates the operation synchronizes accesses to the output storage class (for tessellation control shaders).
New Memory Access Bits:
MakePointerAvailableKHR and MakePointerVisibleKHR make memory access instructions perform availability and visibility operations on the locations pointed to by the pointer operand, as defined in the memory model. NonPrivatePointerKHR makes memory access instructions obey inter-thread ordering, as defined in the memory model.
New Image Operands Bits:
MakeTexelAvailableKHR and MakeTexelVisibleKHR make image access instructions perform availability and visibility operations on the texel’s memory locations, as defined in the memory model. NonPrivateTexelKHR makes image access instructions obey inter-thread ordering, as defined in the memory model.
New Scope:
QueueFamilyKHR is a scope that includes all invocations from queues in the same queue family. The existing Device scope is optional in Vulkan, and use of it with the new memory model requires a new capability VulkanMemoryModelDeviceScopeKHR.
The Coherent decoration is deprecated and replaced (and extended) by MakePointerAvailableKHR or MakePointerVisibleKHR and MakeTexelAvailableKHR or MakeTexelVisibleKHR. Similarly, the Volatile decoration is deprecated and replaced by the Volatile Memory Access bit for pointers, the VolatileTexelKHR Image Operands bit for image accesses, and the Volatile Memory Semantics bit for atomics.
VulkanKHR is a new Memory Model enum which indicates that a module opts into the Vulkan Memory Model.
VulkanMemoryModelKHR is a capability that indicates a module uses the new memory model. VulkanMemoryModelDeviceScopeKHR is a capability that indicates a module uses Device scope with the Vulkan Memory Model.
Extension Name
To use this extension within a SPIR-V module, the following OpExtension must be present in the module:
OpExtension "SPV_KHR_vulkan_memory_model"
New Capabilities
This extension introduces the following new capabilities:
VulkanMemoryModelKHR VulkanMemoryModelDeviceScopeKHR
New Decorations
None
New Builtins
None
New Instructions
None
Modifications to the SPIR-V Specification, Version 1.3
(Modify section 2.18.2, Aliasing):
Add VulkanKHR to the list of models that assume aliasing is generally not present:
How aliasing is managed depends on the Memory Model:
The simple, GLSL450, and VulkanKHR memory models can assume that aliasing is generally not present. …
(Add to the table in 3.5, Memory Model):
3 |
VulkanKHR |
VulkanMemoryModelKHR |
(Modify the table in 3.20, Decoration):
Add to the description of Coherent
Coherent is not allowed when the declared memory model is VulkanKHR. The Memory Access bits MakePointerAvailableKHR and MakePointerVisibleKHR or the Image Operands bits MakeTexelAvailableKHR and MakeTexelVisibleKHR can be used instead.
Add to the description of Volatile
Volatile is not allowed when the declared memory model is VulkanKHR. The Memory Access bit Volatile, the Image Operands bit VolatileTexelKHR, or the Memory Semantics bit Volatile can be used instead.
(Modify Section 3.14, Image Operands, adding to the end of the table)
0x100 |
MakeTexelAvailableKHR |
VulkanMemoryModelKHR |
0x200 |
MakeTexelVisibleKHR |
VulkanMemoryModelKHR |
0x400 |
NonPrivateTexelKHR |
VulkanMemoryModelKHR |
0x800 |
VolatileTexelKHR |
VulkanMemoryModelKHR |
(Modify Section 3.25, Memory Semantics)
Add to the description of SequentiallyConsistent
If the declared memory model is VulkanKHR, SequentiallyConsistent must not be used.
Add new entries to the end of the table:
0x1000 |
OutputMemoryKHR |
VulkanMemoryModelKHR |
0x2000 |
MakeAvailableKHR |
VulkanMemoryModelKHR |
0x4000 |
MakeVisibleKHR |
VulkanMemoryModelKHR |
0x8000 |
Volatile |
VulkanMemoryModelKHR |
(Modify Section 3.26, Memory Operands)
Add to the end of the table:
0x08 |
MakePointerAvailableKHR |
VulkanMemoryModelKHR |
0x10 |
MakePointerVisibleKHR |
VulkanMemoryModelKHR |
0x20 |
NonPrivatePointerKHR |
VulkanMemoryModelKHR |
(Modify Section 3.27, Scope <id>, adding to the end of the table)
5 |
QueueFamilyKHR |
VulkanMemoryModelKHR |
- (Modify Section 3.31, Capability, adding new rows to the Capability table)
-
Capability Implicitly Declares Enabled by Extension 5345
VulkanMemoryModelKHR
Uses the Vulkan Memory Model. This capability must be declared if and only if the VulkanKHR OpMemoryModel memory model is used.None
SPV_KHR_vulkan_memory_model
5346
VulkanMemoryModelDeviceScopeKHR
Uses Device scope with the Vulkan Memory Model. This capability must be declared if a scope of Device is used with any instruction and the VulkanKHR OpMemoryModel memory model is used.None
SPV_KHR_vulkan_memory_model
(Modify Section 3.32.8. Memory Instructions)
In OpCopyMemory and OpCopyMemorySized, if this extension is being used with SPIR-V 1.4, replace:
If two masks are present, the first applies to Target and the second applies to Source.
with:
If two masks are present, the first applies to Target and cannot include MakePointerVisibleKHR, and the second applies to Source and cannot include MakePointerAvailableKHR.
(Modify Section 3.32.20. Barrier Instructions)
Update the description of OpMemoryBarrier. Modify the second paragraph to say:
Ensures that memory accesses issued before this instruction will be observed before memory accesses issued after this instruction. This control is ensured only for memory accesses issued by this invocation and observed by another invocation executing within Memory scope. If the VulkanKHR memory model is used, this ordering only applies to memory accesses that use the NonPrivatePointerKHR or NonPrivateTexelKHR flags.
Validation Rules
An OpExtension must be added to the SPIR-V for validation layers to check legal use of this extension:
OpExtension "SPV_KHR_vulkan_memory_model"
If OpLoad, OpStore, OpCopyMemory, or OpCopyMemorySized use MakePointerAvailableKHR or MakePointerVisibleKHR, the optional scope operand must be present.
If OpImageRead, OpImageSparseRead, or OpImageWrite use MakeTexelAvailableKHR or MakeTexelVisibleKHR, the optional scope operand must be present.
Memory accesses that use NonPrivatePointerKHR must use pointers in the Uniform, Workgroup, CrossWorkgroup, Generic, Image, or StorageBuffer storage classes.
If OpMemoryModel memory model is VulkanKHR and any instruction uses Device scope, VulkanMemoryModelDeviceScopeKHR must be declared.
Issues
(1) How many capabilities do we need?
RESOLVED: We use a single capability for most of the functionality, even though it is (arguably) redundant with the new OpMemoryModel enum, because we expect a lot of tooling to rely n the existence of a capability. There is a second capability (VulkanMemoryModelDeviceScopeKHR) tied to an optional feature.
(2) Can we deprecate "Coherent" and put Availability/Visibility decorations on individual memory instructions instead?
RESOLVED. Yes. In many ways it is cleaner and more natural to use per-instruction coherency. It better matches the definition in the model, matches many hardware implementations, and is more natural when using variable pointers. We do the same for the "Volatile" decoration.
(3) Should inter-thread ordering rules be opt-in (NonPrivate{Pointer,Texel}KHR) or opt-out?
RESOLVED: Having accesses default to private and requiring explicit opt-in to non-private is cleaner in a few ways. It is a default that is valid for all storage classes, including those like Private that can’t possibly be shared between invocations. It naturally matches the default we’ll want in GLSL, where undecorated (non-coherent) variables are usually not used for communication between invocations, and setting the "coherent" qualifier can implicitly make accesses non-private. And it makes it more natural to express some of the validation rules.
Revision History
Rev | Date | Author | Changes |
---|---|---|---|
1 |
2018-04-20 |
Jeff Bolz |
Initial draft |
2 |
2018-09-05 |
Jeff Bolz, David Neto |
Add QueueFamilyKHR, update Memory Access Operands |
3 |
2019-02-19 |
David Neto |
Khronos SPIR-V Issue #413: Interaction with SPIR-V 1.4: Restrictions on memory access bits in two-operand OpCopyMemory and OpCopyMemorySized. |
4 |
2019-06-13 |
Jeff Bolz |
Added Volatile to Memory Semantics |