19 Swapchain::Swapchain(
Surface* surface, glm::ivec2 size) {
20 VkDevice device = VulkanContext::getCurrent()->getDevice()->getHandle();
21 SwapchainSupportDetails swapchainSupportDetail = VulkanContext::getCurrent()->getPhysicalDevice()->getSwapchainSupportDetails();
24 VkSurfaceFormatKHR surfaceFormat = swapchainSupportDetail.
surfaceFormats[0];
26 swapchainSupportDetail.
surfaceFormats[0].format == VK_FORMAT_UNDEFINED) {
27 surfaceFormat.format = VK_FORMAT_B8G8R8A8_UNORM;
28 surfaceFormat.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
31 for (uint32_t i = 0; i < swapchainSupportDetail.
surfaceFormats.size(); i++) {
32 VkSurfaceFormatKHR surfaceFormatCandidate = swapchainSupportDetail.
surfaceFormats[i];
33 if (surfaceFormatCandidate.format == VK_FORMAT_B8G8R8A8_UNORM &&
34 surfaceFormatCandidate.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
35 surfaceFormat = surfaceFormatCandidate;
42 VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR;
43 for (uint32_t i = 0; i < swapchainSupportDetail.
presentModes.size(); i++) {
44 VkPresentModeKHR presentModeCandidate = swapchainSupportDetail.
presentModes[i];
45 if (presentModeCandidate == VK_PRESENT_MODE_MAILBOX_KHR) {
46 presentMode = presentModeCandidate;
48 }
else if (presentModeCandidate == VK_PRESENT_MODE_IMMEDIATE_KHR) {
49 presentMode = presentModeCandidate;
54 VkExtent2D extent = {
static_cast<uint32_t
> (size.x), static_cast<uint32_t> (size.y)};
55 if (swapchainSupportDetail.
surfaceCapabilities.currentExtent.width != numeric_limits<uint32_t>::max()) {
73 QueueFamilyIndices queueFamilyIndices = VulkanContext::getCurrent()->getPhysicalDevice()->getQueueFamilyIndices();
74 vector<uint32_t> queueFamilyIndicesVector = {
75 static_cast<uint32_t
> (queueFamilyIndices.
graphics),
78 VkSwapchainCreateInfoKHR createInfo = {};
79 createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
80 createInfo.surface = surface->
getHandle();
81 createInfo.minImageCount = imageCount;
82 createInfo.imageFormat = surfaceFormat.format;
83 createInfo.imageColorSpace = surfaceFormat.colorSpace;
84 createInfo.imageExtent = extent;
85 createInfo.imageArrayLayers = 1;
86 createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
88 createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
89 createInfo.queueFamilyIndexCount = queueFamilyIndicesVector.size();
90 createInfo.pQueueFamilyIndices = queueFamilyIndicesVector.data();
92 createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
95 createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
96 createInfo.presentMode = presentMode;
97 createInfo.clipped = VK_TRUE;
98 createInfo.oldSwapchain = VK_NULL_HANDLE;
101 if (vkCreateSwapchainKHR(device, &createInfo,
nullptr, &handle) != VK_SUCCESS) {
102 throw runtime_error(
"Could not create a swapchain!");
106 vkGetSwapchainImagesKHR(device, handle, &imageCount,
nullptr);
109 swapchainData.images.resize(imageCount);
110 vkGetSwapchainImagesKHR(device, handle, &imageCount, swapchainData.images.data());
113 swapchainData.imageViews.resize(swapchainData.images.size());
114 for (uint32_t i = 0; i < swapchainData.images.size(); i++) {
116 VkImageViewCreateInfo viewCreateInfo = {};
117 viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
118 viewCreateInfo.image = swapchainData.images[i];
119 viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
120 viewCreateInfo.format = surfaceFormat.format;
121 viewCreateInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
122 viewCreateInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
123 viewCreateInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
124 viewCreateInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
125 viewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
126 viewCreateInfo.subresourceRange.baseMipLevel = 0;
127 viewCreateInfo.subresourceRange.levelCount = 1;
128 viewCreateInfo.subresourceRange.baseArrayLayer = 0;
129 viewCreateInfo.subresourceRange.layerCount = 1;
132 if (vkCreateImageView(device, &viewCreateInfo,
nullptr, &swapchainData.imageViews[i]) != VK_SUCCESS) {
133 throw runtime_error(
"Could not create image views for the swapchain images!");
138 swapchainData.imageFormat = surfaceFormat.format;
139 swapchainData.extent = extent;
140 swapchainData.index = -1;
143 Swapchain::~Swapchain(
void) {
144 VkDevice device = VulkanContext::getCurrent()->getDevice()->getHandle();
147 for (uint32_t i = 0; i < swapchainData.imageViews.size(); i++) {
148 vkDestroyImageView(device, swapchainData.imageViews[i],
nullptr);
152 vkDestroySwapchainKHR(device, handle,
nullptr);
155 VkSwapchainKHR Swapchain::getHandle() {
160 return swapchainData;
163 void Swapchain::acquireNextImage() {
164 VkDevice device = VulkanContext::getCurrent()->getDevice()->getHandle();
165 VkFence fence = VulkanContext::getCurrent()->getRenderFence()->getHandle();
168 vkWaitForFences(device, 1, &fence, VK_TRUE, std::numeric_limits<uint64_t>::max());
169 vkResetFences(device, 1, &fence);
172 VkResult result = vkAcquireNextImageKHR(device, handle, numeric_limits<uint64_t>::max(), VK_NULL_HANDLE, fence, &swapchainData.index);
175 if (result == VK_ERROR_OUT_OF_DATE_KHR) {
177 }
else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
178 throw runtime_error(
"Could not acquire next swapchain image!");
182 void Swapchain::present() {
183 VkQueue queue = VulkanContext::getCurrent()->getDevice()->getQueues().presentation;
186 VkPresentInfoKHR presentInfo = {};
187 presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
188 presentInfo.swapchainCount = 1;
189 presentInfo.pSwapchains = &handle;
190 presentInfo.pImageIndices = &swapchainData.index;
193 VkResult result = vkQueuePresentKHR(queue, &presentInfo);
196 if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
198 }
else if (result != VK_SUCCESS) {
199 throw runtime_error(
"Could not present swapchain image!");
int32_t presentation
The index of the presentation queue family.
This struct stores relevant queue family indices.
std::vector< VkSurfaceFormatKHR > surfaceFormats
The supported surface formats.
This struct stores necessary data for swapchain support.
Generic namespace for the SimpleGL framework.
VkSurfaceKHR getHandle()
Returns the hande of the surface.
This struct stores relevant swapchain data.
VkSurfaceCapabilitiesKHR surfaceCapabilities
The basic capabilities of a surface.
std::vector< VkPresentModeKHR > presentModes
The supported present modes.
int32_t graphics
The index of the graphics queue family.
This class wraps a Vulkan surface.