稀疏资源

资源内存关联 中所述,Vulkan 中的 VkBufferVkImage 资源必须完整且连续地绑定到单个 VkDeviceMemory 对象。 此绑定必须在资源使用前完成,并且该绑定在资源的生命周期内是不可变的。

稀疏资源放宽了这些限制并提供了以下附加功能

  • 稀疏资源可以不连续地绑定到一个或多个 VkDeviceMemory 分配。

  • 稀疏资源可以在资源的生命周期内重新绑定到不同的内存分配。

  • 稀疏资源可以生成描述符,并与内存绑定命令正交使用。

稀疏资源特性

稀疏资源有几个特性必须在资源创建时显式启用。 这些特性通过在 VkImageCreateInfoVkBufferCreateInfoflags 参数中包含位来启用。 每个特性还在 VkPhysicalDeviceFeatures 中指定了一个或多个相应的特性启用。

  • sparseBinding 特性是基础,并提供以下功能

    • 资源可以在某些定义的(稀疏块)粒度上绑定。

    • 在实际访问的区域无关的情况下,整个资源必须在使用前绑定到内存。

    • 未定义图像区域到内存偏移的特定映射,即每个纹素在内存中对应的位置取决于实现。

    • 稀疏缓冲区具有缓冲区范围到内存范围的明确定义的映射,其中缓冲区范围内绑定到单个连续内存范围的偏移量对应于该内存范围内的相同偏移量。

    • 通过 VK_IMAGE_CREATE_SPARSE_BINDING_BITVK_BUFFER_CREATE_SPARSE_BINDING_BIT 位请求。

    • 使用 VK_IMAGE_CREATE_SPARSE_BINDING_BIT (但不是 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)创建的稀疏图像支持非稀疏用法支持的所有格式,并支持 VK_IMAGE_TILING_OPTIMALVK_IMAGE_TILING_LINEAR 平铺。

  • 稀疏驻留建立在 sparseBinding 特性之上(并需要该特性)。 它包括以下功能

    • 资源不必在使用前完全绑定到设备上的内存。

    • 图像具有规定的稀疏图像块布局,允许图像的特定矩形区域绑定到内存分配中的特定偏移量。

    • 对资源未绑定区域的访问一致性由 VkPhysicalDeviceSparseProperties::residencyNonResidentStrict 的存在或不存在来定义。 如果此属性存在,则对资源未绑定区域的访问是明确定义的,并且行为就像绑定数据填充了所有零;写入将被丢弃。 当此属性不存在时,访问被认为是安全的,但读取将返回未定义的值。

    • 通过 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BITVK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT 位请求。

    • 通过以下特性以更精细的粒度通告稀疏驻留支持

      • sparseResidencyBuffer 特性提供对使用 VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT 创建 VkBuffer 对象 的支持。

      • sparseResidencyImage2D 特性提供对使用 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 创建 2D 单采样 VkImage 对象 的支持。

      • sparseResidencyImage3D 特性提供对使用 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 创建 3D VkImage 对象 的支持。

      • sparseResidency2Samples 特性提供对使用 2 个采样和 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 创建 2D VkImage 对象 的支持。

      • sparseResidency4Samples 特性提供对使用 4 个采样和 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 创建 2D VkImage 对象 的支持。

      • sparseResidency8Samples 特性提供对使用 8 个采样和 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 创建 2D VkImage 对象 的支持。

      • sparseResidency16Samples 特性提供对使用 16 个采样和 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 创建 2D VkImage 对象 的支持。

        支持 sparseResidencyImage2D 的实现仅要求支持稀疏 2D 单采样图像。 对稀疏 3D 和 MSAA 图像的支持是可选的,并且可以通过 sparseResidencyImage3DsparseResidency2SamplessparseResidency4SamplessparseResidency8SamplessparseResidency16Samples 启用。

    • 使用 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 创建的稀疏图像支持非稀疏用法支持的所有具有 2 的幂元素大小的非压缩颜色格式。 可能还支持其他格式,并且可以通过 vkGetPhysicalDeviceSparseImageFormatProperties 查询。 不支持 VK_IMAGE_TILING_LINEAR 平铺。

  • sparseResidencyAliased 功能提供了以下能力,可以对每个资源启用:

    允许物理内存范围在同一稀疏资源中的多个位置之间或多个稀疏资源之间共享,并且每个内存位置的绑定都观察到内存内容的一致解释。

    有关更多信息,请参阅 稀疏内存别名

稀疏缓冲区和完全驻留图像

使用 VK_IMAGE_CREATE_SPARSE_BINDING_BITVK_BUFFER_CREATE_SPARSE_BINDING_BIT 位创建的 VkBufferVkImage 对象都可以被视为地址空间的线性区域。在 VkImage 的情况下,如果未使用 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,则此线性区域完全不透明,这意味着在纹素位置和内存偏移之间没有应用程序可见的映射。

除非也使用 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BITVK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,否则整个资源必须在使用前绑定到一个或多个 VkDeviceMemory 对象。

稀疏缓冲区和完全驻留图像块大小

稀疏缓冲区和完全驻留图像的稀疏块大小(以字节为单位)报告为 VkMemoryRequirements::alignmentalignment 表示稀疏资源的内存对齐要求和绑定粒度(以字节为单位)。

稀疏部分驻留缓冲区

使用 VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT 位创建的 VkBuffer 对象允许缓冲区仅部分驻留。部分驻留的 VkBuffer 对象的分配和绑定方式与仅使用 VK_BUFFER_CREATE_SPARSE_BINDING_BIT 功能的 VkBuffer 对象相同。唯一的区别是允许在设备使用期间取消绑定缓冲区的某些区域。

稀疏部分驻留图像

使用 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 位创建的 VkImage 对象允许将图像的特定矩形区域(称为稀疏图像块)绑定到特定的内存范围。这允许应用程序在图像子资源或稀疏图像块粒度上管理驻留。每个图像子资源(在 mip 尾部之外)都从稀疏块边界开始,并且其尺寸是稀疏图像块的相应尺寸的整数倍。

应用程序可以使用这些类型的图像来根据总内存消耗控制 LOD。如果内存压力成为问题,应用程序可以取消绑定并禁用图像的特定 mipmap 级别,而无需重新创建资源或修改未受影响级别的纹素数据。

应用程序可以使用此功能以“超大纹理”的方式访问图像的子区域。应用程序可以创建一个大图像,并且仅填充当前在场景中使用的图像区域。

访问未绑定区域

VkPhysicalDeviceSparseProperties 的以下成员影响实现如何处理稀疏资源的未绑定区域中的数据:

  • residencyNonResidentStrict

如果不存在此属性,则读取图像的未绑定区域将返回未定义的值。读取和写入仍然被认为是安全的,并且不会影响其他资源或图像的已填充区域。

如果存在此属性,则读取图像的未绑定区域的所有行为都将如同该区域绑定到填充了所有零的内存一样;写入将被丢弃。

在未绑定内存上执行的图像操作 可能仍然以自然的方式更改这些访问中的某些组件值,例如,在没有 alpha 组件的格式中将 alpha 值替换为 1。

示例:读取未备份的 VK_FORMAT_R8_UNORM 图像的 alpha 分量将返回 1.0f 的值。

有关检索物理设备属性的说明,请参阅物理设备枚举

Mip 尾部区域

使用 VK_IMAGE_CREATE_SPARSE_BINDING_BIT 创建的稀疏图像(也未使用 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)没有定义图像区域或图像子资源到内存偏移的特定映射,因此整个图像可以被视为线性不透明地址区域。但是,使用 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 创建的图像确实具有规定的稀疏图像块布局,因此每个图像子资源必须从稀疏块边界开始。在每个数组层中,字节大小小于稀疏块大小的 mip 级别集合被分组到一个mip 尾部区域中。

如果 VkSparseImageFormatPropertiesflags 成员中存在 VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT 标志(对于图像的 format),则任何尺寸不是稀疏图像块的相应尺寸的整数倍的 mip 级别,以及所有后续的 mip 级别,也都包含在 mip 尾部区域中。

VkPhysicalDeviceSparseProperties 的以下成员可能会影响实现如何在 mip 尾部区域中放置 mip 级别:

  • residencyAlignedMipSize

每个 mip 尾部区域都以不透明区域的形式绑定到内存(即必须使用 VkSparseImageOpaqueMemoryBindInfo 结构绑定),并且其大小可能大于或等于稀疏块大小(以字节为单位)。此大小保证是稀疏块大小(以字节为单位)的整数倍。

实现可能会选择允许将每个数组层的 mip 尾部区域独立绑定到内存,或者要求将所有数组层的 mip 尾部区域视为一个。这由 VkSparseImageMemoryRequirements::flags 中的 VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT 决定。

以下图表描述了 VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BITVK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT 如何更改内存使用情况和要求。

sparseimage
图 1. 稀疏图像

在没有 VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BITVK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT 的情况下,每个数组层都包含一个 mip 尾部区域,其中包含任何维度上小于稀疏图像块的所有 mip 级别的纹素数据。

在所有维度上都等于或大于稀疏图像块的 mip 级别可以单独绑定。允许每个级别的右边缘和底边缘具有部分使用的稀疏块。任何已绑定的部分使用稀疏块仍然必须在内存中分配其完整的稀疏块大小(以字节为单位)。

sparseimage singlemiptail
图 2. 具有单个 Mip 尾部的稀疏图像

当存在 VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT 时,所有数组层将共享一个 mip 尾部区域。

sparseimage alignedmipsize
图 3. 具有对齐 Mip 大小的稀疏图像

为了图表大小的原因,此处以 2D 数组形式呈现 mip 尾部区域。每个 mip 尾部在逻辑上都是一个稀疏块的单数组,其中纹素或压缩纹素块到稀疏块的映射取决于实现。

当存在 VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT 时,第一个包含部分使用的稀疏块的 mip 级别将开始 mip 尾部区域。此级别和所有后续级别都放置在 mip 尾部中。只有尺寸是稀疏图像块尺寸的精确倍数的第一个 N 个 mip 级别才能在稀疏块的基础上绑定和取消绑定。

sparseimage alignedmipsize singlemiptail
图 4. 具有对齐 Mip 大小和单个 Mip 尾部的稀疏图像

为了图表大小的原因,此处以 2D 数组形式呈现 mip 尾部区域。它在逻辑上是一个稀疏块的单数组,其中纹素或压缩纹素块到稀疏块的映射取决于实现。

当同时存在 VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BITVK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT 时,这两个标志的约束都有效。

标准稀疏图像块形状

标准稀疏图像块形状定义了一组标准的稀疏图像块尺寸,这些尺寸取决于图像的格式。稀疏图像块内的纹素或压缩纹素块的布局是实现相关的。所有当前定义的标准稀疏图像块形状的大小均为 64 KB。

对于块压缩格式(例如 VK_FORMAT_BC5_UNORM_BLOCK),纹素大小是压缩纹素块的大小(例如 BC5 为 128 位),因此标准稀疏图像块形状的尺寸适用于压缩纹素块。

对于块压缩格式,可以用稀疏图像块尺寸乘以压缩纹素块尺寸来计算出稀疏图像块的纹素尺寸。

表 1. 标准稀疏图像块形状(单采样)
纹素大小(位) 块形状 (2D) 块形状 (3D)

8 位

256 × 256 × 1

64 × 32 × 32

16 位

256 × 128 × 1

32 × 32 × 32

32 位

128 × 128 × 1

32 × 32 × 16

64 位

128 × 64 × 1

32 × 16 × 16

128 位

64 × 64 × 1

16 × 16 × 16

表 2. 标准稀疏图像块形状 (MSAA)
纹素大小(位) 块形状 (2X) 块形状 (4X) 块形状 (8X) 块形状 (16X)

8 位

128 × 256 × 1

128 × 128 × 1

64 × 128 × 1

64 × 64 × 1

16 位

128 × 128 × 1

128 × 64 × 1

64 × 64 × 1

64 × 32 × 1

32 位

64 × 128 × 1

64 × 64 × 1

32 × 64 × 1

32 × 32 × 1

64 位

64 × 64 × 1

64 × 32 × 1

32 × 32 × 1

32 × 16 × 1

128 位

32 × 64 × 1

32 × 32 × 1

16 × 32 × 1

16 × 16 × 1

对于 标准稀疏图像块形状(单采样)标准稀疏图像块形状 (MSAA) 表中列出的所有格式都支持标准稀疏图像块形状的实现**可以**声明以下 VkPhysicalDeviceSparseProperties

  • residencyStandard2DBlockShape

  • residencyStandard2DMultisampleBlockShape

  • residencyStandard3DBlockShape

报告这些特性并不意味着所有可能的图像类型都支持稀疏。相反,这表明,对于具有相应标准稀疏图像块形状的任何格式,相应类型的不支持自定义稀疏图像块尺寸的稀疏图像都将使用标准稀疏图像块尺寸。

自定义稀疏图像块形状

对于特定的稀疏部分驻留图像,不支持标准图像块形状的实现**可以**选择为其支持自定义稀疏图像块形状。这种自定义稀疏图像块形状的尺寸在 VkSparseImageFormatProperties::imageGranularity 中报告。与标准稀疏图像块形状一样,自定义稀疏图像块形状的字节大小将在 VkMemoryRequirements::alignment 中报告。

自定义稀疏图像块尺寸通过 vkGetPhysicalDeviceSparseImageFormatPropertiesvkGetImageSparseMemoryRequirements 报告。

对于同一图像,实现**必须**不支持标准稀疏图像块形状和自定义稀疏图像块形状。如果支持,则**必须**使用标准稀疏图像块形状。

多方面

允许部分驻留图像为图像的不同方面报告单独的稀疏属性。一个例子是深度/模板图像,其中实现将深度和模板数据分离到单独的平面中。多方面的另一个原因是允许应用程序管理与图像关联的实现私有*元数据*的内存分配。请参见下图

sparseimage multiaspect
图 5. 多方面稀疏图像

为了图表大小的原因,此处以 2D 数组形式呈现 mip 尾部区域。每个 mip 尾部在逻辑上都是一个稀疏块的单数组,其中纹素或压缩纹素块到稀疏块的映射取决于实现。

在上图中,深度、模板和元数据方面都具有唯一的稀疏属性。每个纹素的模板数据大小是深度数据的 ¼,因此模板稀疏块包含 4 × 纹素的数量。所有方面的稀疏块大小(以字节为单位)是相同的,并由 VkMemoryRequirements::alignment 定义。

元数据

图像的元数据方面具有以下约束

  • 所有元数据都在元数据方面的 mip 尾部区域中报告。

  • 所有元数据**必须**在设备使用稀疏图像之前绑定。

稀疏内存别名

默认情况下,稀疏资源具有与非稀疏资源相同的别名规则。有关更多信息,请参见 内存别名

启用了 sparseResidencyAliased 特性的 VkDevice 对象可以使用 VK_BUFFER_CREATE_SPARSE_ALIASED_BITVK_IMAGE_CREATE_SPARSE_ALIASED_BIT 标志进行资源创建。这些标志允许资源以*数据一致*的方式访问绑定到一个或多个稀疏资源内的多个位置的物理内存。这意味着从多个别名位置读取物理内存将返回相同的值。

当对别名物理内存执行写入操作时,**必须**小心。**必须**使用内存依赖项将对一个别名的写入操作与对另一个别名的读取或写入操作分开。对未正确保护以防止访问不同别名的别名内存的写入操作,对于所有对别名内存的访问都将产生**未定义**的结果。

希望使用数据一致的稀疏内存别名的应用程序**必须**遵守以下准则

  • 所有绑定到别名物理内存的稀疏资源**必须**使用 VK_BUFFER_CREATE_SPARSE_ALIASED_BIT / VK_IMAGE_CREATE_SPARSE_ALIASED_BIT 标志创建。

  • 所有访问别名物理内存的资源**必须**以相同的方式解释内存。这意味着以下几点

    • 缓冲区和图像**不能**以数据一致的方式别名同一物理内存。物理内存范围**必须**由缓冲区独占使用,或者由图像独占使用,以保证数据一致性。

    • 稀疏图像 mip 尾部区域中的内存**不能**以数据一致的方式访问别名内存。

    • 别名同一物理内存的稀疏图像**必须**具有兼容的格式,并使用相同的稀疏图像块形状,以便以数据一致的方式访问别名内存。

未能遵循上述任何准则将需要应用程序遵守普通的、非稀疏资源 别名规则。在这种情况下,内存**不能**以数据一致的方式访问。

启用稀疏资源内存别名可能是一种降低物理内存使用的方法,但它可能会降低某些实现上的性能。应用程序开发人员可以在其目标硬件上进行测试,并权衡内存/性能之间的取舍。

稀疏资源 API

与稀疏资源相关的 API 分为以下几类

物理设备特性

一些与稀疏资源相关的特性在 VkPhysicalDeviceFeatures 中报告和启用。这些特性必须VkDevice 对象上支持和启用,应用程序才能使用它们。有关如何获取和设置启用的设备特性以及这些特性的更详细解释,请参阅物理设备特性

稀疏物理设备特性

  • sparseBinding: 支持创建带有 VK_BUFFER_CREATE_SPARSE_BINDING_BITVK_IMAGE_CREATE_SPARSE_BINDING_BIT 标志的 VkBufferVkImage 对象。

  • sparseResidencyBuffer: 支持创建带有 VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT 标志的 VkBuffer 对象。

  • sparseResidencyImage2D: 支持创建带有 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 的 2D 单采样 VkImage 对象。

  • sparseResidencyImage3D: 支持创建带有 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 的 3D VkImage 对象。

  • sparseResidency2Samples: 支持创建带有 2 个采样和 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 的 2D VkImage 对象。

  • sparseResidency4Samples: 支持创建带有 4 个采样和 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 的 2D VkImage 对象。

  • sparseResidency8Samples: 支持创建带有 8 个采样和 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 的 2D VkImage 对象。

  • sparseResidency16Samples: 支持创建带有 16 个采样和 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 的 2D VkImage 对象。

  • sparseResidencyAliased: 支持创建带有 VK_BUFFER_CREATE_SPARSE_ALIASED_BITVK_IMAGE_CREATE_SPARSE_ALIASED_BIT 标志的 VkBufferVkImage 对象。

物理设备稀疏属性

某些实现的功能无法禁用,并会进行报告,以允许应用程序相应地更改其稀疏资源的使用。这些只读功能在 VkPhysicalDeviceProperties::sparseProperties 成员中报告,它是一个 VkPhysicalDeviceSparseProperties 结构。

VkPhysicalDeviceSparseProperties 结构定义为

// Provided by VK_VERSION_1_0
typedef struct VkPhysicalDeviceSparseProperties {
    VkBool32    residencyStandard2DBlockShape;
    VkBool32    residencyStandard2DMultisampleBlockShape;
    VkBool32    residencyStandard3DBlockShape;
    VkBool32    residencyAlignedMipSize;
    VkBool32    residencyNonResidentStrict;
} VkPhysicalDeviceSparseProperties;
  • 如果物理设备将使用标准稀疏图像块形状(基于图像格式)访问所有单采样 2D 稀疏资源,则 residencyStandard2DBlockShapeVK_TRUE,如标准稀疏图像块形状(单采样)表中所述。如果不支持此属性,则在 VkSparseImageFormatProperties 结构的 imageGranularity 成员中为单采样 2D 图像返回的值不要求与表中列出的标准稀疏图像块尺寸匹配。

  • 如果物理设备将使用标准稀疏图像块形状(基于图像格式)访问所有多采样 2D 稀疏资源,则 residencyStandard2DMultisampleBlockShapeVK_TRUE,如标准稀疏图像块形状 (MSAA) 表中所述。如果不支持此属性,则在 VkSparseImageFormatProperties 结构的 imageGranularity 成员中为多采样 2D 图像返回的值不要求与表中列出的标准稀疏图像块尺寸匹配。

  • 如果物理设备将使用标准稀疏图像块形状(基于图像格式)访问所有 3D 稀疏资源,则 residencyStandard3DBlockShapeVK_TRUE,如标准稀疏图像块形状(单采样)表中所述。如果不支持此属性,则在 VkSparseImageFormatProperties 结构的 imageGranularity 成员中为 3D 图像返回的值不要求与表中列出的标准稀疏图像块尺寸匹配。

  • 如果具有不是稀疏图像块相应尺寸的整数倍的 mip 级别尺寸的图像可能放置在 mip 尾部,则 residencyAlignedMipSizeVK_TRUE。如果未报告此属性,则只有尺寸小于 VkSparseImageFormatProperties 结构的 imageGranularity 成员的 mip 级别才会放置在 mip 尾部。如果报告此属性,则允许实现返回 VkSparseImageFormatPropertiesflags 成员中的 VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT,表示尺寸不是稀疏图像块相应尺寸的整数倍的 mip 级别将放置在 mip 尾部。

  • residencyNonResidentStrict 指定物理设备是否可以一致地访问资源的非驻留区域。如果此属性为 VK_TRUE,则保证对资源的非驻留区域的访问返回的值就像资源填充为 0 一样;写入非驻留区域将被丢弃。

稀疏图像格式属性

鉴于稀疏图像支持的某些方面(包括稀疏图像块尺寸)可能依赖于实现,可以使用 vkGetPhysicalDeviceSparseImageFormatProperties 在创建资源之前查询稀疏图像格式属性。此命令用于检查是否支持给定的稀疏图像参数集以及稀疏图像块形状将是什么。

稀疏图像格式属性 API

VkSparseImageFormatProperties 结构定义为

// Provided by VK_VERSION_1_0
typedef struct VkSparseImageFormatProperties {
    VkImageAspectFlags          aspectMask;
    VkExtent3D                  imageGranularity;
    VkSparseImageFormatFlags    flags;
} VkSparseImageFormatProperties;
  • aspectMask 是一个位掩码 VkImageAspectFlagBits,指定属性应用于图像的哪些方面。

  • imageGranularity 是稀疏图像块在纹素或压缩纹素块中的宽度、高度和深度。

  • flagsVkSparseImageFormatFlagBits 的位掩码,指定有关稀疏资源的附加信息。

可以在 VkSparseImageFormatProperties::flags 中设置的位,指定有关稀疏资源的附加信息,包括

// Provided by VK_VERSION_1_0
typedef enum VkSparseImageFormatFlagBits {
    VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT = 0x00000001,
    VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT = 0x00000002,
    VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT = 0x00000004,
} VkSparseImageFormatFlagBits;
  • VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT 指定图像对所有数组层使用单个 mip 尾部区域。

  • VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT 指定尺寸不是稀疏图像块相应尺寸的整数倍的第一个 mip 级别开始 mip 尾部区域。

  • VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT 指定图像使用非标准的稀疏图像块尺寸,并且 imageGranularity 值与给定格式的标准稀疏图像块尺寸不匹配。

// Provided by VK_VERSION_1_0
typedef VkFlags VkSparseImageFormatFlags;

VkSparseImageFormatFlags 是一个位掩码类型,用于设置零个或多个 VkSparseImageFormatFlagBits 的掩码。

vkGetPhysicalDeviceSparseImageFormatProperties 返回一个 VkSparseImageFormatProperties 数组。每个元素描述了使用提供的图像创建参数创建的 VkImage 同时绑定的一组图像方面的属性。对于图像中的每个方面,这通常是一个元素,但是对于交错的深度/模板图像,只有一个元素描述组合的方面。

// Provided by VK_VERSION_1_0
void vkGetPhysicalDeviceSparseImageFormatProperties(
    VkPhysicalDevice                            physicalDevice,
    VkFormat                                    format,
    VkImageType                                 type,
    VkSampleCountFlagBits                       samples,
    VkImageUsageFlags                           usage,
    VkImageTiling                               tiling,
    uint32_t*                                   pPropertyCount,
    VkSparseImageFormatProperties*              pProperties);
  • physicalDevice 是从中查询稀疏图像格式属性的物理设备。

  • format 是图像格式。

  • type 是图像的维度。

  • samples 是一个 VkSampleCountFlagBits 值,指定每个纹素的采样数。

  • usage 是一个描述图像预期用途的位掩码。

  • tiling 是内存中纹素块的平铺排列。

  • pPropertyCount 是一个指向与可用或查询的稀疏格式属性数量相关的整数的指针,如下所述。

  • pProperties 要么是 NULL,要么是指向 VkSparseImageFormatProperties 结构数组的指针。

如果 pPropertiesNULL,则可用稀疏格式属性的数量将在 pPropertyCount 中返回。否则,pPropertyCount 必须 指向一个由应用程序设置为 pProperties 数组中元素数量的变量,并且在返回时,该变量将被实际写入到 pProperties 的结构数量覆盖。如果 pPropertyCount 小于可用的稀疏格式属性的数量,则最多会写入 pPropertyCount 个结构。

如果给定的参数不支持 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,则返回时 pPropertyCount 将为零,并且不会将数据写入到 pProperties

对于由实现作为单独平面实现的深度/模板图像,会返回多个方面。深度和模板数据平面各自具有唯一的 VkSparseImageFormatProperties 数据。

深度和模板数据交错到单个平面中的深度/模板图像将返回单个 VkSparseImageFormatProperties 结构,其中 aspectMask 设置为 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT

有效使用
  • VUID-vkGetPhysicalDeviceSparseImageFormatProperties-samples-01094
    samples 必须 是一个有效的 VkSampleCountFlagBits 值,该值设置在 vkGetPhysicalDeviceImageFormatProperties 返回的 VkImageFormatProperties::sampleCounts 中,其中 formattypetilingusage 与此命令中的值相等。

有效使用(隐式)
  • VUID-vkGetPhysicalDeviceSparseImageFormatProperties-physicalDevice-parameter
    physicalDevice 必须 是一个有效的 VkPhysicalDevice 句柄

  • VUID-vkGetPhysicalDeviceSparseImageFormatProperties-format-parameter
    format 必须 是一个有效的 VkFormat

  • VUID-vkGetPhysicalDeviceSparseImageFormatProperties-type-parameter
    type 必须 是一个有效的 VkImageType

  • VUID-vkGetPhysicalDeviceSparseImageFormatProperties-samples-parameter
    samples 必须 是一个有效的 VkSampleCountFlagBits

  • VUID-vkGetPhysicalDeviceSparseImageFormatProperties-usage-parameter
    usage 必须VkImageUsageFlagBits 值的有效组合

  • VUID-vkGetPhysicalDeviceSparseImageFormatProperties-usage-requiredbitmask
    usage 不能0

  • VUID-vkGetPhysicalDeviceSparseImageFormatProperties-tiling-parameter
    tiling 必须 是一个有效的 VkImageTiling

  • VUID-vkGetPhysicalDeviceSparseImageFormatProperties-pPropertyCount-parameter
    pPropertyCount 必须 是指向 uint32_t 值的有效指针

  • VUID-vkGetPhysicalDeviceSparseImageFormatProperties-pProperties-parameter
    如果 pPropertyCount 引用的值不为 0,并且 pProperties 不为 NULL,则 pProperties 必须 是指向 pPropertyCountVkSparseImageFormatProperties 结构数组的有效指针

vkGetPhysicalDeviceSparseImageFormatProperties2 返回一个 VkSparseImageFormatProperties2 数组。每个元素描述了使用提供的图像创建参数创建的 VkImage 同时绑定的一组图像方面的属性。对于图像中的每个方面,这通常是一个元素,但是对于交错的深度/模板图像,只有一个元素描述组合的方面。

// Provided by VK_VERSION_1_1
void vkGetPhysicalDeviceSparseImageFormatProperties2(
    VkPhysicalDevice                            physicalDevice,
    const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo,
    uint32_t*                                   pPropertyCount,
    VkSparseImageFormatProperties2*             pProperties);

或等效命令

// Provided by VK_KHR_get_physical_device_properties2
void vkGetPhysicalDeviceSparseImageFormatProperties2KHR(
    VkPhysicalDevice                            physicalDevice,
    const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo,
    uint32_t*                                   pPropertyCount,
    VkSparseImageFormatProperties2*             pProperties);
  • physicalDevice 是从中查询稀疏图像格式属性的物理设备。

  • pFormatInfo 是指向包含命令输入参数的 VkPhysicalDeviceSparseImageFormatInfo2 结构的指针。

  • pPropertyCount 是一个指向与可用或查询的稀疏格式属性数量相关的整数的指针,如下所述。

  • pProperties 要么是 NULL,要么是指向 VkSparseImageFormatProperties2 结构数组的指针。

vkGetPhysicalDeviceSparseImageFormatProperties2 的行为与 vkGetPhysicalDeviceSparseImageFormatProperties 相同,可以通过在其 pProperties 参数的 pNext 链中添加扩展结构来返回扩展信息。

有效使用(隐式)
  • VUID-vkGetPhysicalDeviceSparseImageFormatProperties2-physicalDevice-parameter
    physicalDevice 必须 是一个有效的 VkPhysicalDevice 句柄

  • VUID-vkGetPhysicalDeviceSparseImageFormatProperties2-pFormatInfo-parameter
    pFormatInfo 必须 是指向有效的 VkPhysicalDeviceSparseImageFormatInfo2 结构的有效指针

  • VUID-vkGetPhysicalDeviceSparseImageFormatProperties2-pPropertyCount-parameter
    pPropertyCount 必须 是指向 uint32_t 值的有效指针

  • VUID-vkGetPhysicalDeviceSparseImageFormatProperties2-pProperties-parameter
    如果 pPropertyCount 引用的值不为 0,并且 pProperties 不为 NULL,则 pProperties 必须是指向一个包含 pPropertyCountVkSparseImageFormatProperties2 结构的有效数组的指针。

VkPhysicalDeviceSparseImageFormatInfo2 结构定义如下:

// Provided by VK_VERSION_1_1
typedef struct VkPhysicalDeviceSparseImageFormatInfo2 {
    VkStructureType          sType;
    const void*              pNext;
    VkFormat                 format;
    VkImageType              type;
    VkSampleCountFlagBits    samples;
    VkImageUsageFlags        usage;
    VkImageTiling            tiling;
} VkPhysicalDeviceSparseImageFormatInfo2;

或等效于:

// Provided by VK_KHR_get_physical_device_properties2
typedef VkPhysicalDeviceSparseImageFormatInfo2 VkPhysicalDeviceSparseImageFormatInfo2KHR;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向一个扩展此结构的结构的指针。

  • format 是图像格式。

  • type 是图像的维度。

  • samples 是一个 VkSampleCountFlagBits 值,指定每个纹素的采样数。

  • usage 是一个描述图像预期用途的位掩码。

  • tiling 是内存中纹素块的平铺排列。

有效使用
  • VUID-VkPhysicalDeviceSparseImageFormatInfo2-samples-01095
    samples 必须 是一个有效的 VkSampleCountFlagBits 值,该值设置在 vkGetPhysicalDeviceImageFormatProperties 返回的 VkImageFormatProperties::sampleCounts 中,其中 formattypetilingusage 与此命令中的值相等。

有效使用(隐式)
  • VUID-VkPhysicalDeviceSparseImageFormatInfo2-sType-sType
    sType 必须VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2

  • VUID-VkPhysicalDeviceSparseImageFormatInfo2-pNext-pNext
    pNext 必须NULL

  • VUID-VkPhysicalDeviceSparseImageFormatInfo2-format-parameter
    format 必须 是一个有效的 VkFormat

  • VUID-VkPhysicalDeviceSparseImageFormatInfo2-type-parameter
    type 必须 是一个有效的 VkImageType

  • VUID-VkPhysicalDeviceSparseImageFormatInfo2-samples-parameter
    samples 必须 是一个有效的 VkSampleCountFlagBits

  • VUID-VkPhysicalDeviceSparseImageFormatInfo2-usage-parameter
    usage 必须VkImageUsageFlagBits 值的有效组合

  • VUID-VkPhysicalDeviceSparseImageFormatInfo2-usage-requiredbitmask
    usage 不能0

  • VUID-VkPhysicalDeviceSparseImageFormatInfo2-tiling-parameter
    tiling 必须 是一个有效的 VkImageTiling

VkSparseImageFormatProperties2 结构定义如下:

// Provided by VK_VERSION_1_1
typedef struct VkSparseImageFormatProperties2 {
    VkStructureType                  sType;
    void*                            pNext;
    VkSparseImageFormatProperties    properties;
} VkSparseImageFormatProperties2;

或等效于:

// Provided by VK_KHR_get_physical_device_properties2
typedef VkSparseImageFormatProperties2 VkSparseImageFormatProperties2KHR;
有效使用(隐式)
  • VUID-VkSparseImageFormatProperties2-sType-sType
    sType 必须VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2

  • VUID-VkSparseImageFormatProperties2-pNext-pNext
    pNext 必须NULL

稀疏资源创建

稀疏资源需要指定一个或多个稀疏特性标志(作为先前在 物理设备特性 部分中描述的 VkPhysicalDeviceFeatures 结构的一部分),然后在调用 vkCreateDevice 时。当启用了适当的设备特性后,可以使用 VK_BUFFER_CREATE_SPARSE_*VK_IMAGE_CREATE_SPARSE_* 标志。有关资源创建 API 的详细信息,请参阅 vkCreateBuffervkCreateImage

指定 VK_BUFFER_CREATE_SPARSE_RESIDENCY_BITVK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 分别需要指定 VK_BUFFER_CREATE_SPARSE_BINDING_BITVK_IMAGE_CREATE_SPARSE_BINDING_BIT。这意味着资源必须使用适当的 *_SPARSE_BINDING_BIT 创建,以便与稀疏绑定命令(vkQueueBindSparse)一起使用。

稀疏资源内存要求

稀疏资源具有与绑定稀疏内存相关的特定内存要求。对于 VkBuffer 对象和 VkImage 对象,这些内存要求的报告方式有所不同。

缓冲区和完全驻留图像

缓冲区(完全和部分驻留)和完全驻留的图像可以仅使用来自 VkMemoryRequirements 的数据绑定到内存。对于所有稀疏资源,VkMemoryRequirements::alignment 成员指定字节绑定粒度以及 VkDeviceMemory必需对齐方式。

部分驻留图像

部分驻留图像具有不同的内存绑定方法。与缓冲区和完全驻留的图像一样,VkMemoryRequirements::alignment 字段指定图像的字节绑定粒度。

使用 vkGetImageSparseMemoryRequirements 请求 VkImage 对象的稀疏内存要求将返回一个或多个 VkSparseImageMemoryRequirements 结构的数组。每个结构描述图像的一组方面的稀疏内存要求。

稀疏图像必须使用 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 标志创建,以便检索有效的稀疏图像内存要求。

稀疏图像内存要求

VkSparseImageMemoryRequirements 结构定义如下:

// Provided by VK_VERSION_1_0
typedef struct VkSparseImageMemoryRequirements {
    VkSparseImageFormatProperties    formatProperties;
    uint32_t                         imageMipTailFirstLod;
    VkDeviceSize                     imageMipTailSize;
    VkDeviceSize                     imageMipTailOffset;
    VkDeviceSize                     imageMipTailStride;
} VkSparseImageMemoryRequirements;
  • formatProperties 是一个 VkSparseImageFormatProperties 结构,用于指定图像格式的属性。

  • imageMipTailFirstLod 是图像子资源包含在 mip 尾区域中的第一个 mip 级别。

  • imageMipTailSize 是 mip 尾区域的内存大小(以字节为单位)。如果 formatProperties.flags 包含 VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT,则这是整个 mip 尾的大小,否则这是单个数组层的 mip 尾的大小。保证此值是稀疏块大小(以字节为单位)的倍数。

  • imageMipTailOffset 是与 VkSparseImageOpaqueMemoryBindInfo 一起用于绑定 mip 尾区域的不透明内存偏移量。

  • imageMipTailStride 是每个数组层的 mip 尾之间的偏移步幅,如果 formatProperties.flags 不包含 VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT(否则该值是未定义的)。

要查询图像的稀疏内存要求,请调用:

// Provided by VK_VERSION_1_0
void vkGetImageSparseMemoryRequirements(
    VkDevice                                    device,
    VkImage                                     image,
    uint32_t*                                   pSparseMemoryRequirementCount,
    VkSparseImageMemoryRequirements*            pSparseMemoryRequirements);
  • device 是拥有该图像的逻辑设备。

  • image 是要获取内存要求的 VkImage 对象。

  • pSparseMemoryRequirementCount 是一个指向整数的指针,该整数与可用或查询的稀疏内存要求数量有关,如下所述。

  • pSparseMemoryRequirementsNULL 或指向一个 VkSparseImageMemoryRequirements 结构数组的指针。

如果 pSparseMemoryRequirementsNULL,则可用稀疏内存要求的数量将在 pSparseMemoryRequirementCount 中返回。否则,pSparseMemoryRequirementCount 必须指向应用程序设置为 pSparseMemoryRequirements 数组中元素数量的变量,并在返回时,该变量将被实际写入 pSparseMemoryRequirements 的结构数量覆盖。如果 pSparseMemoryRequirementCount 小于可用的稀疏内存要求数量,则最多将写入 pSparseMemoryRequirementCount 个结构。

如果图像不是使用 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 创建的,则 pSparseMemoryRequirementCount 将为零,并且不会写入 pSparseMemoryRequirements

实现报告 VkMemoryRequirements::size 中的值大于将所有 vkGetImageSparseMemoryRequirements 返回的 VkSparseImageMemoryRequirements 的内存大小加在一起所获得的值是合法的。当实现需要描述资源的地址范围中未使用填充时,可能会发生这种情况。

有效使用(隐式)
  • VUID-vkGetImageSparseMemoryRequirements-device-parameter
    device 必须是有效的 VkDevice 句柄

  • VUID-vkGetImageSparseMemoryRequirements-image-parameter
    image 必须是有效的 VkImage 句柄

  • VUID-vkGetImageSparseMemoryRequirements-pSparseMemoryRequirementCount-parameter
    pSparseMemoryRequirementCount 必须是指向 uint32_t 值的有效指针

  • VUID-vkGetImageSparseMemoryRequirements-pSparseMemoryRequirements-parameter
    如果 pSparseMemoryRequirementCount 引用的值不为 0,并且 pSparseMemoryRequirements 不为 NULL,则 pSparseMemoryRequirements 必须是指向 pSparseMemoryRequirementCountVkSparseImageMemoryRequirements 结构的数组的有效指针

  • VUID-vkGetImageSparseMemoryRequirements-image-parent
    image 必须已从 device 创建、分配或检索

要查询图像的稀疏内存要求,请调用:

// Provided by VK_VERSION_1_1
void vkGetImageSparseMemoryRequirements2(
    VkDevice                                    device,
    const VkImageSparseMemoryRequirementsInfo2* pInfo,
    uint32_t*                                   pSparseMemoryRequirementCount,
    VkSparseImageMemoryRequirements2*           pSparseMemoryRequirements);

或等效命令

// Provided by VK_KHR_get_memory_requirements2
void vkGetImageSparseMemoryRequirements2KHR(
    VkDevice                                    device,
    const VkImageSparseMemoryRequirementsInfo2* pInfo,
    uint32_t*                                   pSparseMemoryRequirementCount,
    VkSparseImageMemoryRequirements2*           pSparseMemoryRequirements);
  • device 是拥有该图像的逻辑设备。

  • pInfo 是指向 VkImageSparseMemoryRequirementsInfo2 结构的指针,其中包含内存需求查询所需的参数。

  • pSparseMemoryRequirementCount 是一个指向整数的指针,该整数与可用或查询的稀疏内存要求数量有关,如下所述。

  • pSparseMemoryRequirements 要么是 NULL,要么是指向 VkSparseImageMemoryRequirements2 结构数组的指针。

有效使用(隐式)
  • VUID-vkGetImageSparseMemoryRequirements2-device-parameter
    device 必须是有效的 VkDevice 句柄

  • VUID-vkGetImageSparseMemoryRequirements2-pInfo-parameter
    pInfo 必须是指向有效的 VkImageSparseMemoryRequirementsInfo2 结构的有效指针

  • VUID-vkGetImageSparseMemoryRequirements2-pSparseMemoryRequirementCount-parameter
    pSparseMemoryRequirementCount 必须是指向 uint32_t 值的有效指针

  • VUID-vkGetImageSparseMemoryRequirements2-pSparseMemoryRequirements-parameter
    如果 pSparseMemoryRequirementCount 引用的值不为 0,并且 pSparseMemoryRequirements 不为 NULL,则 pSparseMemoryRequirements 必须是指向 pSparseMemoryRequirementCountVkSparseImageMemoryRequirements2 结构的数组的有效指针

要在不创建对象的情况下确定图像资源的稀疏内存需求,请调用

// Provided by VK_VERSION_1_3
void vkGetDeviceImageSparseMemoryRequirements(
    VkDevice                                    device,
    const VkDeviceImageMemoryRequirements*      pInfo,
    uint32_t*                                   pSparseMemoryRequirementCount,
    VkSparseImageMemoryRequirements2*           pSparseMemoryRequirements);

或等效命令

// Provided by VK_KHR_maintenance4
void vkGetDeviceImageSparseMemoryRequirementsKHR(
    VkDevice                                    device,
    const VkDeviceImageMemoryRequirements*      pInfo,
    uint32_t*                                   pSparseMemoryRequirementCount,
    VkSparseImageMemoryRequirements2*           pSparseMemoryRequirements);
  • device 是计划拥有该图像的逻辑设备。

  • pInfo 是指向 VkDeviceImageMemoryRequirements 结构的指针,其中包含内存需求查询所需的参数。

  • pSparseMemoryRequirementCount 是一个指向整数的指针,该整数与可用或查询的稀疏内存要求数量有关,如下所述。

  • pSparseMemoryRequirements 要么是 NULL,要么是指向 VkSparseImageMemoryRequirements2 结构数组的指针。

有效使用(隐式)
  • VUID-vkGetDeviceImageSparseMemoryRequirements-device-parameter
    device 必须是有效的 VkDevice 句柄

  • VUID-vkGetDeviceImageSparseMemoryRequirements-pInfo-parameter
    pInfo 必须是指向有效的 VkDeviceImageMemoryRequirements 结构的有效指针

  • VUID-vkGetDeviceImageSparseMemoryRequirements-pSparseMemoryRequirementCount-parameter
    pSparseMemoryRequirementCount 必须是指向 uint32_t 值的有效指针

  • VUID-vkGetDeviceImageSparseMemoryRequirements-pSparseMemoryRequirements-parameter
    如果 pSparseMemoryRequirementCount 引用的值不为 0,并且 pSparseMemoryRequirements 不为 NULL,则 pSparseMemoryRequirements 必须是指向 pSparseMemoryRequirementCountVkSparseImageMemoryRequirements2 结构的数组的有效指针

VkImageSparseMemoryRequirementsInfo2 结构定义如下

// Provided by VK_VERSION_1_1
typedef struct VkImageSparseMemoryRequirementsInfo2 {
    VkStructureType    sType;
    const void*        pNext;
    VkImage            image;
} VkImageSparseMemoryRequirementsInfo2;

或等效于:

// Provided by VK_KHR_get_memory_requirements2
typedef VkImageSparseMemoryRequirementsInfo2 VkImageSparseMemoryRequirementsInfo2KHR;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向一个扩展此结构的结构的指针。

  • image 是要查询的图像。

有效使用(隐式)
  • VUID-VkImageSparseMemoryRequirementsInfo2-sType-sType
    sType 必须VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2

  • VUID-VkImageSparseMemoryRequirementsInfo2-pNext-pNext
    pNext 必须NULL

  • VUID-VkImageSparseMemoryRequirementsInfo2-image-parameter
    image 必须是有效的 VkImage 句柄

VkSparseImageMemoryRequirements2 结构定义如下

// Provided by VK_VERSION_1_1
typedef struct VkSparseImageMemoryRequirements2 {
    VkStructureType                    sType;
    void*                              pNext;
    VkSparseImageMemoryRequirements    memoryRequirements;
} VkSparseImageMemoryRequirements2;

或等效于:

// Provided by VK_KHR_get_memory_requirements2
typedef VkSparseImageMemoryRequirements2 VkSparseImageMemoryRequirements2KHR;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向一个扩展此结构的结构的指针。

  • memoryRequirements 是一个 VkSparseImageMemoryRequirements 结构,描述了稀疏图像的内存需求。

有效使用(隐式)
  • VUID-VkSparseImageMemoryRequirements2-sType-sType
    sType 必须VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2

  • VUID-VkSparseImageMemoryRequirements2-pNext-pNext
    pNext 必须NULL

绑定资源内存

非稀疏资源在设备使用之前(通过 vkBindImageMemoryvkBindBufferMemory)由单个物理分配支持,并且其支持必须不更改。另一方面,稀疏资源可以非连续地绑定到内存,并且这些绑定可以在资源的生命周期内更改。

需要注意的是,使用 vkFreeMemory 释放 VkDeviceMemory 对象不会导致绑定到内存对象的资源(或资源区域)解除绑定。应用程序必须不访问绑定到已释放内存的资源。

稀疏内存绑定在包含 VK_QUEUE_SPARSE_BINDING_BIT 位的队列上执行。应用程序必须使用 同步原语 来保证其他队列在绑定更改时不会同时访问内存范围。在绑定操作执行时,应用程序可以访问同一资源的其他范围。

实现必须保证在另一个队列通过稀疏资源访问同一稀疏块时同时绑定稀疏块,不会访问另一个进程拥有的内存或以其他方式损坏系统。

虽然某些实现可能在也包含图形和计算支持的队列族中包含 VK_QUEUE_SPARSE_BINDING_BIT 支持,但其他实现可能只公开 VK_QUEUE_SPARSE_BINDING_BIT 队列族。在任何一种情况下,应用程序必须使用 同步原语 来显式请求稀疏内存绑定操作与其他图形/计算/传输操作之间的任何排序依赖关系,因为稀疏绑定操作不会自动针对命令缓冲区执行进行排序,即使在单个队列中也是如此。

当显式绑定 VK_IMAGE_ASPECT_METADATA_BIT 的内存时,应用程序在绑定内存时,必须VkSparseMemoryBind::flags 字段中使用 VK_SPARSE_MEMORY_BIND_METADATA_BIT。绑定元数据的内存与绑定 mip 尾部的内存的方式相同,但增加了 VK_SPARSE_MEMORY_BIND_METADATA_BIT 标志。

对于任何方面,绑定 mip 尾部必须仅使用 VkSparseImageOpaqueMemoryBindInfo 执行。如果 formatProperties.flags 包含 VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT,则它可以使用单个 VkSparseMemoryBind 结构绑定,其中 resourceOffset = imageMipTailOffset 并且 size = imageMipTailSize

如果 formatProperties.flags 不包含 VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT,则每个数组层中 mip 尾部的偏移量给出为

arrayMipTailOffset = imageMipTailOffset + arrayLayer * imageMipTailStride;

并且 mip 尾部可以使用 layerCountVkSparseMemoryBind 结构绑定,每个结构使用 size = imageMipTailSizeresourceOffset = 上面定义的 arrayMipTailOffset

稀疏内存绑定由以下 API 和相关数据结构处理。

稀疏内存绑定函数

VkSparseMemoryBind 结构定义如下

// Provided by VK_VERSION_1_0
typedef struct VkSparseMemoryBind {
    VkDeviceSize               resourceOffset;
    VkDeviceSize               size;
    VkDeviceMemory             memory;
    VkDeviceSize               memoryOffset;
    VkSparseMemoryBindFlags    flags;
} VkSparseMemoryBind;
  • resourceOffset 是资源中的偏移量。

  • size 是要绑定的内存区域的大小。

  • memory 是资源范围绑定到的 VkDeviceMemory 对象。如果 memoryVK_NULL_HANDLE,则该范围是未绑定的。

  • memoryOffsetVkDeviceMemory 对象中用于绑定资源范围的偏移量。如果 memoryVK_NULL_HANDLE,则此值将被忽略。

  • flagsVkSparseMemoryBindFlagBits 的位掩码,用于指定绑定操作的使用。

绑定范围 [resourceOffset, resourceOffset + size) 根据 flags 有不同的约束。如果 flags 包含 VK_SPARSE_MEMORY_BIND_METADATA_BIT,则绑定范围必须在元数据方面的 mip 尾部区域内。此元数据区域定义为

metadataRegion = [base, base + imageMipTailSize)

base = imageMipTailOffset + imageMipTailStride × n

imageMipTailOffsetimageMipTailSizeimageMipTailStride 值来自对应于图像元数据方面的 VkSparseImageMemoryRequirements,并且 n 是图像的有效数组层索引,

对于 VkSparseImageMemoryRequirements::formatProperties.flags 包含 VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT 的方面,imageMipTailStride 被视为零。

如果 flags 不包含 VK_SPARSE_MEMORY_BIND_METADATA_BIT,则绑定范围必须在范围 [0,VkMemoryRequirements::size) 内。

有效使用
  • VUID-VkSparseMemoryBind-memory-01096
    如果 memory 不是 VK_NULL_HANDLE,则 memorymemoryOffset 必须与资源的内存需求匹配,如 资源内存关联 节中所述

  • VUID-VkSparseMemoryBind-resourceOffset-09491
    如果正在绑定的资源是 VkBuffer,则 resourceOffsetmemoryOffsetsize 必须是调用 vkGetBufferMemoryRequirements 并使用缓冲区资源返回的 VkMemoryRequirements 结构的 alignment 的整数倍

  • VUID-VkSparseMemoryBind-resourceOffset-09492
    如果正在绑定的资源是 VkImage,则 resourceOffsetmemoryOffset 必须是调用 vkGetImageMemoryRequirements 并使用图像资源返回的 VkMemoryRequirements 结构的 alignment 的整数倍

  • VUID-VkSparseMemoryBind-memory-01097
    如果 memory 不是 VK_NULL_HANDLE,则 memory 必须不是使用报告设置了 VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT 位的内存类型创建的

  • VUID-VkSparseMemoryBind-size-01098
    size 必须大于 0

  • VUID-VkSparseMemoryBind-resourceOffset-01099
    resourceOffset 必须小于资源的大小

  • VUID-VkSparseMemoryBind-size-01100
    size 必须小于或等于资源大小减去 resourceOffset

  • VUID-VkSparseMemoryBind-memoryOffset-01101
    memoryOffset 必须小于 memory 的大小

  • VUID-VkSparseMemoryBind-size-01102
    size 必须小于或等于 memory 的大小减去 memoryOffset

  • VUID-VkSparseMemoryBind-memory-02730
    如果 memory 是使用 VkExportMemoryAllocateInfo::handleTypes 不等于 0 创建的,则它包含的至少一个句柄类型必须也在创建资源时在 VkExternalMemoryBufferCreateInfo::handleTypesVkExternalMemoryImageCreateInfo::handleTypes 中设置

  • VUID-VkSparseMemoryBind-memory-02731
    如果 memory 是通过内存导入操作创建的,则导入内存的外部句柄类型必须也在创建资源时在 VkExternalMemoryBufferCreateInfo::handleTypesVkExternalMemoryImageCreateInfo::handleTypes 中设置

有效使用(隐式)

可以在 VkSparseMemoryBind::flags 中设置的位,用于指定稀疏内存绑定操作的使用,包括

// Provided by VK_VERSION_1_0
typedef enum VkSparseMemoryBindFlagBits {
    VK_SPARSE_MEMORY_BIND_METADATA_BIT = 0x00000001,
} VkSparseMemoryBindFlagBits;
  • VK_SPARSE_MEMORY_BIND_METADATA_BIT 指定绑定的内存仅用于元数据方面。

// Provided by VK_VERSION_1_0
typedef VkFlags VkSparseMemoryBindFlags;

VkSparseMemoryBindFlags 是一个位掩码类型,用于设置零个或多个 VkSparseMemoryBindFlagBits 的掩码。

内存使用以下结构绑定到使用 VK_BUFFER_CREATE_SPARSE_BINDING_BIT 标志创建的 VkBuffer 对象

// Provided by VK_VERSION_1_0
typedef struct VkSparseBufferMemoryBindInfo {
    VkBuffer                     buffer;
    uint32_t                     bindCount;
    const VkSparseMemoryBind*    pBinds;
} VkSparseBufferMemoryBindInfo;
有效使用(隐式)
  • VUID-VkSparseBufferMemoryBindInfo-buffer-parameter
    buffer 必须是有效的 VkBuffer 句柄

  • VUID-VkSparseBufferMemoryBindInfo-pBinds-parameter
    pBinds 必须 是一个指向 bindCount 个有效 VkSparseMemoryBind 结构体数组的有效指针

  • VUID-VkSparseBufferMemoryBindInfo-bindCount-arraylength
    bindCount 必须 大于 0

内存使用以下结构绑定到使用 VK_IMAGE_CREATE_SPARSE_BINDING_BIT 标志创建的 VkImage 对象的透明区域

// Provided by VK_VERSION_1_0
typedef struct VkSparseImageOpaqueMemoryBindInfo {
    VkImage                      image;
    uint32_t                     bindCount;
    const VkSparseMemoryBind*    pBinds;
} VkSparseImageOpaqueMemoryBindInfo;

此结构通常用于将内存绑定到完全驻留的稀疏图像或部分驻留图像的 mip 尾部区域。但是,它可以也用于绑定部分驻留图像的整个绑定范围的内存。

如果 pBinds[i] 的元素 *i* 的 flags 不包含 VK_SPARSE_MEMORY_BIND_METADATA_BIT,则 resourceOffset 的范围为 [0, VkMemoryRequirements::size)。 此范围包括来自图像所有方面的数据,包括元数据。对于大多数实现,这可能意味着 resourceOffset 是资源内的简单设备地址偏移。应用程序可以绑定一个包含资源数据和元数据的内存范围。但是,应用程序不会知道内存用于图像的哪一部分,或者是否将任何范围用于元数据。

如果 pBinds[i] 的元素 *i* 的 flags 包含 VK_SPARSE_MEMORY_BIND_METADATA_BIT,则指定的绑定范围必须在元数据方面的 mip 尾部区域内。在这种情况下,resourceOffset要求是资源内的简单设备地址偏移。但是,它定义为在元数据方面的 [imageMipTailOffset, imageMipTailOffset + imageMipTailSize) 内。有关存在此标志的绑定区域的完整约束,请参阅 VkSparseMemoryBind

有效使用
  • VUID-VkSparseImageOpaqueMemoryBindInfo-pBinds-01103
    如果 pBinds 的任何元素的 flags 成员包含 VK_SPARSE_MEMORY_BIND_METADATA_BIT,则定义的绑定范围必须image 的元数据方面的 mip 尾部区域内

有效使用(隐式)
  • VUID-VkSparseImageOpaqueMemoryBindInfo-image-parameter
    image 必须是有效的 VkImage 句柄

  • VUID-VkSparseImageOpaqueMemoryBindInfo-pBinds-parameter
    pBinds 必须 是一个指向 bindCount 个有效 VkSparseMemoryBind 结构体数组的有效指针

  • VUID-VkSparseImageOpaqueMemoryBindInfo-bindCount-arraylength
    bindCount 必须 大于 0

内存可以使用以下结构绑定到使用 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 标志创建的 VkImage 对象的稀疏图像块

// Provided by VK_VERSION_1_0
typedef struct VkSparseImageMemoryBindInfo {
    VkImage                           image;
    uint32_t                          bindCount;
    const VkSparseImageMemoryBind*    pBinds;
} VkSparseImageMemoryBindInfo;
有效使用
  • VUID-VkSparseImageMemoryBindInfo-subresource-01722
    pBinds 的每个元素的 subresource.mipLevel 成员必须小于创建 imageVkImageCreateInfo 中指定的 mipLevels

  • VUID-VkSparseImageMemoryBindInfo-subresource-01723
    pBinds 的每个元素的 subresource.arrayLayer 成员必须小于创建 imageVkImageCreateInfo 中指定的 arrayLayers

  • VUID-VkSparseImageMemoryBindInfo-subresource-01106
    pBinds 的每个元素的 subresource.aspectMask 成员必须对创建 imageVkImageCreateInfo 中指定的 format 有效

  • VUID-VkSparseImageMemoryBindInfo-image-02901
    image 必须 已使用设置的 VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT 创建

有效使用(隐式)
  • VUID-VkSparseImageMemoryBindInfo-image-parameter
    image 必须是有效的 VkImage 句柄

  • VUID-VkSparseImageMemoryBindInfo-pBinds-parameter
    pBinds 必须 是指向 bindCount 个有效的 VkSparseImageMemoryBind 结构体的有效指针

  • VUID-VkSparseImageMemoryBindInfo-bindCount-arraylength
    bindCount 必须 大于 0

VkSparseImageMemoryBind 结构定义为

// Provided by VK_VERSION_1_0
typedef struct VkSparseImageMemoryBind {
    VkImageSubresource         subresource;
    VkOffset3D                 offset;
    VkExtent3D                 extent;
    VkDeviceMemory             memory;
    VkDeviceSize               memoryOffset;
    VkSparseMemoryBindFlags    flags;
} VkSparseImageMemoryBind;
  • subresource 是图像的*方面*和图像中感兴趣的区域。

  • offset 是要绑定的图像子资源中第一个纹素的坐标。

  • extent 是要绑定的图像子资源内的区域的纹素大小。extent 必须是稀疏图像块尺寸的倍数,除非沿着图像子资源的边缘绑定稀疏图像块,否则它可以使得 offset + extent 的任何坐标等于图像子资源的相应尺寸。

  • memory 是图像的稀疏图像块绑定到的 VkDeviceMemory 对象。如果 memoryVK_NULL_HANDLE,则稀疏图像块将解除绑定。

  • memoryOffsetVkDeviceMemory 对象中的偏移量。如果 memoryVK_NULL_HANDLE,则忽略此值。

  • flags 是稀疏内存绑定标志。

有效使用
  • VUID-VkSparseImageMemoryBind-memory-01104
    如果未启用 sparseResidencyAliased 功能,并且如果任何其他资源绑定到 memory 的范围,则绑定的 memory 范围必须不与那些绑定的范围重叠

  • VUID-VkSparseImageMemoryBind-memory-01105
    memorymemoryOffset 必须与调用命令的 image 的内存要求相匹配,如 资源内存关联 部分中所述

  • VUID-VkSparseImageMemoryBind-offset-01107
    offset.x 必须是图像的稀疏图像块宽度 (VkSparseImageFormatProperties::imageGranularity.width) 的倍数

  • VUID-VkSparseImageMemoryBind-extent-09388
    extent.width 必须大于 0

  • VUID-VkSparseImageMemoryBind-extent-01108
    extent.width 必须是图像的稀疏图像块宽度的倍数,或者 (extent.width + offset.x) 必须等于图像子资源的宽度

  • VUID-VkSparseImageMemoryBind-offset-01109
    offset.y 必须是图像的稀疏图像块高度 (VkSparseImageFormatProperties::imageGranularity.height) 的倍数

  • VUID-VkSparseImageMemoryBind-extent-09389
    extent.height 必须 大于 0

  • VUID-VkSparseImageMemoryBind-extent-01110
    extent.height 必须 是图像稀疏图像块高度的倍数,或者 (extent.height + offset.y) 必须 等于图像子资源的高度

  • VUID-VkSparseImageMemoryBind-offset-01111
    offset.z 必须 是图像稀疏图像块深度 (VkSparseImageFormatProperties::imageGranularity.depth) 的倍数

  • VUID-VkSparseImageMemoryBind-extent-09390
    extent.depth 必须 大于 0

  • VUID-VkSparseImageMemoryBind-extent-01112
    extent.depth 必须 是图像稀疏图像块深度的倍数,或者 (extent.depth + offset.z) 必须 等于图像子资源的深度

  • VUID-VkSparseImageMemoryBind-memory-02732
    如果 memory 是使用 VkExportMemoryAllocateInfo::handleTypes 创建的,且不等于 0,则其中包含的至少一个句柄类型 必须 也已在创建图像时在 VkExternalMemoryImageCreateInfo::handleTypes 中设置

  • VUID-VkSparseImageMemoryBind-memory-02733
    如果 memory 是通过内存导入操作创建的,则导入内存的外部句柄类型 必须 也已在创建 image 时在 VkExternalMemoryImageCreateInfo::handleTypes 中设置

有效使用(隐式)

要将稀疏绑定操作提交到队列,请调用

// Provided by VK_VERSION_1_0
VkResult vkQueueBindSparse(
    VkQueue                                     queue,
    uint32_t                                    bindInfoCount,
    const VkBindSparseInfo*                     pBindInfo,
    VkFence                                     fence);
  • queue 是将提交稀疏绑定操作的队列。

  • bindInfoCountpBindInfo 数组中元素的数量。

  • pBindInfo 是指向 VkBindSparseInfo 结构数组的指针,每个结构指定一个稀疏绑定提交批次。

  • fence 是要发出信号的围栏的可选句柄。如果 fence 不是 VK_NULL_HANDLE,则它定义一个 围栏信号操作

vkQueueBindSparse 是一个 队列提交命令,每个批次由 pBindInfo 的一个元素定义,形式为 VkBindSparseInfo 结构。批次按照它们在 pBindInfo 中出现的顺序开始执行,但可能以乱序完成。

在一个批次内,资源的给定范围必须不能被绑定多次。在跨批次的情况下,如果要将某个范围绑定到一个分配和偏移量,然后绑定到另一个分配和偏移量,则应用程序必须保证(通常使用信号量)绑定操作以正确的顺序执行,以及命令缓冲区提交的执行顺序。

由于没有操作 vkQueueBindSparse 导致任何管线阶段访问内存,因此此命令中使用的同步原语实际上仅定义了执行依赖关系。

有关围栏和信号量操作的更多信息,请参阅同步章节

有效使用
  • VUID-vkQueueBindSparse-fence-01113
    如果 fence 不是 VK_NULL_HANDLE,则 fence 必须未发出信号

  • VUID-vkQueueBindSparse-fence-01114
    如果 fence 不是 VK_NULL_HANDLE,则 fence 必须未与该队列上尚未完成执行的任何其他队列命令关联

  • VUID-vkQueueBindSparse-pSignalSemaphores-01115
    每个 pBindInfo 元素的 pSignalSemaphores 成员的每个元素在设备上执行其定义的信号量信号操作时必须未发出信号

  • VUID-vkQueueBindSparse-pWaitSemaphores-01116
    当在 queue 上执行引用由任何 pBindInfo 元素的 pWaitSemaphores 成员定义的二进制信号量的信号量等待操作时,必须没有其他队列等待同一个信号量

  • VUID-vkQueueBindSparse-pWaitSemaphores-03245
    所有 pBindInfo 元素的所有 pWaitSemaphores 成员引用使用 VK_SEMAPHORE_TYPE_BINARYVkSemaphoreType 创建的信号量,必须引用已提交执行的信号量信号操作,并且其依赖的任何 信号量信号操作必须已提交执行

有效使用(隐式)
  • VUID-vkQueueBindSparse-queue-parameter
    queue 必须 是一个有效的 VkQueue 句柄

  • VUID-vkQueueBindSparse-pBindInfo-parameter
    如果 bindInfoCount 不为 0,则 pBindInfo 必须是指向 bindInfoCount 个有效 VkBindSparseInfo 结构数组的有效指针

  • VUID-vkQueueBindSparse-fence-parameter
    如果 fence 不是 VK_NULL_HANDLE,则 fence 必须是一个有效的 VkFence 句柄

  • VUID-vkQueueBindSparse-queuetype
    queue 必须支持稀疏绑定操作

  • VUID-vkQueueBindSparse-commonparent
    fencequeue 都是有效的、非忽略参数的句柄,必须已从同一个 VkDevice 创建、分配或检索

主机同步
  • queue 的主机访问必须进行外部同步

  • fence 的主机访问必须进行外部同步

返回值
成功
  • VK_SUCCESS

失败
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_DEVICE_LOST

VkBindSparseInfo 结构定义为

// Provided by VK_VERSION_1_0
typedef struct VkBindSparseInfo {
    VkStructureType                             sType;
    const void*                                 pNext;
    uint32_t                                    waitSemaphoreCount;
    const VkSemaphore*                          pWaitSemaphores;
    uint32_t                                    bufferBindCount;
    const VkSparseBufferMemoryBindInfo*         pBufferBinds;
    uint32_t                                    imageOpaqueBindCount;
    const VkSparseImageOpaqueMemoryBindInfo*    pImageOpaqueBinds;
    uint32_t                                    imageBindCount;
    const VkSparseImageMemoryBindInfo*          pImageBinds;
    uint32_t                                    signalSemaphoreCount;
    const VkSemaphore*                          pSignalSemaphores;
} VkBindSparseInfo;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向一个扩展此结构的结构的指针。

  • waitSemaphoreCount 是在执行批次的稀疏绑定操作之前要等待的信号量数量。

  • pWaitSemaphores 是一个指向信号量数组的指针,在执行此批次的稀疏绑定操作之前要等待这些信号量。如果提供了要等待的信号量,它们将定义一个 信号量等待操作

  • bufferBindCount 是批处理中要执行的稀疏缓冲区绑定的数量。

  • pBufferBinds 是指向 VkSparseBufferMemoryBindInfo 结构体数组的指针。

  • imageOpaqueBindCount 是要执行的不透明稀疏图像绑定的数量。

  • pImageOpaqueBinds 是指向 VkSparseImageOpaqueMemoryBindInfo 结构体数组的指针,表示要执行的不透明稀疏图像绑定。

  • imageBindCount 是要执行的稀疏图像绑定的数量。

  • pImageBinds 是指向 VkSparseImageMemoryBindInfo 结构体数组的指针,表示要执行的稀疏图像绑定。

  • signalSemaphoreCount 是由该结构体指定的稀疏绑定操作执行完成后要发出信号的信号量的数量。

  • pSignalSemaphores 是指向信号量数组的指针,当此批次的稀疏绑定操作执行完成后,这些信号量将被发出信号。如果提供了要发出信号的信号量,它们定义了信号量信号操作

有效使用
  • VUID-VkBindSparseInfo-pWaitSemaphores-03246
    如果 pWaitSemaphorespSignalSemaphores 的任何元素是用 VkSemaphoreTypeVK_SEMAPHORE_TYPE_TIMELINE 创建的,则 pNext必须包含一个 VkTimelineSemaphoreSubmitInfo 结构体

  • VUID-VkBindSparseInfo-pNext-03247
    如果此结构的 pNext 链包含一个 VkTimelineSemaphoreSubmitInfo 结构体,并且 pWaitSemaphores 的任何元素是用 VkSemaphoreTypeVK_SEMAPHORE_TYPE_TIMELINE 创建的,则其 waitSemaphoreValueCount 成员必须等于 waitSemaphoreCount

  • VUID-VkBindSparseInfo-pNext-03248
    如果此结构的 pNext 链包含一个 VkTimelineSemaphoreSubmitInfo 结构体,并且 pSignalSemaphores 的任何元素是用 VkSemaphoreTypeVK_SEMAPHORE_TYPE_TIMELINE 创建的,则其 signalSemaphoreValueCount 成员必须等于 signalSemaphoreCount

  • VUID-VkBindSparseInfo-pSignalSemaphores-03249
    对于使用 VkSemaphoreTypeVK_SEMAPHORE_TYPE_TIMELINE 创建的 pSignalSemaphores 的每个元素,VkTimelineSemaphoreSubmitInfo::pSignalSemaphoreValues 的对应元素的值必须大于当信号量信号操作执行时信号量的当前值

  • VUID-VkBindSparseInfo-pWaitSemaphores-03250
    对于使用 VkSemaphoreTypeVK_SEMAPHORE_TYPE_TIMELINE 创建的 pWaitSemaphores 的每个元素,VkTimelineSemaphoreSubmitInfo::pWaitSemaphoreValues 的对应元素的值必须与信号量的当前值,或该信号量的任何未完成的信号量等待或信号操作的值之间的差值不超过 maxTimelineSemaphoreValueDifference

  • VUID-VkBindSparseInfo-pSignalSemaphores-03251
    对于使用 VkSemaphoreTypeVK_SEMAPHORE_TYPE_TIMELINE 创建的 pSignalSemaphores 的每个元素,VkTimelineSemaphoreSubmitInfo::pSignalSemaphoreValues 的对应元素的值必须与信号量的当前值,或该信号量的任何未完成的信号量等待或信号操作的值之间的差值不超过 maxTimelineSemaphoreValueDifference

有效使用(隐式)
  • VUID-VkBindSparseInfo-sType-sType
    sType 必须VK_STRUCTURE_TYPE_BIND_SPARSE_INFO

  • VUID-VkBindSparseInfo-pNext-pNext
    pNext 链中任何结构体(包括此结构体)的每个 pNext 成员必须NULL 或指向 VkDeviceGroupBindSparseInfoVkFrameBoundaryEXTVkTimelineSemaphoreSubmitInfo 的有效实例的指针

  • VUID-VkBindSparseInfo-sType-unique
    pNext 链中每个结构体的 sType必须是唯一的

  • VUID-VkBindSparseInfo-pWaitSemaphores-parameter
    如果 waitSemaphoreCount 不为 0,则 pWaitSemaphores 必须是指向 waitSemaphoreCount 个有效 VkSemaphore 句柄数组的有效指针

  • VUID-VkBindSparseInfo-pBufferBinds-parameter
    如果 bufferBindCount 不为 0,则 pBufferBinds 必须是指向 bufferBindCount 个有效 VkSparseBufferMemoryBindInfo 结构体数组的有效指针

  • VUID-VkBindSparseInfo-pImageOpaqueBinds-parameter
    如果 imageOpaqueBindCount 不为 0,则 pImageOpaqueBinds 必须是指向 imageOpaqueBindCount 个有效 VkSparseImageOpaqueMemoryBindInfo 结构体数组的有效指针

  • VUID-VkBindSparseInfo-pImageBinds-parameter
    如果 imageBindCount 不为 0,则 pImageBinds 必须是指向 imageBindCount 个有效 VkSparseImageMemoryBindInfo 结构体数组的有效指针

  • VUID-VkBindSparseInfo-pSignalSemaphores-parameter
    如果 signalSemaphoreCount 不为 0,则 pSignalSemaphores 必须是指向 signalSemaphoreCount 个有效 VkSemaphore 句柄数组的有效指针

  • VUID-VkBindSparseInfo-commonparent
    pSignalSemaphores 的所有元素,以及 pWaitSemaphores 中作为非忽略参数的有效句柄的元素,必须已从同一个 VkDevice 创建、分配或检索。

要指定在等待和发出以 VK_SEMAPHORE_TYPE_TIMELINEVkSemaphoreType 创建的信号量时要使用的值,请将一个 VkTimelineSemaphoreSubmitInfo 结构添加到 VkBindSparseInfo 结构的 pNext 链中。

如果 VkBindSparseInfopNext 链中包含 VkDeviceGroupBindSparseInfo 结构,则该结构包含设备索引,指定绑定哪个资源和内存实例。

VkDeviceGroupBindSparseInfo 结构定义如下:

// Provided by VK_VERSION_1_1
typedef struct VkDeviceGroupBindSparseInfo {
    VkStructureType    sType;
    const void*        pNext;
    uint32_t           resourceDeviceIndex;
    uint32_t           memoryDeviceIndex;
} VkDeviceGroupBindSparseInfo;

或等效于:

// Provided by VK_KHR_device_group
typedef VkDeviceGroupBindSparseInfo VkDeviceGroupBindSparseInfoKHR;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向一个扩展此结构的结构的指针。

  • resourceDeviceIndex 是一个设备索引,指示绑定的是哪个资源的实例。

  • memoryDeviceIndex 是一个设备索引,指示资源实例绑定到哪个内存实例。

这些设备索引适用于指向此结构的所有批处理中包含的缓冲区和图像内存绑定。批处理的信号量等待和发出仅由 resourceDeviceIndex 指定的物理设备执行。

如果此结构不存在,则假定 resourceDeviceIndexmemoryDeviceIndex 为零。

有效使用
  • VUID-VkDeviceGroupBindSparseInfo-resourceDeviceIndex-01118
    resourceDeviceIndexmemoryDeviceIndex 必须都是有效的设备索引。

  • VUID-VkDeviceGroupBindSparseInfo-memoryDeviceIndex-01119
    此批处理中绑定的每个内存分配必须已为 memoryDeviceIndex 分配了一个实例。

有效使用(隐式)
  • VUID-VkDeviceGroupBindSparseInfo-sType-sType
    sType 必须VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO