启用扩展
本节介绍启用扩展的逻辑。
两种类型的扩展
扩展分为两组,实例扩展和设备扩展。 简而言之,实例扩展与整个 VkInstance
相关联,而设备扩展仅与单个 VkDevice
对象相关联。
此信息记录在每个扩展参考页的“扩展类型”部分下。 以下示例

检查支持
应用程序可以首先查询物理设备,以使用 vkEnumerateInstanceExtensionProperties
或 vkEnumerateDeviceExtensionProperties
检查扩展是否受支持。
// Simple example
uint32_t count = 0;
vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &count, nullptr);
std::vector<VkExtensionProperties> extensions(count);
vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &count, extensions.data());
// Checking for support of VK_KHR_bind_memory2
for (uint32_t i = 0; i < count; i++) {
if (strcmp(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, extensions[i].extensionName) == 0) {
break; // VK_KHR_bind_memory2 is supported
}
}
启用扩展
即使实现支持该扩展,除非在 VkInstance
或 VkDevice
创建时启用该扩展,否则使用该扩展的功能是未定义的行为。
以下是启用诸如 VK_KHR_driver_properties
之类的扩展所需的一个示例。

// VK_KHR_get_physical_device_properties2 is required to use VK_KHR_driver_properties
// since it's an instance extension it needs to be enabled before at VkInstance creation time
std::vector<const char*> instance_extensions;
instance_extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
VkInstanceCreateInfo instance_create_info = {};
instance_create_info.enabledExtensionCount = static_cast<uint32_t>(instance_extensions.size());
instance_create_info.ppEnabledExtensionNames = instance_extensions.data();
vkCreateInstance(&instance_create_info, nullptr, &myInstance);
// ...
std::vector<const char*> device_extensions;
device_extensions.push_back(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME);
VkDeviceCreateInfo device_create_info = {};
device_create_info.enabledExtensionCount = static_cast<uint32_t>(device_extensions.size());
device_create_info.ppEnabledExtensionNames = device_extensions.data();
vkCreateDevice(physicalDevice, &device_create_info, nullptr, &myDevice);
检查特性位
重要的是要记住,扩展为 Vulkan 规范增加了功能的存在,但这并不意味着如果扩展受支持,则可以使用扩展的所有特性。 例如,VK_KHR_8bit_storage
扩展,它在 VkPhysicalDevice8BitStorageFeatures
中公开了 3 个特性。

这意味着在启用扩展之后,应用程序仍然需要查询并启用扩展所需的特性。
晋升过程
当 Vulkan 的次要版本发布时,某些扩展会根据规范定义进行晋升。 晋升的目标是将 Vulkan 工作组确定为广泛支持的扩展功能放入核心 Vulkan 规范中。 有关 Vulkan 版本的更多详细信息,请参见版本章节。
一个示例是 VK_KHR_get_physical_device_properties2
,它用于大多数其他扩展。 在 Vulkan 1.0 中,应用程序必须先查询对 VK_KHR_get_physical_device_properties2
的支持,然后才能调用诸如 vkGetPhysicalDeviceFeatures2KHR
之类的函数。 从 Vulkan 1.1 开始,保证支持 vkGetPhysicalDeviceFeatures2
函数。
看待晋升的另一种方式是再次以 VK_KHR_8bit_storage
为例。 由于 Vulkan 1.0,一些特性(如 textureCompressionASTC_LDR
)不是必须支持的,但是可以在无需启用任何扩展的情况下进行查询。 从 Vulkan 1.2 开始,当 VK_KHR_8bit_storage
晋升为核心时,现在可以在 VkPhysicalDeviceVulkan12Features
中找到 VkPhysicalDevice8BitStorageFeatures
中的所有特性。
晋升行为的变更
重要的是要意识到,对于某些被晋升的扩展,存在细微的差异。 规范描述了晋升可能涉及较小的更改,例如扩展的“特性广告/启用”。 为了最好地描述这种微妙之处,可以将 VK_KHR_8bit_storage
用作一个用例。
Vulkan 规范描述了 Vulkan 1.2 的 VK_KHR_8bit_storage
的变化,其中指出
如果不支持 VK_KHR_8bit_storage 扩展,则着色器模块中对 SPIR-V StorageBuffer8BitAccess 功能的支持是可选的。
这里的“不支持”是指这样一个事实:实现可能支持 Vulkan 1.2+,但是如果应用程序查询 vkEnumerateDeviceExtensionProperties
,则 VK_KHR_8bit_storage
可能不在结果中。
-
如果在
vkEnumerateDeviceExtensionProperties
中找到VK_KHR_8bit_storage
,则保证支持storageBuffer8BitAccess
特性。 -
如果未在
vkEnumerateDeviceExtensionProperties
中找到VK_KHR_8bit_storage
,则可能支持storageBuffer8BitAccess
特性,并且可以通过查询VkPhysicalDeviceVulkan12Features::storageBuffer8BitAccess
来检查。
可以在规范的版本附录中找到对升级的扩展的所有特性更改的列表。