鲁棒性
健壮性
健壮性的意义
当 Vulkan 应用尝试访问(加载、存储或执行原子操作)它无权访问的内存时,驱动实现必须用某种方式做出反应。在没有健壮性的情况下,它是未定义的行为,甚至会导致终止程序。如果为访问的内存启用了健壮特性,则驱动实现必须按照 spec 定义的方式运行。
适用场景
某些 Vulkan 应用会要求运行的着色器代码,无法保证内存访问不越界,这些应用就需要稳健性功能。
启用健壮性可 能会降低运行性能,应用程序应仔细考虑启用健壮性的影响性。
Vulkan 核心功能的要求
所有 Vulkan 驱动实现都需要支持robustBufferAccess
特性。规范描述了什么是访问越界,以及应该如何处理。一个例子是访问vec4(x,y,z,w)
其中w
的值是越界的, spec 允许驱动实现决定x
,y
,z
是否也被视为越界。
如果在绑定后进行更新描述符(Vulkan 1.2 的核心内容VK_EXT_descriptor_indexing
),一定要检查robustBufferAccessUpdateAfterBind是否支持 ,它表明驱动实现是否可以同时支持robustBufferAccess
以及在绑定后更新描述符。
robustBufferAccess
功能有一些限制,它只涵盖了缓冲区,不涵盖图像。它允许越界写入以及原子修改正被访问的缓冲区数据。如果需要更稳健性的功能,请阅读 VK_EXT_robustness2。
当图像越界时,核心 Vulkan 功能 可以保证 存储和原子修改对正被访问的内存没有影响。
VK_EXT_image_robustness
robustImageAccess
VK_EXT_image_robustness 中的 robustImageAccess 功能支持对访问的图像视图尺寸进行越界检查。如果存在越界访问,将返回 (0, 0, 0, 0)
或(0, 0, 0, 1)
。
robustImageAccess
功能不保证访问无效的 LOD ,它是未定义的行为。
VK_EXT_robustness2
某些应用程序(例如从 D3D12 移植的应用程序)需要比robustBufferAccess
和robustImageAccess
更严格的保证,VK_EXT_robustness2 扩展通过公开 3 个新的健壮性功能来增强这一点。对于某些驱动实现来说,这些额外的保证可能会降低性能。建议不需要额外健壮性的应用尽可能使用robustBufferAccess
和robustImageAccess
。
robustBufferAccess2
robustBufferAccess2 功能可以看作是robustBufferAccess
的超集。
启用该功能后,它会阻止所有越界的写入和原子修改缓冲区对应的内存。robustBufferAccess2
功能还规定了越界访问时各种类型的返回值,详细内容将规范描述。
从 VkPhysicalDeviceRobustness2PropertiesEXT 查询robustUniformBufferAccessSizeAlignment
和robustStorageBufferAccessSizeAlignment
非常重要,因为缓冲区的对齐方式在不同驱动实现间有所不同。
robustImageAccess2
robustImageAccess2 功能可以看作是robustImageAccess
的超集。它针图像视图的越界检查,对返回值有更严格的要求。
如果robustImageAccess2
检查出越界, R
、RG
或 RGB
格式将返回(0, 0, 0, 1)
, RGBA 格式(如VK_FORMAT_R8G8B8A8_UNORM
),将返回(0, 0, 0, 0)
。
启用robustImageAccess2
后,访问超出范围的图像 LOD 将被视为越界。
nullDescriptor
如果未启用 nullDescriptor 功能,在更新VkDescriptorSet
时,支持它的所有资源都必须为非null,即使着色器不使用该描述符也是一样。此功能允许描述符为 null 资源或视图,读取 null 描述符返回零值,原子读写null描述符的操作被丢弃。
nullDescriptor
功能还允许访问vkCmdBindVertexBuffers::pBuffers
为 null的顶点输入。
VK_EXT_pipeline_robustness
由于某些驱动实现的健壮性可能会以牺牲性能为代价,因此添加了 VK_EXT_pipeline_robustness 扩展,以允许应用只在需要时请求健壮性。
在VkPipeline
创建时,可以传递一个或多个VkPipelineRobustnessCreateInfoEXT
结构,以指定对缓冲区、图像和顶点输入资源的访问所需的健壮性,无论是针对整个管线还是每个管线阶段。
此扩展还提供了VkPhysicalDevicePipelineRobustnessPropertiesEXT
,来查询驱动实现,在未启用健壮性特性时的默认行为。