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;