原子操作
本章的目的是帮助用户理解 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- 共享内存