Using SPIR-V Extensions
SPIR-V is the shader representation used at vkCreateShaderModule
time. Just like Vulkan, SPIR-V also has extensions and a capabilities system.
It is important to remember that SPIR-V is an intermediate language and not an API, it relies on an API, such as Vulkan, to expose what features are available to the application at runtime. This chapter aims to explain how Vulkan, as a SPIR-V client API, interacts with the SPIR-V extensions and capabilities.
SPIR-V Extension Example
For this example, the VK_KHR_8bit_storage and SPV_KHR_8bit_storage will be used to expose the UniformAndStorageBuffer8BitAccess
capability. The following is what the SPIR-V disassembled looks like:
OpCapability Shader
OpCapability UniformAndStorageBuffer8BitAccess
OpExtension "SPV_KHR_8bit_storage"
Steps for using SPIR-V features:
-
Make sure the SPIR-V extension and capability are available in Vulkan.
-
Check if the required Vulkan extension, features or version are supported.
-
If needed, enable the Vulkan extension and features.
-
If needed, see if there is a matching extension for the high-level shading language (ex. GLSL or HLSL) being used.
Breaking down each step in more detail:
Check if SPIR-V feature is supported
Depending on the shader feature there might only be a OpExtension
or OpCapability
that is needed. For this example, the UniformAndStorageBuffer8BitAccess
is part of the SPV_KHR_8bit_storage extension.
To check if the SPIR-V extension is supported take a look at the Supported SPIR-V Extension Table in the Vulkan Spec.
Also, take a look at the Supported SPIR-V Capabilities Table in the Vulkan Spec.
while it says |
Luckily if you forget to check, the Vulkan Validation Layers has an auto-generated validation in place. Both the Validation Layers and the Vulkan Spec table are all based on the ./xml/vk.xml file.
<spirvcapability name="UniformAndStorageBuffer8BitAccess">
<enable struct="VkPhysicalDeviceVulkan12Features" feature="uniformAndStorageBuffer8BitAccess" requires="VK_VERSION_1_2,VK_KHR_8bit_storage"/>
</spirvcapability>
<spirvextension name="SPV_KHR_8bit_storage">
<enable version="VK_VERSION_1_2"/>
<enable extension="VK_KHR_8bit_storage"/>
</spirvextension>
Check for support then enable if needed
In this example, either VK_KHR_8bit_storage
or a Vulkan 1.2 device is required.
If using a Vulkan 1.0 or 1.1 device, the VK_KHR_8bit_storage
extension will need to be supported and enabled at device creation time.
Regardless of using the Vulkan extension or version, if required, an app still must make sure any matching Vulkan feature needed is supported and enabled at device creation time. Some SPIR-V extensions and capabilities don’t require a Vulkan feature, but this is all listed in the tables in the spec.
For this example, either the VkPhysicalDeviceVulkan12Features::uniformAndStorageBuffer8BitAccess
or VkPhysicalDevice8BitStorageFeatures::uniformAndStorageBuffer8BitAccess
feature must be supported and enabled.
Using high level shading language extensions
For this example, GLSL has a GL_EXT_shader_16bit_storage extension that includes the match GL_EXT_shader_8bit_storage
extension in it.
Tools such as glslang
and SPIRV-Tools
will handle to make sure the matching OpExtension
and OpCapability
are used.