原子操作
本章的目的是帮助用户理解 Vulkan 为原子操作公开的各种特性。
原子操作的变体
为了更好地理解不同的扩展,首先了解公开的各种类型的原子操作非常重要。
-
类型
-
float
-
int
-
-
宽度
-
16 位
-
32 位
-
64 位
-
-
操作
-
加载
-
存储
-
交换
-
加
-
最小值
-
最大值
-
等等。
-
-
存储类
-
StorageBuffer
或Uniform
(缓冲区) -
Workgroup
(共享内存) -
Image
(图像或稀疏图像)
-
基线支持
在 Vulkan 1.0 中,没有扩展的情况下,应用程序可以使用 32 位 int
类型进行原子操作。这可以用于所有支持的 SPIR-V 操作(加载、存储、交换等)。SPIR-V 包含一些受 Kernel
功能保护的原子操作,目前在 Vulkan 中不允许使用。
原子计数器
虽然 GLSL 和 SPIR-V 都支持使用原子计数器,但 Vulkan 不公开使用 AtomicCounter
存储类所需的 AtomicStorage
SPIR-V 功能。最终决定应用程序只需使用 OpAtomicIAdd
和 OpAtomicISub
,值为 1
即可达到相同的效果。
VK_KHR_shader_atomic_int64
在 Vulkan 1.2 中升级为核心功能 |
此扩展允许对 缓冲区 和 共享内存 进行 64 位 int
原子操作。如果声明了 Int64Atomics
SPIR-V 功能,则所有支持的 SPIR-V 操作都可以与 64 位 int
一起使用。
两个特性位 shaderBufferInt64Atomics
和 shaderSharedInt64Atomics
用于查询支持 64 位 int
原子操作的存储类。
-
shaderBufferInt64Atomics
- 缓冲区 -
shaderSharedInt64Atomics
- 共享内存
如果使用 Vulkan 1.2+ 或公开了该扩展,则始终保证支持 shaderBufferInt64Atomics
。
VK_EXT_shader_image_atomic_int64
此扩展允许对 图像 和 稀疏图像 进行 64 位 int
原子操作。如果声明了 Int64Atomics
和 Int64ImageEXT
SPIR-V 功能,则所有支持的 SPIR-V 操作都可以在图像上使用 64 位 int
。
图像与稀疏图像支持
此扩展公开了 shaderImageInt64Atomics
和 sparseImageInt64Atomics
特性位。sparseImage*
特性是一个附加特性位,只有在启用了 shaderImage*
位时才允许使用。有些硬件很难对带有 稀疏资源 的图像进行原子操作,因此将原子特性分开,以允许 稀疏图像 作为实现可以公开的附加特性。
VK_EXT_shader_atomic_float
此扩展允许对 缓冲区、共享内存、图像 和 稀疏图像 进行 float
原子操作。此扩展仅支持 float
类型的一小部分操作。
该扩展列出了许多特性位。一种对其进行分组的方法是按照 *Float*Atomics
和 *Float*AtomicAdd
分组
-
*Float*Atomics
特性允许对float
类型使用OpAtomicStore
、OpAtomicLoad
和OpAtomicExchange
。-
请注意,
OpAtomicCompareExchange
“交换” 操作不包括在内,因为 SPIR-V 规范仅允许其使用int
类型。
-
-
*Float*AtomicAdd
特性允许使用两个扩展的 SPIR-V 操作AtomicFloat32AddEXT
和AtomicFloat64AddEXT
。
从这里开始,其余的特性排列可以分为 32 位 float
支持组
-
shaderBufferFloat32*
- 缓冲区 -
shaderSharedFloat32*
- 共享内存 -
shaderImageFloat32*
- 图像 -
sparseImageFloat32*
- 稀疏图像
和 64 位 float
支持
-
shaderBufferFloat64*
- 缓冲区 -
shaderSharedFloat64*
- 共享内存
OpenGLES OES_shader_image_atomic 允许对 |
VK_EXT_shader_atomic_float2
此扩展添加了 VK_EXT_shader_atomic_float
中缺失的 2 个额外功能集。
首先,它为缓冲区和共享内存添加了 16 位浮点数
,其方式与上面 VK_EXT_shader_atomic_float
中的方式相同。
-
shaderBufferFloat16*
- 缓冲区 -
shaderSharedFloat16*
- 共享内存
其次,它为 min
和 max
原子操作 (OpAtomicFMinEXT
和 OpAtomicFMaxEXT
) 添加了 float
支持。
对于 16 位浮点数
支持(具有 AtomicFloat16MinMaxEXT
功能):
-
shaderBufferFloat16AtomicMinMax
- 缓冲区 -
shaderSharedFloat16AtomicMinMax
- 共享内存
对于 32 位浮点数
支持(具有 AtomicFloat32MinMaxEXT
功能):
-
shaderBufferFloat32AtomicMinMax
- 缓冲区 -
shaderSharedFloat32AtomicMinMax
- 共享内存 -
shaderImageFloat32AtomicMinMax
- 图像 -
sparseImageFloat32AtomicMinMax
- 稀疏图像
对于 64 位浮点数
支持(具有 AtomicFloat64MinMaxEXT
功能):
-
shaderBufferFloat64AtomicMinMax
- 缓冲区 -
shaderSharedFloat64AtomicMinMax
- 共享内存