Initialising Objects in Vulkan

A brief summary of how initialisation works in Vulkan.

Initialising Vulkan applications is a considerably longer process than other higher-level APIs, such as OpenGL ES, due to its more verbose nature. All Vulkan objects have to be explicitly defined and initialised - there are no defaults to fall back on. Tasks such as memory allocation have to be managed directly by the developer rather than the driver handling it quietly in the background.

The section below demonstrates the standard approach to object initialisation.

How to initialise objects in Vulkan

Most objects in Vulkan are created using a creation struct and a vkCreate... function. A creation struct contains details about the object that is going to be created. This struct is then passed to the vkCreate... function along with a pointer to the handle in which the actual object instance will be returned. Almost all Vulkan objects are initialised in this way so many of the setup functions shown in this example will follow the same pattern.

An example is shown below:
   
    VkDeviceCreateInfo deviceInfo; // This is the creation struct.
    
    // These are the properties of the object that is going to be created.
    deviceInfo.flags = 0;
    deviceInfo.pNext = nullptr;
    deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
    deviceInfo.enabledLayerCount = 0;
    deviceInfo.ppEnabledLayerNames = nullptr;
    deviceInfo.enabledExtensionCount = static_cast<uint32_t>(appManager.deviceExtensionNames.size());
    deviceInfo.ppEnabledExtensionNames = appManager.deviceExtensionNames.data();
    deviceInfo.queueCreateInfoCount = 1;
    deviceInfo.pQueueCreateInfos = &deviceQueueInfo;
    deviceInfo.pEnabledFeatures = &features;
    
    // This is a vkCreate.. function.
    // appManager.device is where the object will be stored when created.
    vkCreateDevice(appManager.physicalDevice, &deviceInfo, nullptr, &appManager.device)
           

The creation struct here is called deviceInfo. The members of different creation structs vary depending on the type of object being created but there are three members which are common to all: sType, pNext, and flags.

  • sType is the type of creation struct. This is usually set with an enum of type VkStructureType.
  • pNext is used in the case where a Vulkan extension requires extra information when setting up an object. pNext points to another struct which contains this additional information. The original struct is therefore unaffected by the extension. Throughout this tutorial this pointer will always be set to NULL.
  • flags is used to pass additional information. In this case and most other cases this member is reserved for future use and is set to zero.

There is no need to worry about the details of this particular example yet. It will be explained in the following section.

All initialisation in this example will take place in the following three sections: "Initialising Vulkan", "Preparing to Present to the Screen" and "Getting Ready to Render".