清理扩展
这些是未正式称为“清理扩展”的扩展。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_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
分配大块,然后子分配给各种缓冲区和图像。有时,为 VkImage
或 VkBuffer
进行专用分配可能更好。应用程序可以将 VkMemoryDedicatedRequirements
传递到 vkGetBufferMemoryRequirements2
或 vkGetImageMemoryRequirements2
中,以了解是否首选或需要专用分配。在处理外部内存时,通常需要专用分配。
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
),它有效地使用一张纹理图,该纹理图是原始图像的两倍大,其中新图像的额外一半是原始图像的镜像。这种新模式通过使用原始图像来生成匹配的“镜像”,从而放松了对生成其相对边缘匹配的图像的需求。此模式允许纹理仅在负 s
、t
和 r
方向上镜像一次。
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 中被捆绑为核心功能。每个扩展的所有细节都在扩展附录页面中有详细定义。
-
VK_KHR_maintenance1 - Vulkan 1.1 中的核心功能
-
VK_KHR_maintenance2 - Vulkan 1.1 中的核心功能
-
VK_KHR_maintenance3 - Vulkan 1.1 中的核心功能
-
VK_KHR_maintenance4 - Vulkan 1.3 中的核心功能
-
VK_KHR_maintenance5 - 仅限扩展
-
VK_KHR_maintenance6 - 仅限扩展
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_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]);
}
}