清理扩展

这些是未正式称为“清理扩展”的扩展。Vulkan 指南将它们定义为清理扩展,因为它们本质上只添加了一小部分功能,或者在目的方面是非常简单、不言自明的扩展。

VK_KHR_driver_properties

在 Vulkan 1.2 中晋升为核心

此扩展添加了更多关于每个实现的查询信息。VkDriverId 将是已注册供应商的实现 ID。VkConformanceVersion 显示了该实现通过的 Vulkan 一致性测试套件 的版本。

VK_EXT_host_query_reset

在 Vulkan 1.2 中晋升为核心

此扩展允许应用程序从主机调用 vkResetQueryPool,而无需设置逻辑来提交 vkCmdResetQueryPool,因为这对于大多数实现来说主要只是快速写入内存。

VK_KHR_separate_depth_stencil_layouts

在 Vulkan 1.2 中晋升为核心

此扩展允许应用程序在使用深度/模板格式时分别对深度和模板进行图像转换。从 Vulkan 1.2 开始,所有实现都必须具备此功能。

VK_KHR_depth_stencil_resolve

在 Vulkan 1.2 中晋升为核心

此扩展增加了对在子通道中自动解析多重采样的深度/模板附件的支持,其方式与颜色附件类似。

有关更多信息,请查看 GDC 演示文稿。(幻灯片视频

VK_EXT_separate_stencil_usage

在 Vulkan 1.2 中晋升为核心

有一些格式同时表达了深度和模板的用法,但没有办法列出它们的其他用法。现在,VkImageStencilUsageCreateInfo 允许应用程序为图像的模板用法传入单独的 VkImageUsageFlags。深度用法是传入 VkImageCreateInfo::usage 的原始用法,如果不使用 VkImageStencilUsageCreateInfo,则模板用法也将相同。

一个很好的用例是使用 VK_KHR_image_format_list 扩展时。这为应用程序提供了一种在创建时更明确地描述其 VkImage 的可能图像视图的方法。这允许某些实现可能根据设置的用法进行依赖于实现的优化。

VK_KHR_dedicated_allocation

在 Vulkan 1.1 中晋升为核心

通常,应用程序为 VkDeviceMemory 分配大块,然后子分配给各种缓冲区和图像。有时,为 VkImageVkBuffer 进行专用分配可能更好。应用程序可以将 VkMemoryDedicatedRequirements 传递到 vkGetBufferMemoryRequirements2vkGetImageMemoryRequirements2 中,以了解是否首选或需要专用分配。在处理外部内存时,通常需要专用分配。

VK_EXT_sampler_filter_minmax

在 Vulkan 1.2 中晋升为核心

默认情况下,使用线性滤波的 Vulkan 采样器会返回一个经过滤波的纹素值,该值是通过计算提供的纹理坐标附近的一组纹素的加权平均值来产生的。此扩展提供了一个新的采样器参数,允许应用程序通过计算通常被平均的纹素的逐分量最小值 (VK_SAMPLER_REDUCTION_MODE_MIN) 或最大值 (VK_SAMPLER_REDUCTION_MODE_MAX) 来生成经过滤波的纹素值。这类似于 GL EXT_texture_filter_minmax

VK_KHR_sampler_mirror_clamp_to_edge

在 Vulkan 1.2 中晋升为核心

此扩展添加了一种新的采样器寻址模式 (VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE),它有效地使用一张纹理图,该纹理图是原始图像的两倍大,其中新图像的额外一半是原始图像的镜像。这种新模式通过使用原始图像来生成匹配的“镜像”,从而放松了对生成其相对边缘匹配的图像的需求。此模式允许纹理仅在负 str 方向上镜像一次。

VK_EXT_4444_formats 和 VK_EXT_ycbcr_2plane_444_formats

在 Vulkan 1.3 中晋升为核心

这些扩展添加了规范中最初没有的新 VkFormat

VK_KHR_format_feature_flags2

在 Vulkan 1.3 中晋升为核心

此扩展添加了一个新的 VkFormatFeatureFlagBits2KHR 64 位格式特性标志类型,以扩展现有的 VkFormatFeatureFlagBits,后者限制为 31 个标志。

VK_EXT_rgba10x6_formats

此扩展在 验证层中为 VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 添加了一个例外,以允许渲染到该格式。

维护扩展

维护扩展添加了一系列在最初的 Vulkan 1.0 版本中有意遗漏或忽略的小功能。

目前,有 6 个维护扩展。前 3 个在 Vulkan 1.1 中被捆绑为核心功能。每个扩展的所有细节都在扩展附录页面中有详细定义。

pNext 扩展

Vulkan 工作组曾多次意识到,由于缺少 sType/pNext,原始 1.0 Vulkan 规范中的一些结构体缺少正确扩展的能力。

保持版本之间的向后兼容性非常重要,因此最佳解决方案是创建一个扩展来修正这个错误。这些扩展主要是新的结构体,但也需要创建新的函数入口点来使用新的结构体。

符合此类别的当前扩展列表为:

  • VK_KHR_get_memory_requirements2

    • 添加到 Vulkan 1.1 的核心功能

  • VK_KHR_get_physical_device_properties2

    • 添加到 Vulkan 1.1 的核心功能

  • VK_KHR_bind_memory2

    • 添加到 Vulkan 1.1 的核心功能

  • VK_KHR_create_renderpass2

    • 添加到 Vulkan 1.2 的核心功能

  • VK_KHR_copy_commands2

    • 添加到 Vulkan 1.3 的核心功能

所有这些都是非常简单的扩展,并在各自的版本中被提升为核心功能,以便更容易使用,而无需查询它们的支持。

VK_KHR_get_physical_device_properties2 具有额外的功能,因为它增加了查询扩展和较新 Vulkan 版本的特性支持的能力。由于这个原因,它已成为大多数其他 Vulkan 扩展的要求。

示例

VK_KHR_bind_memory2 为例,而不是使用标准的 vkBindImageMemory

// VkImage images[3]
// VkDeviceMemory memories[2];

vkBindImageMemory(myDevice, images[0], memories[0], 0);
vkBindImageMemory(myDevice, images[1], memories[0], 64);
vkBindImageMemory(myDevice, images[2], memories[1], 0);

它们现在可以批量处理

// VkImage images[3];
// VkDeviceMemory memories[2];

VkBindImageMemoryInfo infos[3];
infos[0] = {VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, NULL, images[0], memories[0], 0};
infos[1] = {VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, NULL, images[1], memories[0], 64};
infos[2] = {VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, NULL, images[2], memories[1], 0};

vkBindImageMemory2(myDevice, 3, infos);

一些扩展,如 VK_KHR_sampler_ycbcr_conversion,公开了可以传递到 pNext 中的结构体

VkBindImagePlaneMemoryInfo plane_info[2];
plane_info[0] = {VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO, NULL, VK_IMAGE_ASPECT_PLANE_0_BIT};
plane_info[1] = {VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO, NULL, VK_IMAGE_ASPECT_PLANE_1_BIT};

// Can now pass other extensions structs into the pNext missing from vkBindImageMemory()
VkBindImageMemoryInfo infos[2];
infos[0] = {VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, &plane_info[0], image, memories[0], 0};
infos[1] = {VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, &plane_info[1], image, memories[1], 0};

vkBindImageMemory2(myDevice, 2, infos);

不使用这些扩展也可以

除非应用程序需要使用依赖于上述扩展的扩展,否则通常仍然可以使用原始的函数/结构体。

一种可能的处理方式如下

void HandleVkBindImageMemoryInfo(const VkBindImageMemoryInfo* info) {
    // ...
}

//
// Entry points into tool/implementation
//
void vkBindImageMemory(VkDevice device,
                       VkImage image,
                       VkDeviceMemory memory,
                       VkDeviceSize memoryOffset)
{
    VkBindImageMemoryInfo info;
    // original call doesn't have a pNext or sType
    info.sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
    info.pNext = nullptr;

    // Match the rest of struct the same
    info.image = image;
    info.memory = memory;
    info.memoryOffset = memoryOffset;

    HandleVkBindImageMemoryInfo(&info);
}

void vkBindImageMemory2(VkDevice device,
                        uint32_t bindInfoCount,
                        const VkBindImageMemoryInfo* pBindInfos)
{
    for (uint32_t i = 0; i < bindInfoCount; i++) {
        HandleVkBindImageMemoryInfo(pBindInfos[i]);
    }
}