## 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. Loaders are encouraged to export function symbols for all other core Vulkan commands as well; if this is done, then applications that use only the core Vulkan commands have no need to use `vkGetInstanceProcAddr`.

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 3.1. vkGetInstanceProcAddr behavior

`instance` | `pName` | return value
--- | --- | ---
* | `NULL` | undefined
invalid instance | * | undefined
`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 extension” is an extension function supported by any of the loader, driver or layer.

In order to support systems with multiple Vulkan implementations comprising heterogeneous collections of hardware and software, the function pointers returned by `vkGetInstanceProcAddr` may point to dispatch code, which calls a different real implementation for different `VkDevice` objects (and objects created from them). The overhead of this internal dispatch 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.

Table 3.2. vkGetDeviceProcAddr behavior

`device` | `pName` | return value
--- | --- | ---
`NULL` | * | undefined
invalid device | * | undefined
device | `NULL` | undefined
device | core Vulkan command | fp1
device | enabled extension commands | fp1
device | * (any `pName` not covered above) | `NULL`

1
  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`.

The definition of `PFN_vkVoidFunction` is:

    typedef void (VKAPI_PTR *PFN_vkVoidFunction)(void);