Vulkan Logo

4. Initialization

Before using Vulkan, an application must initialize it by loading the Vulkan commands, and creating a VkInstance object.

4.1. Command Function Pointers

Vulkan commands are not necessarily exposed by static linking on a platform. Commands to query function pointers for Vulkan commands are described below.

Note

When extensions are promoted or otherwise incorporated into another extension or Vulkan core version, command aliases may be included. 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.

Function pointers for all Vulkan commands can be obtained by calling:

// Provided by VK_VERSION_1_0
PFN_vkVoidFunction vkGetInstanceProcAddr(
    VkInstance                                  instance,
    const char*                                 pName);
  • instance is the instance that the function pointer will be compatible with, or NULL for commands not dependent on any instance.

  • pName is the name of the command to obtain.

vkGetInstanceProcAddr itself is obtained in a platform- and loader- specific manner. Typically, the loader library will export this command as a function symbol, so applications can link against the loader library, or load it dynamically and look up the symbol using platform-specific APIs.

The table below defines the various use cases for vkGetInstanceProcAddr and expected return value (“fp” is “function pointer”) for each case. A valid returned function pointer (“fp”) must not be NULL.

The returned function pointer is of type PFN_vkVoidFunction, and must be cast to the type of the command being queried before use.

Table 1. vkGetInstanceProcAddr behavior
instance pName return value

*1

NULL

undefined

invalid non-NULL instance

*1

undefined

NULL

global command2

fp

NULL

vkGetInstanceProcAddr

fp5

instance

vkGetInstanceProcAddr

fp

instance

core dispatchable command

fp3

instance

enabled instance extension dispatchable command for instance

fp3

instance

available device extension4 dispatchable command for instance

fp3

any other case, not covered above

NULL

1

"*" means any representable value for the parameter (including valid values, invalid values, and NULL).

2

The global commands are: vkEnumerateInstanceVersion, vkEnumerateInstanceExtensionProperties, vkEnumerateInstanceLayerProperties, and vkCreateInstance. Dispatchable commands are all other commands which are not global.

3

The returned function pointer must only be called with a dispatchable object (the first parameter) that is instance or a child of instance, e.g. VkInstance, VkPhysicalDevice, VkDevice, VkQueue, or VkCommandBuffer.

4

An “available device extension” is a device extension supported by any physical device enumerated by instance.

5

Starting with Vulkan 1.2, vkGetInstanceProcAddr can resolve itself with a NULL instance pointer.

Valid Usage (Implicit)
  • VUID-vkGetInstanceProcAddr-instance-parameter
    If instance is not NULL, instance must be a valid VkInstance handle

  • VUID-vkGetInstanceProcAddr-pName-parameter
    pName must be a null-terminated UTF-8 string

In order to support systems with multiple Vulkan implementations, the function pointers returned by vkGetInstanceProcAddr may point to dispatch code that calls a different real implementation for different VkDevice objects or their child objects. The overhead of the internal dispatch for VkDevice objects can be avoided by obtaining device-specific function pointers for any commands that use a device or device-child object as their dispatchable object. Such function pointers can be obtained by calling:

// Provided by VK_VERSION_1_0
PFN_vkVoidFunction vkGetDeviceProcAddr(
    VkDevice                                    device,
    const char*                                 pName);

The table below defines the various use cases for vkGetDeviceProcAddr and expected return value (“fp” is “function pointer”) for each case. A valid returned function pointer (“fp”) must not be NULL.

The returned function pointer is of type PFN_vkVoidFunction, and must be cast to the type of the command being queried before use. The function pointer must only be called with a dispatchable object (the first parameter) that is device or a child of device.

Table 2. vkGetDeviceProcAddr behavior
device pName return value

NULL

*1

undefined

invalid device

*1

undefined

device

NULL

undefined

device

requested core version2 device-level dispatchable command3

fp4

device

enabled extension device-level dispatchable command3

fp4

any other case, not covered above

NULL

1

"*" means any representable value for the parameter (including valid values, invalid values, and NULL).

2

Device-level commands which are part of the core version specified by VkApplicationInfo::apiVersion when creating the instance will always return a valid function pointer. If the maintenance5 feature is enabled, core commands beyond that version which are supported by the implementation will return NULL, otherwise the implementation may either return NULL or a function pointer. If a function pointer is returned, it must not be called.

3

In this function, device-level excludes all physical-device-level commands.

4

The returned function pointer must only be called with a dispatchable object (the first parameter) that is device or a child of device e.g. VkDevice, VkQueue, or VkCommandBuffer.

Valid Usage (Implicit)
  • VUID-vkGetDeviceProcAddr-device-parameter
    device must be a valid VkDevice handle

  • VUID-vkGetDeviceProcAddr-pName-parameter
    pName must be a null-terminated UTF-8 string

The definition of PFN_vkVoidFunction is:

// Provided by VK_VERSION_1_0
typedef void (VKAPI_PTR *PFN_vkVoidFunction)(void);

This type is returned from command function pointer queries, and must be cast to an actual command function pointer before use.

4.1.1. Extending Physical Device Core Functionality

New core physical-device-level functionality can be used when the physical-device version is greater than or equal to the version of Vulkan that added the new functionality. The Vulkan version supported by a physical device can be obtained by calling vkGetPhysicalDeviceProperties.

4.1.2. Extending Physical Device From Device Extensions

When the VK_KHR_get_physical_device_properties2 extension is enabled, or when both the instance and the physical-device versions are at least 1.1, physical-device-level functionality of a device extension can be used with a physical device if the corresponding extension is enumerated by vkEnumerateDeviceExtensionProperties for that physical device, even before a logical device has been created.

To obtain a function pointer for a physical-device-level command from a device extension, an application can use vkGetInstanceProcAddr. This function pointer may point to dispatch code, which calls a different real implementation for different VkPhysicalDevice objects. Applications must not use a VkPhysicalDevice in any command added by an extension or core version that is not supported by that physical device.

Device extensions may define structures that can be added to the pNext chain of physical-device-level commands.

4.2. Instances

There is no global state in Vulkan and all per-application state is stored in a VkInstance object. Creating a VkInstance object initializes the Vulkan library and allows the application to pass information about itself to the implementation.

Instances are represented by VkInstance handles:

// Provided by VK_VERSION_1_0
VK_DEFINE_HANDLE(VkInstance)

To query the version of instance-level functionality supported by the implementation, call:

// Provided by VK_VERSION_1_1
VkResult vkEnumerateInstanceVersion(
    uint32_t*                                   pApiVersion);
  • pApiVersion is a pointer to a uint32_t, which is the version of Vulkan supported by instance-level functionality, encoded as described in Version Numbers.

Note

The intended behavior of vkEnumerateInstanceVersion is that an implementation should not need to perform memory allocations and should unconditionally return VK_SUCCESS. The loader, and any enabled layers, may return VK_ERROR_OUT_OF_HOST_MEMORY in the case of a failed memory allocation.

Valid Usage (Implicit)
  • VUID-vkEnumerateInstanceVersion-pApiVersion-parameter
    pApiVersion must be a valid pointer to a uint32_t value

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

To create an instance object, call:

// Provided by VK_VERSION_1_0
VkResult vkCreateInstance(
    const VkInstanceCreateInfo*                 pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkInstance*                                 pInstance);
  • pCreateInfo is a pointer to a VkInstanceCreateInfo structure controlling creation of the instance.

  • pAllocator controls host memory allocation as described in the Memory Allocation chapter.

  • pInstance points a VkInstance handle in which the resulting instance is returned.

vkCreateInstance verifies that the requested layers exist. If not, vkCreateInstance will return VK_ERROR_LAYER_NOT_PRESENT. Next vkCreateInstance verifies that the requested extensions are supported (e.g. in the implementation or in any enabled instance layer) and if any requested extension is not supported, vkCreateInstance must return VK_ERROR_EXTENSION_NOT_PRESENT. After verifying and enabling the instance layers and extensions the VkInstance object is created and returned to the application. If a requested extension is only supported by a layer, both the layer and the extension need to be specified at vkCreateInstance time for the creation to succeed.

Valid Usage
Valid Usage (Implicit)
  • VUID-vkCreateInstance-pCreateInfo-parameter
    pCreateInfo must be a valid pointer to a valid VkInstanceCreateInfo structure

  • VUID-vkCreateInstance-pAllocator-parameter
    If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocationCallbacks structure

  • VUID-vkCreateInstance-pInstance-parameter
    pInstance must be a valid pointer to a VkInstance handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

  • VK_ERROR_INITIALIZATION_FAILED

  • VK_ERROR_LAYER_NOT_PRESENT

  • VK_ERROR_EXTENSION_NOT_PRESENT

  • VK_ERROR_INCOMPATIBLE_DRIVER

The VkInstanceCreateInfo structure is defined as:

// Provided by VK_VERSION_1_0
typedef struct VkInstanceCreateInfo {
    VkStructureType             sType;
    const void*                 pNext;
    VkInstanceCreateFlags       flags;
    const VkApplicationInfo*    pApplicationInfo;
    uint32_t                    enabledLayerCount;
    const char* const*          ppEnabledLayerNames;
    uint32_t                    enabledExtensionCount;
    const char* const*          ppEnabledExtensionNames;
} VkInstanceCreateInfo;
  • sType is a VkStructureType value identifying this structure.

  • pNext is NULL or a pointer to a structure extending this structure.

  • flags is a bitmask of VkInstanceCreateFlagBits indicating the behavior of the instance.

  • pApplicationInfo is NULL or a pointer to a VkApplicationInfo structure. If not NULL, this information helps implementations recognize behavior inherent to classes of applications. VkApplicationInfo is defined in detail below.

  • enabledLayerCount is the number of global layers to enable.

  • ppEnabledLayerNames is a pointer to an array of enabledLayerCount null-terminated UTF-8 strings containing the names of layers to enable for the created instance. The layers are loaded in the order they are listed in this array, with the first array element being the closest to the application, and the last array element being the closest to the driver. See the Layers section for further details.

  • enabledExtensionCount is the number of global extensions to enable.

  • ppEnabledExtensionNames is a pointer to an array of enabledExtensionCount null-terminated UTF-8 strings containing the names of extensions to enable.

Valid Usage
  • VUID-VkInstanceCreateInfo-flags-06559
    If flags has the VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR bit set, the list of enabled extensions in ppEnabledExtensionNames must contain VK_KHR_portability_enumeration

Valid Usage (Implicit)
  • VUID-VkInstanceCreateInfo-sType-sType
    sType must be VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO

  • VUID-VkInstanceCreateInfo-pNext-pNext
    pNext must be NULL or a pointer to a valid instance of VkLayerSettingsCreateInfoEXT

  • VUID-VkInstanceCreateInfo-sType-unique
    The sType value of each struct in the pNext chain must be unique, with the exception of structures of type VkLayerSettingsCreateInfoEXT

  • VUID-VkInstanceCreateInfo-flags-parameter
    flags must be a valid combination of VkInstanceCreateFlagBits values

  • VUID-VkInstanceCreateInfo-pApplicationInfo-parameter
    If pApplicationInfo is not NULL, pApplicationInfo must be a valid pointer to a valid VkApplicationInfo structure

  • VUID-VkInstanceCreateInfo-ppEnabledLayerNames-parameter
    If enabledLayerCount is not 0, ppEnabledLayerNames must be a valid pointer to an array of enabledLayerCount null-terminated UTF-8 strings

  • VUID-VkInstanceCreateInfo-ppEnabledExtensionNames-parameter
    If enabledExtensionCount is not 0, ppEnabledExtensionNames must be a valid pointer to an array of enabledExtensionCount null-terminated UTF-8 strings

// Provided by VK_VERSION_1_0
typedef enum VkInstanceCreateFlagBits {
  // Provided by VK_KHR_portability_enumeration
    VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR = 0x00000001,
} VkInstanceCreateFlagBits;
  • VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR specifies that the instance will enumerate available Vulkan Portability-compliant physical devices and groups in addition to the Vulkan physical devices and groups that are enumerated by default.

// Provided by VK_VERSION_1_0
typedef VkFlags VkInstanceCreateFlags;

VkInstanceCreateFlags is a bitmask type for setting a mask of zero or more VkInstanceCreateFlagBits.

To create a Vulkan instance with a specific configuration of layer settings, add VkLayerSettingsCreateInfoEXT structures to the pNext chain of the VkInstanceCreateInfo structure, specifying the settings to be configured.

// Provided by VK_EXT_layer_settings
typedef struct VkLayerSettingsCreateInfoEXT {
    VkStructureType             sType;
    const void*                 pNext;
    uint32_t                    settingCount;
    const VkLayerSettingEXT*    pSettings;
} VkLayerSettingsCreateInfoEXT;
  • sType is a VkStructureType value identifying this structure.

  • pNext is NULL or a pointer to a structure extending this structure.

  • settingCount is the number of settings to configure.

  • pSettings is a pointer to an array of settingCount VkLayerSettingEXT values specifying the setting to be configured.

Valid Usage (Implicit)
  • VUID-VkLayerSettingsCreateInfoEXT-sType-sType
    sType must be VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT

  • VUID-VkLayerSettingsCreateInfoEXT-pSettings-parameter
    If settingCount is not 0, pSettings must be a valid pointer to an array of settingCount valid VkLayerSettingEXT structures

The values of elements of the VkLayerSettingsCreateInfoEXT::pSettings array, specifying layer settings to be configured, are:

// Provided by VK_EXT_layer_settings
typedef struct VkLayerSettingEXT {
    const char*              pLayerName;
    const char*              pSettingName;
    VkLayerSettingTypeEXT    type;
    uint32_t                 valueCount;
    const void*              pValues;
} VkLayerSettingEXT;
  • pLayerName is a pointer to a null-terminated UTF-8 string naming the layer to configure the setting from.

  • pSettingName is a pointer to a null-terminated UTF-8 string naming the setting to configure. Unknown pSettingName by the layer are ignored.

  • type is a VkLayerSettingTypeEXT value specifying the type of the pValues values.

  • count is the number of values used to configure the layer setting.

  • pValues is a pointer to an array of count values of the type indicated by type to configure the layer setting.

When multiple VkLayerSettingsCreateInfoEXT structures are chained and the same pSettingName is referenced for the same pLayerName, the value of the first reference of the layer setting is used.

Valid Usage (Implicit)
  • VUID-VkLayerSettingEXT-pLayerName-parameter
    pLayerName must be a null-terminated UTF-8 string

  • VUID-VkLayerSettingEXT-pSettingName-parameter
    pSettingName must be a null-terminated UTF-8 string

  • VUID-VkLayerSettingEXT-type-parameter
    type must be a valid VkLayerSettingTypeEXT value

  • VUID-VkLayerSettingEXT-pValues-parameter
    If valueCount is not 0, pValues must be a valid pointer to an array of valueCount bytes

Possible values of VkLayerSettingEXT::type, specifying the type of the data returned in VkLayerSettingEXT::pValues, are:

// Provided by VK_EXT_layer_settings
typedef enum VkLayerSettingTypeEXT {
    VK_LAYER_SETTING_TYPE_BOOL32_EXT = 0,
    VK_LAYER_SETTING_TYPE_INT32_EXT = 1,
    VK_LAYER_SETTING_TYPE_INT64_EXT = 2,
    VK_LAYER_SETTING_TYPE_UINT32_EXT = 3,
    VK_LAYER_SETTING_TYPE_UINT64_EXT = 4,
    VK_LAYER_SETTING_TYPE_FLOAT32_EXT = 5,
    VK_LAYER_SETTING_TYPE_FLOAT64_EXT = 6,
    VK_LAYER_SETTING_TYPE_STRING_EXT = 7,
} VkLayerSettingTypeEXT;
  • VK_LAYER_SETTING_TYPE_BOOL32_EXT specifies that the layer setting’s type is VkBool32.

  • VK_LAYER_SETTING_TYPE_INT32_EXT specifies that the layer setting’s type is signed 32-bit integer.

  • VK_LAYER_SETTING_TYPE_INT64_EXT specifies that the layer setting’s type is signed 64-bit integer.

  • VK_LAYER_SETTING_TYPE_UINT32_EXT specifies that the layer setting’s type is unsigned 32-bit integer.

  • VK_LAYER_SETTING_TYPE_UINT64_EXT specifies that the layer setting’s type is unsigned 64-bit integer.

  • VK_LAYER_SETTING_TYPE_FLOAT32_EXT specifies that the layer setting’s type is 32-bit floating-point.

  • VK_LAYER_SETTING_TYPE_FLOAT64_EXT specifies that the layer setting’s type is 64-bit floating-point.

  • VK_LAYER_SETTING_TYPE_STRING_EXT specifies that the layer setting’s type is a pointer to a null-terminated UTF-8 string.

The VkApplicationInfo structure is defined as:

// Provided by VK_VERSION_1_0
typedef struct VkApplicationInfo {
    VkStructureType    sType;
    const void*        pNext;
    const char*        pApplicationName;
    uint32_t           applicationVersion;
    const char*        pEngineName;
    uint32_t           engineVersion;
    uint32_t           apiVersion;
} VkApplicationInfo;
  • sType is a VkStructureType value identifying this structure.

  • pNext is NULL or a pointer to a structure extending this structure.

  • pApplicationName is NULL or is a pointer to a null-terminated UTF-8 string containing the name of the application.

  • applicationVersion is an unsigned integer variable containing the developer-supplied version number of the application.

  • pEngineName is NULL or is a pointer to a null-terminated UTF-8 string containing the name of the engine (if any) used to create the application.

  • engineVersion is an unsigned integer variable containing the developer-supplied version number of the engine used to create the application.

  • apiVersion must be the highest version of Vulkan that the application is designed to use, encoded as described in Version Numbers. The patch version number specified in apiVersion is ignored when creating an instance object. The variant version of the instance must match that requested in apiVersion.

Vulkan 1.0 implementations were required to return VK_ERROR_INCOMPATIBLE_DRIVER if apiVersion was larger than 1.0. Implementations that support Vulkan 1.1 or later must not return VK_ERROR_INCOMPATIBLE_DRIVER for any value of apiVersion .

Note

Because Vulkan 1.0 implementations may fail with VK_ERROR_INCOMPATIBLE_DRIVER, applications should determine the version of Vulkan available before calling vkCreateInstance. If the vkGetInstanceProcAddr returns NULL for vkEnumerateInstanceVersion, it is a Vulkan 1.0 implementation. Otherwise, the application can call vkEnumerateInstanceVersion to determine the version of Vulkan.

As long as the instance supports at least Vulkan 1.1, an application can use different versions of Vulkan with an instance than it does with a device or physical device.

Note

The Khronos validation layers will treat apiVersion as the highest API version the application targets, and will validate API usage against the minimum of that version and the implementation version (instance or device, depending on context). If an application tries to use functionality from a greater version than this, a validation error will be triggered.

For example, if the instance supports Vulkan 1.1 and three physical devices support Vulkan 1.0, Vulkan 1.1, and Vulkan 1.2, respectively, and if the application sets apiVersion to 1.2, the application can use the following versions of Vulkan:

  • Vulkan 1.0 can be used with the instance and with all physical devices.

  • Vulkan 1.1 can be used with the instance and with the physical devices that support Vulkan 1.1 and Vulkan 1.2.

  • Vulkan 1.2 can be used with the physical device that supports Vulkan 1.2.

If we modify the above example so that the application sets apiVersion to 1.1, then the application must not use Vulkan 1.2 functionality on the physical device that supports Vulkan 1.2.

Note

Providing a NULL VkInstanceCreateInfo::pApplicationInfo or providing an apiVersion of 0 is equivalent to providing an apiVersion of VK_MAKE_API_VERSION(0,1,0,0).

Valid Usage
  • VUID-VkApplicationInfo-apiVersion-04010
    If apiVersion is not 0, then it must be greater than or equal to VK_API_VERSION_1_0

Valid Usage (Implicit)
  • VUID-VkApplicationInfo-sType-sType
    sType must be VK_STRUCTURE_TYPE_APPLICATION_INFO

  • VUID-VkApplicationInfo-pNext-pNext
    pNext must be NULL

  • VUID-VkApplicationInfo-pApplicationName-parameter
    If pApplicationName is not NULL, pApplicationName must be a null-terminated UTF-8 string

  • VUID-VkApplicationInfo-pEngineName-parameter
    If pEngineName is not NULL, pEngineName must be a null-terminated UTF-8 string

To destroy an instance, call:

// Provided by VK_VERSION_1_0
void vkDestroyInstance(
    VkInstance                                  instance,
    const VkAllocationCallbacks*                pAllocator);
  • instance is the handle of the instance to destroy.

  • pAllocator controls host memory allocation as described in the Memory Allocation chapter.

Valid Usage
  • VUID-vkDestroyInstance-instance-00629
    All child objects created using instance must have been destroyed prior to destroying instance

  • VUID-vkDestroyInstance-instance-00630
    If VkAllocationCallbacks were provided when instance was created, a compatible set of callbacks must be provided here

  • VUID-vkDestroyInstance-instance-00631
    If no VkAllocationCallbacks were provided when instance was created, pAllocator must be NULL

Valid Usage (Implicit)
  • VUID-vkDestroyInstance-instance-parameter
    If instance is not NULL, instance must be a valid VkInstance handle

  • VUID-vkDestroyInstance-pAllocator-parameter
    If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocationCallbacks structure

Host Synchronization
  • Host access to instance must be externally synchronized

  • Host access to all VkPhysicalDevice objects enumerated from instance must be externally synchronized