Using Vulkan -- Atomics

原子操作的类型变体

想要更好地理解各类相关扩展,首先需要了解 Vulkan 提供的不同原子操作类型,主要分为以下维度:

数据类型

  • float
  • int

位宽

  • 16 bit
  • 32 bit
  • 64 bit

操作类型

  • 加载(loads)
  • 存储(stores)
  • 交换(exchange)
  • 加法(add)
  • 最小值(min)
  • 最大值(max)
  • 其他操作(etc.)

存储类

  • StorageBufferUniform(缓冲区)
  • Workgroup(共享内存)
  • Image(普通图像或稀疏图像)

基础支持

在 Vulkan 1.0 且未启用任何扩展的情况下,应用程序仅可使用32 位整型(32-bit int) 进行原子操作,该类型支持所有受支持的 SPIR-V 原子操作(加载、存储、交换等)。SPIR-V 中部分原子操作受Kernel能力限制,目前在 Vulkan 中暂不被允许使用。

原子计数器

尽管 GLSL 和 SPIR-V 均支持原子计数器的使用,但 Vulkan 并未开放使用AtomicCounter存储类所需的AtomicStorage SPIR-V 能力。官方建议应用程序可通过对数值1调用OpAtomicIAddOpAtomicISub指令,实现原子计数器的同等效果。

扩展原子操作支持

目前可扩展原子操作支持的相关扩展如下:

下文将对各扩展进行详细说明。

VK_KHR_shader_atomic_int64

|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| | Promoted to core in Vulkan 1.2 GLSL - GL_EXT_shader_atomic_int64 |

此扩展允许在缓冲区共享内存 中执行64 位整型(64-bit int) 原子操作。若声明了Int64Atomics SPIR-V 能力,所有受支持的 SPIR-V 操作均可用于 64 位整型。

可通过两个特性位查询 64 位整型原子操作支持的存储类:

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

若使用 Vulkan 1.2 及以上版本,或设备暴露了该扩展,则必然支持 shaderBufferInt64Atomics特性。

VK_EXT_shader_image_atomic_int64

SPV_EXT_shader_image_int64

GLSL_EXT_shader_image_int64

此扩展允许在普通图像稀疏图像 中执行64 位整型(64-bit int) 原子操作。若同时声明了Int64AtomicsInt64ImageEXT SPIR-V 能力,所有受支持的 SPIR-V 操作均可用于图像的 64 位整型原子操作。

普通图像与稀疏图像的支持差异

该扩展暴露了shaderImageInt64AtomicssparseImageInt64Atomics两个特性位,其中sparseImage*系列特性位为附加特性位,仅在shaderImage*特性位启用的前提下才可使用。部分硬件对稀疏资源图像执行原子操作的效率较低,因此官方将该原子特性拆分,使稀疏图像的原子操作成为实现可选择性暴露的附加特性。

VK_EXT_shader_atomic_float

|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| | SPV_EXT_shader_atomic_float_add GLSL_EXT_shader_atomic_float |

此扩展允许在缓冲区、共享内存、普通图像和稀疏图像 中执行浮点型(float) 原子操作,仅该扩展为浮点类型开放了子集原子操作的支持。

该扩展定义了多个特性位,可按照*Float*Atomics*Float*AtomicAdd两类进行分组:

  1. *Float*Atomics系列特性:允许对浮点类型执行OpAtomicStoreOpAtomicLoadOpAtomicExchange操作。注意:OpAtomicCompareExchange(比较交换)操作未被包含在内,因 SPIR-V 规范仅允许该操作作用于整型。
  2. *Float*AtomicAdd系列特性:允许使用两个扩展的 SPIR-V 操作指令 ------AtomicFloat32AddEXTAtomicFloat64AddEXT

其余特性位可按32 位浮点64 位浮点的支持范围进一步划分:

32 位浮点(32-bit float)支持

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

64 位浮点(64-bit float)支持

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

OpenGLES 的 OES_shader_image_atomic 扩展允许在r32f格式图像上通过imageAtomicExchange执行原子操作。若要将相关代码移植到 Vulkan,应用程序需检查设备是否支持shaderImageFloat32Atomics特性,以实现同等功能。

VK_EXT_shader_atomic_float2

|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| | SPV_EXT_shader_atomic_float_min_max SPV_EXT_shader_atomic_float16_add GLSL_EXT_shader_atomic_float |

此扩展为VK_EXT_shader_atomic_float补充了两类此前缺失的特性支持:

第一类:16 位浮点型原子操作支持

缓冲区共享内存 中新增16 位浮点(16-bit floats) 原子操作支持,使用方式与VK_EXT_shader_atomic_float中的浮点操作一致:

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

第二类:浮点型的最小 / 最大值原子操作支持

新增浮点类型的最小值(min)最大值(max) 原子操作支持,对应指令为OpAtomicFMinEXTOpAtomicFMaxEXT,不同位宽的支持特性位如下:

16 位浮点(需声明AtomicFloat16MinMaxEXT能力)
  • shaderBufferFloat16AtomicMinMax - 缓冲区
  • shaderSharedFloat16AtomicMinMax - 共享内存
32 位浮点(需声明AtomicFloat32MinMaxEXT能力)
  • shaderBufferFloat32AtomicMinMax - 缓冲区
  • shaderSharedFloat32AtomicMinMax - 共享内存
  • shaderImageFloat32AtomicMinMax - 普通图像
  • sparseImageFloat32AtomicMinMax - 稀疏图像
64 位浮点(需声明AtomicFloat64MinMaxEXT能力)
  • shaderBufferFloat64AtomicMinMax - 缓冲区
  • shaderSharedFloat64AtomicMinMax - 共享内存
相关推荐
千里马-horse10 天前
Using Vulkan -- Mapping Data to Shaders -- Storage Image and Texel Buffers
着色器·vulkan·图像存储·纹理元素缓存区
千里马-horse13 天前
Linux 安装Vulkan, 在终端输入:vulkaninfo
vulkan·vulkaninfo
Icys22 天前
Vulkan Cooperative Matrix 简明教程
并行计算·vulkan
千里马-horse1 个月前
Building a Simple Engine -- Advanced Topics--Planar reflections
rendering·vulkan·平面反射
千里马-horse1 个月前
Building a Simple Engine -- Advanced Topics -- Mipmaps & LOD
rendering·vulkan·lod·mipmaps
千里马-horse2 个月前
Building a Simple Engine -- Advanced Topics -- Forward+ rendering
rendering·vulkan·forward+
千里马-horse2 个月前
Building a Simple Engine -- Mobile Development -- Conclusion
pipeline·shader·rendering·vulkan
千里马-horse2 个月前
Building a Simple Engine -- Mobile Development -- Platform considerations
android·ios·rendering·vulkan
千里马-horse2 个月前
Building a Simple Engine -- Mobile Development -- Performance optimizations
shader·内存优化·rendering·纹理优化·vulkan·压缩格式