Core functionality and enumerating supported extensions

Recently I observed that function VkEnumerateInstanceExtensionProperties returns the list of supported extensions including those promoted to core Vulkan. But back in 2018 there was discussion here about if promoted extensions must be returned by VkEnumerateXExtensionProperties, and Vulkan working group decided that it will not be added. So my question is : Can I take for granted that VkEnumerateXExtensionProperties will always return all supported extensions even if core extensions are enabled by default? Or should I check what is version of Vulkan runtime and deduce which extensions are enabled in core functionality?

I don’t quite understand what you mean by that.

Using the variable_pointers example, if you enumerate extensions, you may find that KHR_variable_pointers is available. If it is, and the Vulkan version is 1.1, then the variablePointersStorageBuffer feature must also be available. If you find that the extension is not available, and the version is 1.1, then the variablePointersStorageBuffer feature may or may not be available.

If you are writing code against Vulkan 1.1 (aka: your program will fail to run on a version less than 1.1), then you should be looking at the optional features of 1.1, and non-promoted extensions. There is no reason to care about the presence or absence of the KHR_variable_pointers extension; you should only care if the variablePointersStorageBuffer feature is available. If the 1.1 implementation supports the functionality, then it will expose it via the feature; it may also do it via an extension.

If you’re writing your code to be more adaptive, to run on multiple versions of Vulkan instead of picking a minimum base version, then you should look at things based on the device version advertised. If the available version is 1.0, then look for the extension. If the available version is 1.1 or higher, then look for the feature.

Using the variable_pointers example, if you enumerate extensions, you may find that KHR_variable_pointers is available. If it is, and the Vulkan version is 1.1, then the variablePointersStorageBuffer feature must also be available. If you find that the extension is not available, and the version is 1.1, then the variablePointersStorageBuffer feature may or may not be available.

Ok, you gave example of extension that have additional support contidion when was promoted to core Vulkan - if extension is not on the list of supported extensions then check features. But what with extensions that are promoted without it, i.e. they are just supported by Vulkan from now on? For example VK_KHR_bind_memory2, it is just on the list of promoted extensions without description that says “if extension not supported, check features”, it is just added to core functionality. Can I be sure that it will be returned inside list of supported extensions?

I am trying to write portable code. I have function that programmer/user will only need to supply with list of extensions that they want to enable and function will return extensions that are actually supported. My concerns are : if I won’t check supported version of Vulkan and just try to enable some extensions, will supported extensions list contain extensions that were prromoted to core Vulkan up to that version, or they will not be on this list and my function will se them as not supported, where in reality they are in core functionality and supported “by default” for that version.

Or is it not defined if all Vulkan implementations will behave this way and the best solution is what you suggested :

If you’re writing your code to be more adaptive, to run on multiple versions of Vulkan instead of picking a minimum base version, then you should look at things based on the device version advertised. If the available version is 1.0, then look for the extension. If the available version is 1.1 or higher, then look for the feature.

Thanks for your answer in advance.

If an implementation advertises Vulkan 1.1, then it must provide vkBindBufferMemory2 et. al. That is not an optional feature of 1.1; it is mandatory. By contrast, variablePointer is optional in 1.1.

So if you’re writing against 1.1, there’s nothing to check; those functions exist.

From the specification:

Whilst the behavior of each command alias is identical, the behavior of retrieving each alias’s function pointer is not. A function pointer for a given alias can only be retrieved if the extension or version that introduced that alias is supported and enabled, irrespective of whether any other alias is available.

So if a user asks for KHR_bind_memory2, but the implementation exposes Vulkan 1.1 and not the extension, you cannot query KHR_bind_memory2 extension functions.

You can, of course, lie to the user. The Vulkan XML specification document contains information about extension promotion and function/type aliases. Therefore, if a user asks for KHR_bind_memory2, and a Vulkan 1.1 implementation doesn’t expose that extension, you can just lie to the user. Since you know that KHR_bind_memory2 was promoted in 1.1, and you know that it isn’t an optional feature, then you can treat 1.1 as equivalent.

You can therefore expose the extension function aliases by querying the core functions and shoving those function pointers into the extension functions.

That having been said, it’s very important to understand this: not every part of Vulkan 1.x was exposed as an extension from 1.(x-1). Bespoke functionality can arise in 1.x with no prior extensions. And even if an extension is promoted, not all of its functionality may be aliased. Therefore, users are going to have to deal with Vulkan versions.

So this is not a general solution.

not every part of Vulkan 1.x was exposed as an extension from 1.(x-1). Bespoke functionality can arise in 1.x with no prior extensions.

I understand that and won’t use such functions without preparing my code to deal with version that supports it.

You can, of course, lie to the user. The Vulkan XML specification document contains information about extension promotion and function/type aliases. Therefore, if a user asks for KHR_bind_memory2, and a Vulkan 1.1 implementation doesn’t expose that extension, you can just lie to the user. Since you know that KHR_bind_memory2 was promoted in 1.1, and you know that it isn’t an optional feature, then you can treat 1.1 as equivalent.

So from what I understand : it is not granted that core promoted extensions will always be inside list returned by VkEnymerateXExtensionProperties and I should always check version of Vulkan supported on the machine and run my code accordingly to this version.

If an extension is supported, then the equivalent core features must be supported (assuming appropriate core version is supported).

But not the other way around.

For example, a player late to the game could implement a Vulkan 1.3 driver, but include none of the extensions that lead to it.

2 Likes

Sorry to ask maybe the same question but I still didn’t get satifying answer.
Will VkEnumerateXExtensionProperties always return extensions that are supported as core functionality? I am not talking about extensions that if not supported then feature will indicate if it is indeed supported. I am talking about extensions that were added to core functionality and are guaranteed to be supported by this version and later versions. For example : Can I be sure that VkEnumerateXExtensionProperties will always return VK_KHR_bind_memory2 as supported extension in Vulkan 1.1+? Where VK_KHR_bind_memory2 was added as core functionality in Vulkan 1.1.

There are no mandatory extensions (well, there was one at one point, but anyway…). As I was saying, you can have Vulkan 1.3 driver with zero extensions.

Sorry to answer maybe the same answer. Extension implies there will be the corresponding core feature. Core feature does not imply there will be an extension. Teh specc:

When a promoted extension is available, any corresponding feature aliases must be supported.

1 Like