## 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);

- `pLayerName` is either `NULL` or a pointer to a null-terminated UTF-8 string naming the layer to retrieve extensions from.
- `pPropertyCount` is a pointer to an integer related to the number of extension properties available or queried, as described below.
- `pProperties` is either `NULL` or a pointer to an array of `VkExtensionProperties` structures.

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.

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.

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);

- `physicalDevice` is the physical device that will be queried.
- `pLayerName` is either `NULL` or a pointer to a null-terminated UTF-8 string naming the layer to retrieve extensions from.
- `pPropertyCount` is a pointer to an integer related to the number of extension properties available or queried, and is treated in the same fashion as the `vkEnumerateInstanceExtensionProperties`::`pPropertyCount` parameter.
- `pProperties` is either `NULL` or a pointer to an array of `VkExtensionProperties` structures.

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.

The `VkExtensionProperties` structure is defined as:

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

- `extensionName` is a null-terminated string specifying the name of the extension.
- `specVersion` is the version of this extension. It is an integer, incremented with backward compatible changes.

### 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
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, located at URL https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/sdk-1.0.13/loader/LoaderAndLayerInterface.md 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.