Chronos 0.0
A advanced 2D rendering and animation system
Loading...
Searching...
No Matches
Chronos::Engine::SwapChain Class Reference

#include <swapchain.hpp>

Collaboration diagram for Chronos::Engine::SwapChain:

Public Member Functions

void init (Chronos::Engine::Device *device, VkSurfaceKHR surface, GLFWwindow *window)
 Initilize the swapchain.
 
void recreate ()
 When the swapchain is rendered invalid, recreate it.
 
void cleanup ()
 Cleans up the assets that are rendered invalid during MSAA changes or swapchain.
 
void changeMsaa ()
 Changes the MSAA count of the swapchain images.
 

Public Attributes

VkExtent2D swapChainExtent
 Dimenisons of the current swapchain.
 
VkSwapchainKHR swapChain
 Vulkan swapchain object.
 
VkSurfaceKHR surface
 Surface to which we need to present the swapchain images.
 
std::vector< VkImageView > swapChainImageViews
 Image views of the swapchain textures(images, aka window)
 
VkImageView colorImageView
 image view of the color attachement
 
VkFormat swapChainImageFormat
 Chosen swapchain image format.
 
VkPresentModeKHR preferredPresentMode = VK_PRESENT_MODE_MAILBOX_KHR
 Preferred present mode for the swapchain.
 
bool changePresentMode = false
 

Private Member Functions

void create ()
 Creates the swapchain image resources and chooses the optimal settings for given hardware.
 
void createImageViews ()
 Creates the image views of the swapchain images.
 
void createColorResources ()
 Creates the color images along with the associated objects.
 
VkPresentModeKHR chooseSwapPresentMode (const std::vector< VkPresentModeKHR > &availablePresentModes)
 From the available present mode, this chooses the the best present mode.
 

Private Attributes

Chronos::Engine::Devicedevice
 Device to which swapchain needs to be created.
 
GLFWwindow * window
 The window to present the surface to.
 
VkImage colorImage
 The color image.
 
VkDeviceMemory colorImageMemory
 Memory to store the color image.
 
std::vector< VkImage > swapChainImages
 Swapchaim images to render and present to.
 

Detailed Description

/brief Responsible for initializing, managing, recreating and presenting the swapchain images.

In Vulkan, we render to images(texture). These images are then present to the GLFW window. Since there will be multiple images in flight, along with multiple other assets for this, we need to manage these assets.

Definition at line 99 of file swapchain.hpp.

Member Function Documentation

◆ changeMsaa()

void Chronos::Engine::SwapChain::changeMsaa ( )

Changes the MSAA count of the swapchain images.

When the user decides to change the MSAA, we need to recreate the swapchain. This does it.

Definition at line 223 of file swapchain.cpp.

224{
225 // if we want to change msaa, we need to recreate the swapchain
226 vkDeviceWaitIdle(device->device);
227 cleanup();
228 create();
231}
VkDevice device
This is the logical device that is used by Vulkan.
Definition device.hpp:52
void createImageViews()
Creates the image views of the swapchain images.
Chronos::Engine::Device * device
Device to which swapchain needs to be created.
void create()
Creates the swapchain image resources and chooses the optimal settings for given hardware.
void cleanup()
Cleans up the assets that are rendered invalid during MSAA changes or swapchain.
void createColorResources()
Creates the color images along with the associated objects.

◆ chooseSwapPresentMode()

VkPresentModeKHR Chronos::Engine::SwapChain::chooseSwapPresentMode ( const std::vector< VkPresentModeKHR > &  availablePresentModes)
private

From the available present mode, this chooses the the best present mode.

If available VK_PRESENT_MODE_MAILBOX_KHR will be chosen.

Some of the presentation modes available are:

  • VK_PRESENT_MODE_IMMEDIATE_KHR: Images submitted by your application are transferred to the screen right away, which may result in tearing.
  • VK_PRESENT_MODE_FIFO_KHR : The swap chain is a queue where the display takes an image from the front of the queue when the display is refreshed and the program inserts rendered images at the back of the queue.If the queue is full then the program has to wait. This is most similar to vertical sync as found in modern games.The moment that the display is refreshed is known as "vertical blank".
  • VK_PRESENT_MODE_FIFO_RELAXED_KHR : This mode only differs from the previous one if the application is late and the queue was empty at the last vertical blank. Instead of waiting for the next vertical blank, the image is transferred right away when it finally arrives.This may result in visible tearing.
  • VK_PRESENT_MODE_MAILBOX_KHR : This is another variation of the second mode.Instead of blocking the application when the queue is full, the images that are already queued are simply replaced with the newer ones.This mode can be used to render frames as fast as possible while still avoiding tearing, resulting in fewer latency issues than standard vertical sync.This is commonly known as "triple buffering", although the existence of three buffers alone does not necessarily mean that the framerate
Parameters
availablePresentModesThe available present modes to choose from.
Returns
The best present mode based on availability and preference.

Definition at line 233 of file swapchain.cpp.

235{
236 // The presentation modes available
237 // VK_PRESENT_MODE_IMMEDIATE_KHR: Images submitted by your application are
238 // transferred to the screen right away, which may result in tearing.
239 // VK_PRESENT_MODE_FIFO_KHR : The swap chain is a queue where the display
240 // takes an image from the front of the queue when the display is refreshed
241 // and the program inserts
242 // rendered images at the
243 // back of the queue.If the queue is full then the program has to wait.
244 // This is most similar to vertical sync as found in modern games.The moment
245 // that the display is refreshed is known as
246 // "vertical blank". VK_PRESENT_MODE_FIFO_RELAXED_KHR : This mode only
247 // differs from the previous one if the application is late and the queue
248 // was empty at the last
249 // vertical blank.Instead of waiting for the next vertical blank, the image
250 // is transferred right away when it
251 // finally arrives.This may result in visible tearing.
252 // VK_PRESENT_MODE_MAILBOX_KHR : This is another variation of the second
253 // mode.Instead of blocking the application when the queue is full, the
254 // images that are already
255 // queued are simply replaced with the newer ones.This mode can be used to
256 // render frames as fast as
257 // possible while still avoiding tearing, resulting in fewer latency issues
258 // than standard vertical sync.This is commonly
259 // known as "triple buffering", although the existence of three buffers
260 // alone does not necessarily mean that the framerate
261 // is unlocked.
262
263 // try to select mailbox mode, else select the default FIFO mode
264 for (const auto& availablePresentMode : availablePresentModes) {
265 if (availablePresentMode == this->preferredPresentMode) {
266 return availablePresentMode;
267 }
268 }
269
270 return VK_PRESENT_MODE_FIFO_KHR;
271}
VkPresentModeKHR preferredPresentMode
Preferred present mode for the swapchain.

◆ cleanup()

void Chronos::Engine::SwapChain::cleanup ( )

Cleans up the assets that are rendered invalid during MSAA changes or swapchain.

Definition at line 193 of file swapchain.cpp.

194{
195 vkDestroyImageView(device->device, colorImageView, nullptr);
196 vkDestroyImage(device->device, colorImage, nullptr);
197 vkFreeMemory(device->device, colorImageMemory, nullptr);
198 // destroy the image views
199 for (auto imageView : swapChainImageViews) {
200 vkDestroyImageView(device->device, imageView, nullptr);
201 }
202 // destroy the swap chain
203 vkDestroySwapchainKHR(device->device, swapChain, nullptr);
204}
std::vector< VkImageView > swapChainImageViews
Image views of the swapchain textures(images, aka window)
VkImageView colorImageView
image view of the color attachement
VkDeviceMemory colorImageMemory
Memory to store the color image.
VkImage colorImage
The color image.
VkSwapchainKHR swapChain
Vulkan swapchain object.

◆ create()

void Chronos::Engine::SwapChain::create ( )
private

Creates the swapchain image resources and chooses the optimal settings for given hardware.

Definition at line 105 of file swapchain.cpp.

106{
107 // create the swapchain
108 SwapChainSupportDetails swapChainSupport
110 (*device).physicalDevice, surface);
111 VkSurfaceFormatKHR surfaceFormat
112 = Chronos::Engine::chooseSwapSurfaceFormat(swapChainSupport.formats);
113 VkPresentModeKHR presentMode
114 = this->chooseSwapPresentMode(swapChainSupport.presentModes);
115 VkExtent2D extent = Chronos::Engine::chooseSwapExtent(
116 swapChainSupport.capabilities, window);
117
118 // set the number of images in the swap chain
119 uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1;
120
121 // check if the number of images exceeds the maximum possible images
122 // supprted
123 if (swapChainSupport.capabilities.maxImageCount > 0
124 && imageCount > swapChainSupport.capabilities.maxImageCount) {
125 imageCount = swapChainSupport.capabilities.maxImageCount;
126 }
127
128 VkSwapchainCreateInfoKHR createInfo {};
129 createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
130 createInfo.surface = surface;
131 createInfo.minImageCount = imageCount;
132 createInfo.imageFormat = surfaceFormat.format;
133 createInfo.imageColorSpace = surfaceFormat.colorSpace;
134 createInfo.imageExtent = extent;
135 createInfo.imageArrayLayers = 1;
136 createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
137
140 uint32_t queueFamilyIndices[]
141 = { indices.graphicsFamily.value(), indices.presentFamily.value() };
142
143 if (indices.graphicsFamily != indices.presentFamily) {
144 createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
145 createInfo.queueFamilyIndexCount = 2;
146 createInfo.pQueueFamilyIndices = queueFamilyIndices;
147 } else {
148 createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
149 createInfo.queueFamilyIndexCount = 0; // Optional
150 createInfo.pQueueFamilyIndices = nullptr; // Optional
151 }
152 createInfo.preTransform = swapChainSupport.capabilities.currentTransform;
153 createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
154 createInfo.presentMode = presentMode;
155 createInfo.clipped = VK_TRUE;
156 createInfo.oldSwapchain = NULL;
157
158 if (vkCreateSwapchainKHR(device->device, &createInfo, nullptr, &swapChain)
159 != VK_SUCCESS) {
160 throw std::runtime_error("Failed to create swap chain");
161 }
162 vkGetSwapchainImagesKHR(device->device, swapChain, &imageCount, nullptr);
163 swapChainImages.resize(imageCount);
164 vkGetSwapchainImagesKHR(
165 device->device, swapChain, &imageCount, swapChainImages.data());
166 swapChainImageFormat = surfaceFormat.format;
167 swapChainExtent = extent;
168}
VkPhysicalDevice physicalDevice
This is the physical device that is used by Vulkan.
Definition device.hpp:60
VkExtent2D swapChainExtent
Dimenisons of the current swapchain.
VkSurfaceKHR surface
Surface to which we need to present the swapchain images.
VkFormat swapChainImageFormat
Chosen swapchain image format.
std::vector< VkImage > swapChainImages
Swapchaim images to render and present to.
GLFWwindow * window
The window to present the surface to.
VkPresentModeKHR chooseSwapPresentMode(const std::vector< VkPresentModeKHR > &availablePresentModes)
From the available present mode, this chooses the the best present mode.
VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilities, GLFWwindow *window)
Gets the maximum extent of the swapchain images(framebuffer size).
Definition swapchain.cpp:41
VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector< VkSurfaceFormatKHR > &availableFormats)
Chooses the best present mode among the supported modes.
Definition swapchain.cpp:26
SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device, VkSurfaceKHR surface)
For a given swapchain mode, it gets the capabilites, formats and present modes.
Definition swapchain.cpp:65
QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR surface)
Gets the indices of the needed queue families.
Definition helper.cpp:126
This is used to check if a given familty supports graphics and presentation.
Definition helper.hpp:44
std::optional< uint32_t > presentFamily
Definition helper.hpp:46
std::optional< uint32_t > graphicsFamily
Definition helper.hpp:45

References Chronos::Engine::SwapChainSupportDetails::capabilities, Chronos::Engine::chooseSwapExtent(), Chronos::Engine::chooseSwapSurfaceFormat(), Chronos::Engine::findQueueFamilies(), Chronos::Engine::SwapChainSupportDetails::formats, Chronos::Engine::QueueFamilyIndices::graphicsFamily, Chronos::Engine::QueueFamilyIndices::presentFamily, Chronos::Engine::SwapChainSupportDetails::presentModes, and Chronos::Engine::querySwapChainSupport().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ createColorResources()

void Chronos::Engine::SwapChain::createColorResources ( )
private

Creates the color images along with the associated objects.

Definition at line 179 of file swapchain.cpp.

180{
181 VkFormat colorFormat = swapChainImageFormat;
183 colorFormat, VK_IMAGE_TILING_OPTIMAL,
184 VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
185 | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
186 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &colorImage, &colorImageMemory,
188
191}
VkSampleCountFlagBits msaaSamples
This sets the MSAA samples count.
Definition device.hpp:80
VkImageView createImageView(Chronos::Engine::Device device, VkFormat format, VkImage image)
Create a VkImageView for a given VkImage.
Definition texture.cpp:255
void createImage(Chronos::Engine::Device device, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage *image, VkDeviceMemory *imageMemory, VkSampleCountFlagBits numSamples)
For a given image dimensons, it creates a VkImage and.
Definition texture.cpp:42

References Chronos::Engine::createImage(), and Chronos::Engine::createImageView().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ createImageViews()

void Chronos::Engine::SwapChain::createImageViews ( )
private

Creates the image views of the swapchain images.

Definition at line 170 of file swapchain.cpp.

171{
173 for (size_t i = 0; i < swapChainImages.size(); i++) {
176 }
177}

References Chronos::Engine::createImageView().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init()

void Chronos::Engine::SwapChain::init ( Chronos::Engine::Device device,
VkSurfaceKHR  surface,
GLFWwindow *  window 
)

Initilize the swapchain.

The swapchain is an insanely complicated process to setup. We need to create multiple textures, along with their memory and views. We also need to select the format to render to. Along with that we need the color rendering texture attachment, which has its own texture, memory and view.

Parameters
deviceThe device to create the swapchain on
surfaceThe surface(VK version of window texture) to render to
windowThw window to display the image on.

Definition at line 94 of file swapchain.cpp.

96{
97 this->device = device;
98 this->surface = surface;
99 this->window = window;
100 create();
103}

References create(), createColorResources(), createImageViews(), device, surface, and window.

Here is the call graph for this function:

◆ recreate()

void Chronos::Engine::SwapChain::recreate ( )

When the swapchain is rendered invalid, recreate it.

Due to various user activities such as window resizing and minimization, the swapchain can become invalid. At that point, we need to recreate the assets based on the new dimensions.

Definition at line 206 of file swapchain.cpp.

207{
208 int width = 0, height = 0;
209 glfwGetFramebufferSize(window, &width, &height);
210 while (width == 0 || height == 0) {
211 glfwGetFramebufferSize(window, &width, &height);
212 glfwWaitEvents();
213 }
214
215 vkDeviceWaitIdle(device->device);
216
217 cleanup();
218 create();
221}

Member Data Documentation

◆ changePresentMode

bool Chronos::Engine::SwapChain::changePresentMode = false

Definition at line 175 of file swapchain.hpp.

◆ colorImage

VkImage Chronos::Engine::SwapChain::colorImage
private

The color image.

Definition at line 191 of file swapchain.hpp.

◆ colorImageMemory

VkDeviceMemory Chronos::Engine::SwapChain::colorImageMemory
private

Memory to store the color image.

Definition at line 196 of file swapchain.hpp.

◆ colorImageView

VkImageView Chronos::Engine::SwapChain::colorImageView

image view of the color attachement

Definition at line 163 of file swapchain.hpp.

◆ device

Chronos::Engine::Device* Chronos::Engine::SwapChain::device
private

Device to which swapchain needs to be created.

Definition at line 181 of file swapchain.hpp.

◆ preferredPresentMode

VkPresentModeKHR Chronos::Engine::SwapChain::preferredPresentMode = VK_PRESENT_MODE_MAILBOX_KHR

Preferred present mode for the swapchain.

Definition at line 173 of file swapchain.hpp.

◆ surface

VkSurfaceKHR Chronos::Engine::SwapChain::surface

Surface to which we need to present the swapchain images.

Definition at line 153 of file swapchain.hpp.

◆ swapChain

VkSwapchainKHR Chronos::Engine::SwapChain::swapChain

Vulkan swapchain object.

Definition at line 148 of file swapchain.hpp.

◆ swapChainExtent

VkExtent2D Chronos::Engine::SwapChain::swapChainExtent

Dimenisons of the current swapchain.

Definition at line 143 of file swapchain.hpp.

◆ swapChainImageFormat

VkFormat Chronos::Engine::SwapChain::swapChainImageFormat

Chosen swapchain image format.

Definition at line 168 of file swapchain.hpp.

◆ swapChainImages

std::vector<VkImage> Chronos::Engine::SwapChain::swapChainImages
private

Swapchaim images to render and present to.

Definition at line 201 of file swapchain.hpp.

◆ swapChainImageViews

std::vector<VkImageView> Chronos::Engine::SwapChain::swapChainImageViews

Image views of the swapchain textures(images, aka window)

Definition at line 158 of file swapchain.hpp.

◆ window

GLFWwindow* Chronos::Engine::SwapChain::window
private

The window to present the surface to.

Definition at line 186 of file swapchain.hpp.


The documentation for this class was generated from the following files: