3. Initialization

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

3.1. Command Function Pointers

Vulkan commands are not necessarily exposed statically on a platform. Function pointers for all Vulkan commands can be obtained with the command:

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.

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

Table 1. vkGetInstanceProcAddr behavior
instance pName return value

*

NULL

undefined

invalid instance

*

undefined

NULL

vkEnumerateInstanceVersion

fp

NULL

vkEnumerateInstanceExtensionProperties

fp

NULL

vkEnumerateInstanceLayerProperties

fp

NULL

vkCreateInstance

fp

NULL

* (any pName not covered above)

NULL

instance

core Vulkan command

fp1

instance

enabled instance extension commands for instance

fp1

instance

available device extension2 commands for instance

fp1

instance

* (any pName not covered above)

NULL

1

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.

2

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

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

  • 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 with the command:

PFN_vkVoidFunction vkGetDeviceProcAddr(
    VkDevice                                    device,
    const char*                                 pName);

The table below defines the various use cases for vkGetDeviceProcAddr and expected return value for each case.

The returned function pointer is of type PFN_vkVoidFunction, and must be cast to the type of the command being queried. 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

*

undefined

invalid device

*

undefined

device

NULL

undefined

device

core device-level Vulkan command

fp

device

enabled device extension commands

fp

device

* (any pName not covered above)

NULL

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • pName must be a null-terminated UTF-8 string

The definition of PFN_vkVoidFunction is:

typedef void (VKAPI_PTR *PFN_vkVoidFunction)(void);

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

3.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. Behavior is undefined if an extension physical-device command is called on a physical device that does not support the extension.

Device extensions may define structures that can be added to the pNext chain of physical-device-level commands. Behavior is undefined if such an extension structure is passed to a physical-device-level command for a physical device that does not support the extension.

3.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:

VK_DEFINE_HANDLE(VkInstance)

The version of Vulkan that is supported by an instance may be different than the version of Vulkan supported by a device or physical device. To query properties that can be used in creating an instance, call:

VkResult vkEnumerateInstanceVersion(
    uint32_t*                                   pApiVersion);
  • pApiVersion points to a uint32_t, which is the version of Vulkan supported by instance-level functionality, encoded as described in the API Version Numbers and Semantics section.

Valid Usage (Implicit)
  • pApiVersion must be a valid pointer to a uint32_t value

Return Codes
Success
  • VK_SUCCESS

To create an instance object, call:

VkResult vkCreateInstance(
    const VkInstanceCreateInfo*                 pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkInstance*                                 pInstance);
  • pCreateInfo points to an instance of VkInstanceCreateInfo 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)
  • pCreateInfo must be a valid pointer to a valid VkInstanceCreateInfo structure

  • If pAllocator is not NULL, pAllocator must be a valid pointer to a valid VkAllocationCallbacks structure

  • 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:

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 the type of this structure.

  • pNext is NULL or a pointer to an extension-specific structure.

  • flags is reserved for future use.

  • pApplicationInfo is NULL or a pointer to an instance of VkApplicationInfo. 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. 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 (Implicit)
  • sType must be VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO

  • Each pNext member of any structure (including this one) in the pNext chain must be either NULL or a pointer to a valid instance of VkDebugReportCallbackCreateInfoEXT, VkDebugUtilsMessengerCreateInfoEXT, or VkValidationFlagsEXT

  • Each sType member in the pNext chain must be unique

  • flags must be 0

  • If pApplicationInfo is not NULL, pApplicationInfo must be a valid pointer to a valid VkApplicationInfo structure

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

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

typedef VkFlags VkInstanceCreateFlags;

VkInstanceCreateFlags is a bitmask type for setting a mask, but is currently reserved for future use.

When creating a Vulkan instance for which you wish to disable validation checks, add a VkValidationFlagsEXT structure to the pNext chain of the VkInstanceCreateInfo structure, specifying the checks to be disabled.

typedef struct VkValidationFlagsEXT {
    VkStructureType                sType;
    const void*                    pNext;
    uint32_t                       disabledValidationCheckCount;
    const VkValidationCheckEXT*    pDisabledValidationChecks;
} VkValidationFlagsEXT;
  • sType is the type of this structure.

  • pNext is NULL or a pointer to an extension-specific structure.

  • disabledValidationCheckCount is the number of checks to disable.

  • pDisabledValidationChecks is a pointer to an array of VkValidationCheckEXT values specifying the validation checks to be disabled.

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT

  • pDisabledValidationChecks must be a valid pointer to an array of disabledValidationCheckCount valid VkValidationCheckEXT values

  • disabledValidationCheckCount must be greater than 0

Possible values of elements of the VkValidationFlagsEXT::pDisabledValidationChecks array, specifying validation checks to be disabled, are:

typedef enum VkValidationCheckEXT {
    VK_VALIDATION_CHECK_ALL_EXT = 0,
    VK_VALIDATION_CHECK_SHADERS_EXT = 1,
} VkValidationCheckEXT;
  • VK_VALIDATION_CHECK_ALL_EXT specifies that all validation checks are disabled.

  • VK_VALIDATION_CHECK_SHADERS_EXT specifies that shader validation is disabled.

The VkApplicationInfo structure is defined as:

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 the type of this structure.

  • pNext is NULL or a pointer to an extension-specific 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 the API Version Numbers and Semantics section. The patch version number specified in apiVersion is ignored when creating an instance object. Only the major and minor versions of the instance must match those 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.

Implicit layers must be disabled if they do not support a version at least as high as apiVersion. See the Vulkan Loader Specification and Architecture Overview document for additional information.

Note

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

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_APPLICATION_INFO

  • pNext must be NULL

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

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

To destroy an instance, call:

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
  • All child objects created using instance must have been destroyed prior to destroying instance

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

  • If no VkAllocationCallbacks were provided when instance was created, pAllocator must be NULL

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

  • 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