30.2. Extensions

Extensions may define new Vulkan commands, structures, and enumerants. For compilation purposes, the interfaces defined by registered extensions, including new structures and enumerants as well as function pointer types for new commands, are defined in the Khronos-supplied vulkan.h together with the core API. However, commands defined by extensions may not be available for static linking - in which case function pointers to these commands should be queried at runtime as described in Section 3.1, “Command Function Pointers”. Extensions may be provided by layers as well as by a Vulkan implementation.

To query the available instance extensions, call:

 

VkResult vkEnumerateInstanceExtensionProperties(
    const char*                                 pLayerName,
    uint32_t*                                   pPropertyCount,
    VkExtensionProperties*                      pProperties);

When pLayerName parameter is NULL, only extensions provided by the Vulkan implementation or by implicitly enabled layers are returned. When pLayerName is the name of a layer, the instance extensions provided by that layer are returned.

To enable an instance extension, the name of the extension should be added to the ppEnabledExtensionNames member of VkInstanceCreateInfo when creating a VkInstance.

Enabling an extension does not change behavior of functionality exposed by the core Vulkan API or any other extension, other than making valid the use of the commands, enums and structures defined by that extension.

To query the extensions available to a given physical device, call:

 

VkResult vkEnumerateDeviceExtensionProperties(
    VkPhysicalDevice                            physicalDevice,
    const char*                                 pLayerName,
    uint32_t*                                   pPropertyCount,
    VkExtensionProperties*                      pProperties);

When pLayerName parameter is NULL, only extensions provided by the Vulkan implementation or by implicitly enabled layers are returned. When pLayerName is the name of a layer, the device extensions provided by that layer are returned.

For both vkEnumerateInstanceExtensionProperties and vkEnumerateDeviceExtensionProperties, if pProperties is NULL, then the number of extensions properties available is returned in pPropertyCount. Otherwise, pPropertyCount must point to a variable set by the user to the number of elements in the pProperties array, and on return the variable is overwritten with the number of structures actually written to pProperties. If pPropertyCount is less than the number of extension properties available, at most pPropertyCount structures will be written. If pPropertyCount is smaller than the number of extensions available, VK_INCOMPLETE will be returned instead of VK_SUCCESS, to indicate that not all the available properties were returned.

The VkExtensionProperties structure is defined as:

 

typedef struct VkExtensionProperties {
    char        extensionName[VK_MAX_EXTENSION_NAME_SIZE];
    uint32_t    specVersion;
} VkExtensionProperties;

30.2.1. Instance Extensions and Device Extensions

Because an instance extension can affect the operation of an instance and any of its child objects, the decision to expose functionality as an instance extension or as a device extension is not always clear. This section provides some guidelines and rules for when to expose new functionality as an instance extension, device extension, or both.

The decision is influenced by whether extension functionality affects instance-level objects (e.g. instances and physical devices) and commands, or device-level objects (e.g. logical devices, queues, and command buffers) and commands, or both.

In some cases, the decision is clear:

  • Functionality that is restricted to the instance-level must be implemented as an instance extension.
  • Functionality that is restricted to the device-level must be implemented as an device extension.

In other cases, the decision is not so clear:

  • Global functionality that affects the entire Vulkan API, including instance and device-level objects and commands, should be an instance extension.
  • Device-level functionality that contains physical-device queries, can be implemented as an instance extension. If some part of an instance extension’s functionality might not be available on all physical devices, the extension should provide a query to determine which physical devices provide the functionality.
  • For a set of global functionality that provides new instance-level and device-level commands, and can be enabled for a subset of devices, it is recommended that the functionality be partitioned across two extensions—one for the instance-level functionality, and one for the device-specific functionality. In this latter case, it is generally recommended that the two extensions have unique names.

Examples of instance extensions include:

  • Logging of debug messages by any enabled layers for all Vulkan commands.
  • Functionality creating new objects which are direct children of an instance.
  • Functionality creating new objects which are direct children of a physical device and intended to work with any logical device created from the physical device.
  • Functionality adding new instance-level Vulkan commands that do not affect any device-level commands.
[Note]Note

Instance extensions generally require support in the Vulkan loader. This is especially true for commands that are dispatched from instances and physical devices. Additional information about supporting instance-level commands may be found in the "Vulkan Loader Specification and Architecture Overview" document, which may be found at the following web page:

Please see the "Architectural overview of layers and loader" section for information about how both instance-level and device-level commands are supported and dispatched.