原子操作的类型变体
想要更好地理解各类相关扩展,首先需要了解 Vulkan 提供的不同原子操作类型,主要分为以下维度:
数据类型
floatint
位宽
16 bit32 bit64 bit
操作类型
- 加载(loads)
- 存储(stores)
- 交换(exchange)
- 加法(add)
- 最小值(min)
- 最大值(max)
- 其他操作(etc.)
存储类
StorageBuffer或Uniform(缓冲区)Workgroup(共享内存)Image(普通图像或稀疏图像)
基础支持
在 Vulkan 1.0 且未启用任何扩展的情况下,应用程序仅可使用32 位整型(32-bit int) 进行原子操作,该类型支持所有受支持的 SPIR-V 原子操作(加载、存储、交换等)。SPIR-V 中部分原子操作受Kernel能力限制,目前在 Vulkan 中暂不被允许使用。
原子计数器
尽管 GLSL 和 SPIR-V 均支持原子计数器的使用,但 Vulkan 并未开放使用AtomicCounter存储类所需的AtomicStorage SPIR-V 能力。官方建议应用程序可通过对数值1调用OpAtomicIAdd和OpAtomicISub指令,实现原子计数器的同等效果。
扩展原子操作支持
目前可扩展原子操作支持的相关扩展如下:
下文将对各扩展进行详细说明。
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
此扩展允许在普通图像 和稀疏图像 中执行64 位整型(64-bit int) 原子操作。若同时声明了Int64Atomics和Int64ImageEXT SPIR-V 能力,所有受支持的 SPIR-V 操作均可用于图像的 64 位整型原子操作。
普通图像与稀疏图像的支持差异
该扩展暴露了shaderImageInt64Atomics和sparseImageInt64Atomics两个特性位,其中sparseImage*系列特性位为附加特性位,仅在shaderImage*特性位启用的前提下才可使用。部分硬件对稀疏资源图像执行原子操作的效率较低,因此官方将该原子特性拆分,使稀疏图像的原子操作成为实现可选择性暴露的附加特性。
VK_EXT_shader_atomic_float
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| | SPV_EXT_shader_atomic_float_add GLSL_EXT_shader_atomic_float |
此扩展允许在缓冲区、共享内存、普通图像和稀疏图像 中执行浮点型(float) 原子操作,仅该扩展为浮点类型开放了子集原子操作的支持。
该扩展定义了多个特性位,可按照*Float*Atomics和*Float*AtomicAdd两类进行分组:
*Float*Atomics系列特性:允许对浮点类型执行OpAtomicStore、OpAtomicLoad和OpAtomicExchange操作。注意:OpAtomicCompareExchange(比较交换)操作未被包含在内,因 SPIR-V 规范仅允许该操作作用于整型。*Float*AtomicAdd系列特性:允许使用两个扩展的 SPIR-V 操作指令 ------AtomicFloat32AddEXT和AtomicFloat64AddEXT。
其余特性位可按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) 原子操作支持,对应指令为OpAtomicFMinEXT和OpAtomicFMaxEXT,不同位宽的支持特性位如下:
16 位浮点(需声明AtomicFloat16MinMaxEXT能力)
shaderBufferFloat16AtomicMinMax- 缓冲区shaderSharedFloat16AtomicMinMax- 共享内存
32 位浮点(需声明AtomicFloat32MinMaxEXT能力)
shaderBufferFloat32AtomicMinMax- 缓冲区shaderSharedFloat32AtomicMinMax- 共享内存shaderImageFloat32AtomicMinMax- 普通图像sparseImageFloat32AtomicMinMax- 稀疏图像
64 位浮点(需声明AtomicFloat64MinMaxEXT能力)
shaderBufferFloat64AtomicMinMax- 缓冲区shaderSharedFloat64AtomicMinMax- 共享内存