跳到主要内容

原子操作

本章旨在帮助用户了解 Vulkan 中原子操作的各种功能。

原子操作的变体

为了更好地理解不同的扩展,首先重要的是要了解各种公开的原子类型。

  • 类型
    • float
    • int
  • 宽度
    • 16 bit
    • 32 bit
    • 64 bit
  • 操作
    • loads
    • stores
    • exchange
    • add
    • min
    • min
  • 存储类
    • StorageBufferUniformBuffer
    • Workgroup(共享内存)
    • Image(图像或稀疏图像)

基线支持情况

在 Vulkan 1.0 且没有扩展的情况下,应用程序可以使用原子的32-bit int操作,这可用于所有的 SPIR-V 操作(load、 store、 exchange等)。SPIR-V 包含一些原子操作,这些操作由Kernel能力支持,目前在 Vulkan 中不允许使用。

原子计数器

虽然 GLSL 和 SPIR-V 都支持使用原子计数器,但 Vulkan 并未公开AtomicCounter存储类。应用程序可以对1使用OpAtomicIAddOpAtomicISub 来实现相同结果。

支持Atomic 的扩展

支持原子操作的扩展包含:

下面将更详细地解释每个扩展。

VK_KHR_shader_atomic_int64

提示

GLSL - GL_EXT_shader_atomic_int64在 Vulkan 1.2 中提升为核心扩展。

此扩展允许对缓冲区共享内存执行64-bit int的原子操作。如果声明了Int64Atomics SPIR-V 功能集,则所有 SPIR-V 操作都可以与64-bit int 一起使用。

shaderBufferInt64AtomicsshaderSharedInt64Atomics这两个功能位用于查询原子支持哪些64-bit int存储类:

  • shaderBufferInt64Atomics-缓冲区
  • shaderSharedInt64Atomics- 共享内存

如果使用 Vulkan 1.2+ 或公开了扩展,则shaderBufferInt64Atomics就是支持的。

VK_EXT_shader_image_atomic_int64

此扩展允许对图像稀疏图像进行64-bit intd的原子操作。如果声明了 Int64AtomicsInt64ImageEXT SPIR-V 功能集,则可以在64-bit int图像上使用所有 SPIR-V 操作。

图像与稀疏图像的支持

此扩展公开了shaderImageInt64AtomicssparseImageInt64Atomics功能位。sparseImage*特性功能只有在启用shaderImage*位的情况下才允许使用。一些硬件很难对资源稀疏的图像进行原子运算,因此 atomic 功能被拆分,以允许稀疏图像作为驱动实现可以公开的附加功能。

VK_EXT_shader_atomic_float

此扩展允许对缓冲区共享内存、图像和稀疏图像执行float原子操作,但只有部分操作支持原子float类型。

该扩展列出了许多功能位,可以通过*Float*Atomics*Float*AtomicAdd对它们进行分组 :

  • *Float*Atomics功能允许对float类型使用OpAtomicStoreOpAtomicLoadOpAtomicExchange
    • 请注意,OpAtomicCompareExchange“交换”操作不包括在内,因为该操作 SPIR-V 只支持int类型。
  • *Float*AtomicAdd功能允许使用两个 SPIR-V 扩展操作:AtomicFloat32AddEXTAtomicFloat64AddEXT

其余的是支持32-bit float的功能:

  • shaderBufferFloat32*-缓冲区
  • shaderSharedFloat32*- 共享内存
  • shaderImageFloat32*-图像
  • sparseImageFloat32*- 稀疏图像

和支持64-bit float的功能:

  • shaderBufferFloat64*-缓冲区
  • shaderSharedFloat64*- 共享内存
提示

OpenGLES的 OES_shader_image_atomic 允许imageAtomicExchange使用原子的r32f。对于移植的shader,vulkan应用程序需要检查是否支持shaderImageFloat32Atomics,以便能够在 Vulkan 中实现相当的功能。

VK_EXT_shader_atomic_float2

此扩展在VK_EXT_shader_atomic_float的基础上添加了 2 个功能:

首先,它为 buffer共享内存添加了16-bit floats功能 。

  • shaderBufferFloat16*-缓冲区
  • shaderSharedFloat16*- 共享内存

其次,它支持了floatminmax原子操作 ( OpAtomicFMinEXTOpAtomicFMaxEXT),

支持16-bit floatAtomicFloat16MinMaxEXT功能):

  • shaderBufferFloat16AtomicMinMax-缓冲区
  • shaderSharedFloat16AtomicMinMax- 共享内存

支持32-bit floatAtomicFloat32MinMaxEXT功能):

  • shaderBufferFloat32AtomicMinMax-缓冲区
  • shaderSharedFloat32AtomicMinMax- 共享内存
  • shaderImageFloat32AtomicMinMax-图像
  • sparseImageFloat32AtomicMinMax- 稀疏图像

支持64-bit floatAtomicFloat64MinMaxEXT功能):

  • shaderBufferFloat64AtomicMinMax-缓冲区
  • shaderSharedFloat64AtomicMinMax- 共享内存