Creating a Vulkan Instance
A Vulkan Instance is an object that gathers the state of an application. It encloses information such as an application name, name and version of an engine used to create an application, or enabled instance-level extensions and layers.
Through the Instance, we can also enumerate available physical devices and create logical devices on which typical operations such as image creation or drawing are performed. So, before we proceed with using the Vulkan API, we need to create a new Instance object.
How to do it...
- Prepare a variable of type
std::vector<char const *>nameddesired_extensions. Store the names of all extensions you want to enable in thedesired_extensionsvariable. - Create a variable of type
std::vector<VkExtensionProperties>namedavailable_extensions. Acquire the list of all available extensions and store it in theavailable_extensionsvariable (refer to the Checking available Instance extensions recipe).
- Make sure that the name of each extension from the
desired_extensionsvariable is also present in theavailable_extensionsvariable. - Prepare a variable of type
VkApplicationInfonamedapplication_info. Assign the following values for members of theapplication_infovariable:VK_STRUCTURE_TYPE_APPLICATION_INFOvalue forsType.nullptrvalue forpNext.- Name of your application for
pApplicationName. - Version of your application for the
applicationVersionstructure member; do that by usingVK_MAKE_VERSIONmacro and specifying major, minor, and patch values in it. - Name of the engine used to create an application for
pEngineName. - Version of the engine used to create an application for
engineVersion; do that by usingVK_MAKE_VERSIONmacro. VK_MAKE_VERSION( 1, 0, 0 )forapiVersion.
- Create a variable of type
VkInstanceCreateInfonamedinstance_create_info. Assign the following values for members of theinstance_create_infovariable:VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFOvalue forsType.nullptrvalue forpNext.0value forflags.- Pointer to the
application_infovariable inpApplicationInfo. 0value forenabledLayerCount.nullptrvalue forppEnabledLayerNames.- Number of elements of the
desired_extensionsvector forenabledExtensionCount. - Pointer to the first element of the
desired_extensionsvector (ornullptrif is empty) forppEnabledExtensionNames.
- Create a variable of type
VkInstancenamedinstance. - Call the
vkCreateInstance( &instance_create_info, nullptr, &instance )function. Provide a pointer to theinstance_create_infovariable in the first parameter, anullptrvalue in the second, and a pointer to theinstancevariable in the third parameter. - Make sure the operation was successful by checking whether the value returned by the
vkCreateInstance()function call is equal toVK_SUCCESS.
How it works...
To create an Instance, we need to prepare some information. First, we need to create an array of names of instance-level extensions that we would like to enable. Next, we need to check if they are supported on a given hardware. This is done by acquiring the list of all available instance-level extensions and checking if it contains the names of all the extensions we want to enable:
std::vector<VkExtensionProperties> available_extensions;
if( !CheckAvailableInstanceExtensions( available_extensions ) ) {
return false;
}
for( auto & extension : desired_extensions ) {
if( !IsExtensionSupported( available_extensions, extension ) ) {
std::cout << "Extension named '" << extension << "' is not supported." << std::endl;
return false;
}
}Next, we need to create a variable in which we will provide information about our application, such as its name and version, the name and version of an engine used to create an application, and the version of a Vulkan API we want to use (right now only the first version is supported by the API):
VkApplicationInfo application_info = {
VK_STRUCTURE_TYPE_APPLICATION_INFO,
nullptr,
application_name,
VK_MAKE_VERSION( 1, 0, 0 ),
"Vulkan Cookbook",
VK_MAKE_VERSION( 1, 0, 0 ),
VK_MAKE_VERSION( 1, 0, 0 )
};
The pointer to the application_info variable in the preceding code sample is provided in a second variable with the actual parameters used to create an Instance. In it, apart from the previously mentioned pointer, we provide information about the number and names of extensions we want to enable, and also the number and names of layers we want to enable. Neither extensions nor layers are required to create a valid Instance object and we can skip them. However, there are very important extensions, without which it will be hard to create a fully functional application, so it is recommended to use them. Layers may be safely omitted. Following is the sample code preparing a variable used to define Instance parameters:
VkInstanceCreateInfo instance_create_info = {
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
nullptr,
0,
&application_info,
0,
nullptr,
static_cast<uint32_t>(desired_extensions.size()),
desired_extensions.size() > 0 ? &desired_extensions[0] : nullptr
};Finally, when we have prepared the preceding data, we can create an Instance object. This is done with the vkCreateInstance() function. Its first parameter must point to the variable of type VkInstanceCreateInfo. The third parameter must point to a variable of type VkInstance. The created Instance handle will be stored in it. The second parameter is very rarely used: It may point to a variable of type VkAllocationCallbacks, in which allocator callback functions are defined. These functions control the way host memory is allocated and are mainly used for debugging purposes. Most of the time, the second parameter defining allocation callbacks can be set to nullptr:
VkResult result = vkCreateInstance( &instance_create_info, nullptr, &instance );
if( (result != VK_SUCCESS) ||
(instance == VK_NULL_HANDLE) ) {
std::cout << "Could not create Vulkan Instance." << std::endl;
return false;
}
return true;
See also
- The following recipes in this chapter:
- Checking available Instance extensions
- Destroying a Vulkan Instance
- The following recipe in Chapter 2, Image Presentation:
- Creating a Vulkan Instance with WSI extensions enabled