Acquiring, Presenting, Cleaning Up
For this chapter, we'll be focusing on:
- Acquiring the next image in the swapchain
- Presenting images
- Cleaning up when we're done with the swapchain
Acquiring the Next Image
For this section, we'll be writing a small helper method. The definition looks like this:
void getSwapchainNext(VkSemaphore presentCompleteSemaphore, uint32_t buffer) {}
We already have the function pointer from earlier called fpAcquireNextImageKHR. This has the same definition as vkAcquireNextImageKHR.
Definition for vkAcquireNextImageKHR:
VkResult vkAcquireNextImageKHR(
VkDevice device,
VkSwapchainKHR swapchain,
uint64_t timeout,
VkSemaphore semaphore,
VkFence fence,
uint32_t* pImageIndex);
Documentation for vkAcquireNextImageKHR:
deviceis the device assocated with swapchain.swapchainis the swapchain from which an image is being acquired.timeoutindicates how long the function waits, in nanoseconds, if no image is available.semaphoreisVK_NULL_HANDLEor a semaphore to signal.fenceisVK_NULL_HANDLEor a fence to signal.pImageIndexis a pointer to auint32_tthat is set to the index of the next image to use (i.e. an index into the array of images returned byvkGetSwapchainImagesKHR).
Usage for vkAcquireNextImageKHR:
VkResult result =
fpAcquireNextImageKHR(device, swapchain, UINT64_MAX,
presentCompleteSemaphore, (VkFence)0, &buffer);
assert(result == VK_SUCCESS);
Swapchain Image Presentation
For this section and the next, we'll be writing the body of this method:
void swapchainPresent(VkCommandBuffer cmdBuffer, VkQueue queue,
uint32_t buffer) {}
In order for the swapchain to present images, we'll have to inform Vulkan of some things. We can use VkPresentInfoKHR to do this.
Definition for VkPresentInfoKHR:
typedef struct VkPresentInfoKHR {
VkStructureType sType;
const void* pNext;
uint32_t waitSemaphoreCount;
const VkSemaphore* pWaitSemaphores;
uint32_t swapchainCount;
const VkSwapchainKHR* pSwapchains;
const uint32_t* pImageIndices;
VkResult* pResults;
} VkPresentInfoKHR;
Documentation for VkPresentInfoKHR:
sTypeis the type of this structure and must beVK_STRUCTURE_TYPE_PRESENT_INFO_KHR.pNextisNULLor a pointer to an extension-specific structure.waitSemaphoreCountis the number of semaphores to wait for before issuing the present request. The number may be zero.pWaitSemaphores, if non-NULL, is an array ofVkSemaphoreobjects withwaitSemaphoreCountentries, and specifies the semaphores to wait for before issuing the present request.swapchainCountis the number of swapchains being presented to by this command.pSwapchainsis an array ofVkSwapchainKHRobjects withswapchainCountentries. A given swapchain must not appear in this list more than once.pImageIndicesis an array of indices into the array of each swapchain’s presentable images, withswapchainCountentries. Each entry in this array identifies the image to present on the corresponding entry in thepSwapchainsarray.pResultsis an array ofVkResulttyped elements withswapchainCountentries. Applications that don’t need per-swapchain results can useNULLfor pResults. If non-NULL, each entry inpResultswill be set to theVkResultfor presenting the swapchain corresponding to the same index inpSwapchains.
Usage for VkPresentInfoKHR:
VkPresentInfoKHR presentInfo = {};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.pNext = NULL;
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = &swapchain;
presentInfo.pImageIndices = &buffer;
Queue Presentation
As the last part of the swapchainPresent method, we actually get to present! We'll be using the function pointer from earlier called fpQueuePresentKHR which has the definition is the same as vkQueuePresentKHR.
Definition for vkQueuePresentKHR:
VkResult vkQueuePresentKHR(
VkQueue queue,
const VkPresentInfoKHR* pPresentInfo);
Documentation for vkQueuePresentKHR:
queueis a queue that is capable of presentation to the target surface’s platform on the same device as the image’s swapchain.pPresentInfois a pointer to an instance of theVkPresentInfoKHRstructure specifying the parameters of the presentation.
Usage for vkQueuePresentKHR:
VkResult result = fpQueuePresentKHR(queue, &presentInfo);
assert(result == VK_SUCCESS);
Cleaning Up
For our new destructor, we will:
- Destroy all image views we stored
- Destroy the swapchain
- Destroy the surface
- Destroy the instance
That can be done easily with the following lines of code:
for (SwapChainBuffer buffer : buffers)
vkDestroyImageView(device, buffer.view, NULL);
fpDestroySwapchainKHR(device, swapchain, NULL);
vkDestroySurfaceKHR(instance, surface, NULL);
vkDestroyInstance(instance, NULL);