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:

  1. Make sure the SPIR-V extension and capability are available in Vulkan.

  2. Check if the required Vulkan extension, features or version are supported.

  3. If needed, enable the Vulkan extension and features.

  4. 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.

spirv_extensions_8bit_extension

Also, take a look at the Supported SPIR-V Capabilities Table in the Vulkan Spec.

spirv_extensions_8bit_capability

while it says VkPhysicalDeviceVulkan12Features::uniformAndStorageBuffer8BitAccess in the table, the VkPhysicalDevice8BitStorageFeatures::uniformAndStorageBuffer8BitAccess is an alias can be considered the same here.

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.