Atomics
The purpose of this chapter is to help users understand the various features Vulkan exposes for atomic operations.
Variations of Atomics
To better understand the different extensions, it is first important to be aware of the various types of atomics exposed.
-
Type
-
float
-
int
-
-
Width
-
16 bit
-
32 bit
-
64 bit
-
-
Operations
-
loads
-
stores
-
exchange
-
add
-
min
-
max
-
etc.
-
-
Storage Class
-
StorageBuffer
orUniform
(buffer) -
Workgroup
(shared memory) -
Image
(image or sparse image)
-
Baseline Support
With Vulkan 1.0 and no extensions, an application is allowed to use 32-bit int
type for atomics. This can be used for all supported SPIR-V operations (load, store, exchange, etc). SPIR-V contains some atomic operations that are guarded with the Kernel
capability and are not currently allowed in Vulkan.
Atomic Counters
While both GLSL and SPIR-V support the use of atomic counters, Vulkan does not expose the AtomicStorage
SPIR-V capability needed to use the AtomicCounter
storage class. It was decided that an app can just use OpAtomicIAdd
and OpAtomicISub
with the value 1
to achieve the same results.
VK_KHR_shader_atomic_int64
Promoted to core in Vulkan 1.2 |
This extension allows for 64-bit int
atomic operations for buffers and shared memory. If the Int64Atomics
SPIR-V capability is declared, all supported SPIR-V operations can be used with 64-bit int
.
The two feature bits, shaderBufferInt64Atomics
and shaderSharedInt64Atomics
, are used to query what storage classes are supported for 64-bit int
atomics.
-
shaderBufferInt64Atomics
- buffers -
shaderSharedInt64Atomics
- shared memory
The shaderBufferInt64Atomics
is always guaranteed to be supported if using Vulkan 1.2+ or the extension is exposed.
VK_EXT_shader_image_atomic_int64
This extension allows for 64-bit int
atomic operations for images and sparse images. If the Int64Atomics
and Int64ImageEXT
SPIR-V capability is declared, all supported SPIR-V operations can be used with 64-bit int
on images.
Image vs Sparse Image support
This extension exposes both a shaderImageInt64Atomics
and sparseImageInt64Atomics
feature bit. The sparseImage*
feature is an additional feature bit and is only allowed to be used if the shaderImage*
bit is enabled as well. Some hardware has a hard time doing atomics on images with sparse resources, therefor the atomic feature is split up to allow sparse images as an additional feature an implementation can expose.
VK_EXT_shader_atomic_float
This extension allows for float
atomic operations for buffers, shared memory, images, and sparse images. Only a subset of operations is supported for float
types with this extension.
The extension lists many feature bits. One way to group them is by *Float*Atomics
and *Float*AtomicAdd
:
-
The
*Float*Atomics
features allow for the use ofOpAtomicStore
,OpAtomicLoad
, andOpAtomicExchange
forfloat
types.-
Note the
OpAtomicCompareExchange
“exchange” operation is not included as the SPIR-V spec only allowsint
types for it.
-
-
The
*Float*AtomicAdd
features allow the use of the two extended SPIR-V operationsAtomicFloat32AddEXT
andAtomicFloat64AddEXT
.
From here the rest of the permutations of features fall into the grouping of 32-bit float
support:
-
shaderBufferFloat32*
- buffers -
shaderSharedFloat32*
- shared memory -
shaderImageFloat32*
- images -
sparseImageFloat32*
- sparse images
and 64-bit float
support:
-
shaderBufferFloat64*
- buffers -
shaderSharedFloat64*
- shared memory
OpenGLES OES_shader_image_atomic allowed the use of atomics on |
VK_EXT_shader_atomic_float2
This extension adds 2 additional sets of features missing in VK_EXT_shader_atomic_float
First, it adds 16-bit floats
for both buffers and shared memory in the same fashion as found above for VK_EXT_shader_atomic_float
.
-
shaderBufferFloat16*
- buffers -
shaderSharedFloat16*
- shared memory
Second, it adds float
support for min
and max
atomic operations (OpAtomicFMinEXT
and OpAtomicFMaxEXT
)
For 16-bit float
support (with AtomicFloat16MinMaxEXT
capability):
-
shaderBufferFloat16AtomicMinMax
- buffers -
shaderSharedFloat16AtomicMinMax
- shared memory
For 32-bit float
support (with AtomicFloat32MinMaxEXT
capability):
-
shaderBufferFloat32AtomicMinMax
- buffers -
shaderSharedFloat32AtomicMinMax
- shared memory -
shaderImageFloat32AtomicMinMax
- images -
sparseImageFloat32AtomicMinMax
- sparse images
For 64-bit float
support (with AtomicFloat64MinMaxEXT
capability):
-
shaderBufferFloat64AtomicMinMax
- buffers -
shaderSharedFloat64AtomicMinMax
- shared memory