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

Namespaces

namespace  FontStructs
 

Classes

class  Buffer
 Used to store buffers in GPU. More...
 
class  ColorBuffer
 This is a buffer for storing and updating the color of the shape. More...
 
class  ColoredRectangle
 
struct  ColorVertex
 This defines the position of a vertex. Used when we need a colored vertex. Does not support textures. More...
 
class  Device
 This initializes, manages and destroys the logical and physical devices(GPU). More...
 
class  Engine
 
struct  FontTypes
 The parameters needed for the font style. More...
 
class  Object
 Abstract class for creating and managing generic graphical objects. More...
 
class  ObjectManager
 
struct  PipelineAttributes
 Structure defining attributes required for creating a graphics pipeline. More...
 
struct  QueueFamilyIndices
 This is used to check if a given familty supports graphics and presentation. More...
 
class  SwapChain
 
struct  SwapChainSupportDetails
 Contains the fields to the support details of a physical device. More...
 
class  Text
 Class for creating a text object for rendering text. More...
 
struct  TextParams
 Parameters for rendering text. More...
 
class  Texture
 This class holds the Vulkan data and objects needed for a texture. More...
 
class  TexturedRectangle
 
struct  TexturedVertex
 This defines the position and texture coordinates of a vertex. Used when we need a textured vertex. More...
 
class  TextureManager
 This is the texture manager for Chronos. It handles creation, modification, updating and desrtuction of textures. More...
 
class  UniformBuffer
 This is a Uniform buffer for storing the uniform variables in the shaders. More...
 
struct  UniformBufferObject
 Uniform struct passed to shader. More...
 
struct  UniformColorBufferObject
 Uniform struct for color passed to shader. More...
 

Enumerations

enum  ObjectType { TypeTexturedRectangle , TypeColoredRectangle , TypeText }
 

Functions

VkCommandBuffer beginSingleTimeCommands (VkCommandPool commandPool, VkDevice device)
 Begins recording of a command buffer that will be used once.
 
void endSingleTimeCommands (VkCommandBuffer *commandBuffer, Chronos::Engine::Device device, VkCommandPool commandPool)
 Ends recording of single time command buffer and destroys it.
 
uint32_t findMemoryType (uint32_t typeFilter, VkMemoryPropertyFlags properties, VkPhysicalDevice physicalDevice)
 Finds suitable memory type for given requrements.
 
void createBuffer (Chronos::Engine::Device device, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer *buffer, VkDeviceMemory *bufferMemory)
 Creates a buffer of a given size, usage and properties.
 
void copyBuffer (Chronos::Engine::Device device, VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size, VkCommandPool commandPool)
 Copies data from one buffer to another.
 
QueueFamilyIndices findQueueFamilies (VkPhysicalDevice device, VkSurfaceKHR surface)
 Gets the indices of the needed queue families.
 
VkCommandPool createCommandPool (Chronos::Engine::Device device, VkSurfaceKHR surface)
 Creates a command pool for a given device and surface.
 
VkRenderPass createRenderPass (Chronos::Engine::Device device, Chronos::Engine::SwapChain swapChain, VkImageLayout initalLayout, VkImageLayout finalLayout, VkImageLayout msaaFinalLayout, bool msaa, bool clearFramebuffer, bool dependency)
 Creates a render pass.
 
std::vector< VkFramebuffer > createFramebuffer (Chronos::Engine::Device device, Chronos::Engine::SwapChain swapChain, VkRenderPass renderPass, bool msaa)
 Creates a set of framebuffers for use.
 
std::vector< VkCommandBuffer > createCommandBuffer (Chronos::Engine::Device device, Chronos::Engine::SwapChain swapChain, VkCommandPool commandPool)
 Creates a set of command buffers for use.
 
Chronos::Engine::FontTypes getFontType (std::string fontType, int fontSize)
 
VkExtent2D chooseSwapExtent (const VkSurfaceCapabilitiesKHR &capabilities, GLFWwindow *window)
 Gets the maximum extent of the swapchain images(framebuffer size).
 
VkSurfaceFormatKHR chooseSwapSurfaceFormat (const std::vector< VkSurfaceFormatKHR > &availableFormats)
 Chooses the best present mode among the supported modes.
 
SwapChainSupportDetails querySwapChainSupport (VkPhysicalDevice device, VkSurfaceKHR surface)
 For a given swapchain mode, it gets the capabilites, formats and present modes.
 
void createTextureSampler (Chronos::Engine::Device device, VkSampler *textureSampler)
 Creates a VkSampler
 
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.
 
void transitionImageLayout (VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, VkCommandPool commandPool, Chronos::Engine::Device device)
 Transiton a VkImage from one layout to another.
 
void copyBufferToImage (VkBuffer buffer, VkImage image, uint32_t width, uint32_t height, VkCommandPool commandPool, Chronos::Engine::Device device)
 Copy data from a buffer to an image.
 
VkImageView createImageView (Chronos::Engine::Device device, VkFormat format, VkImage image)
 Create a VkImageView for a given VkImage.
 

Variables

const std::vector< const char * > deviceExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME }
 THis contain the device extensions that are needed to be enabled in vulkan.
 

Enumeration Type Documentation

◆ ObjectType

Enumerator
TypeTexturedRectangle 
TypeColoredRectangle 
TypeText 

Definition at line 4 of file objectTypes.hpp.

Function Documentation

◆ beginSingleTimeCommands()

VkCommandBuffer Chronos::Engine::beginSingleTimeCommands ( VkCommandPool  commandPool,
VkDevice  device 
)

Begins recording of a command buffer that will be used once.

This is used to create a temporary commandBuffer for single use and starts recording. Generally used for transfering data to the GPU. After using the buffer, it must be ended and destroyed using endSingleTimeCommands.

Parameters
commandPoolThe command pool to create the temporary command buffer on.
deviceThe device that has the command pool.
Returns
The created command buffer.

Definition at line 24 of file helper.cpp.

26{
27 // used for staging buffers. We need a temproary command buffer to copy the
28 // data to the device buffer
29 VkCommandBufferAllocateInfo allocInfo {};
30 allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
31 allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
32 allocInfo.commandPool = commandPool;
33 allocInfo.commandBufferCount = 1;
34
35 VkCommandBuffer commandBuffer;
36 vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer);
37
38 VkCommandBufferBeginInfo beginInfo {};
39 beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
40 beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
41
42 vkBeginCommandBuffer(commandBuffer, &beginInfo);
43
44 return commandBuffer;
45}
Here is the caller graph for this function:

◆ chooseSwapExtent()

VkExtent2D Chronos::Engine::chooseSwapExtent ( const VkSurfaceCapabilitiesKHR &  capabilities,
GLFWwindow *  window 
)

Gets the maximum extent of the swapchain images(framebuffer size).

We need to calculate the maximum extent of the swapchain. Preferably we want to support the width and height of the window. However the hardware may not support this. Hence after getting the desired height and and width, we clamp it to the hardware limits.

Parameters
capabilitesThe capabailites of the hardware/surface to display the image(max/min height and width)
windowThe GLFW window instance to be rendered to. This contains the desired height and width.
Returns
The chosen extent of the swapchain based on the capabilites of the hardware.

Definition at line 41 of file swapchain.cpp.

43{
44 if (capabilities.currentExtent.width
45 != std::numeric_limits<uint32_t>::max()) {
46 return capabilities.currentExtent;
47 } else {
48 int width, height;
49 glfwGetFramebufferSize(window, &width, &height);
50
51 VkExtent2D actualExtent
52 = { static_cast<uint32_t>(width), static_cast<uint32_t>(height) };
53
54 actualExtent.width
55 = std::clamp(actualExtent.width, capabilities.minImageExtent.width,
56 capabilities.maxImageExtent.width);
57 actualExtent.height = std::clamp(actualExtent.height,
58 capabilities.minImageExtent.height,
59 capabilities.maxImageExtent.height);
60
61 return actualExtent;
62 }
63}
Here is the caller graph for this function:

◆ chooseSwapSurfaceFormat()

VkSurfaceFormatKHR Chronos::Engine::chooseSwapSurfaceFormat ( const std::vector< VkSurfaceFormatKHR > &  availableFormats)

Chooses the best present mode among the supported modes.

It chooses RGBA format along with SRGB for color space. If such a format is not available then it chooses the first one that is available.

Parameters
availableFormatsThe available formats available to choose from.
Returns
The best format chosen for rendering

Definition at line 26 of file swapchain.cpp.

28{
29 // try to choose SRBG format, else return the first available format
30 for (const auto& availableFormat : availableFormats) {
31 if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB
32 && availableFormat.colorSpace
33 == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
34 return availableFormat;
35 }
36 }
37
38 return availableFormats[0];
39}
Here is the caller graph for this function:

◆ copyBuffer()

void Chronos::Engine::copyBuffer ( Chronos::Engine::Device  device,
VkBuffer  srcBuffer,
VkBuffer  dstBuffer,
VkDeviceSize  size,
VkCommandPool  commandPool 
)

Copies data from one buffer to another.

This is used to transfer data between host and device using staging buffers.

Parameters
deviceThe device that has the commandPool.
srcBufferThe source buffer to copy from.
dstBufferThe destination buffer to copy to.
sizeThe size of the buffer to copy.
commandPoolThe command pool to create the temporary command buffer on.

Definition at line 111 of file helper.cpp.

114{
115 // copies data from a buffer to another buffer
116 VkCommandBuffer commandBuffer
118 VkBufferCopy copyRegion {};
119 copyRegion.srcOffset = 0;
120 copyRegion.dstOffset = 0;
121 copyRegion.size = size;
122 vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, &copyRegion);
123 Chronos::Engine::endSingleTimeCommands(&commandBuffer, device, commandPool);
124}
VkDevice device
This is the logical device that is used by Vulkan.
Definition device.hpp:52
VkCommandBuffer beginSingleTimeCommands(VkCommandPool commandPool, VkDevice device)
Begins recording of a command buffer that will be used once.
Definition helper.cpp:24
void endSingleTimeCommands(VkCommandBuffer *commandBuffer, Chronos::Engine::Device device, VkCommandPool commandPool)
Ends recording of single time command buffer and destroys it.
Definition helper.cpp:47

References beginSingleTimeCommands(), Chronos::Engine::Device::device, and endSingleTimeCommands().

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

◆ copyBufferToImage()

void Chronos::Engine::copyBufferToImage ( VkBuffer  buffer,
VkImage  image,
uint32_t  width,
uint32_t  height,
VkCommandPool  commandPool,
Chronos::Engine::Device  device 
)

Copy data from a buffer to an image.

Parameters
bufferThe buffer to copy data from.
imageThe image to copy data to.
widthWidth of the image.
heightHeight of the image.
commandPoolThe command pool to create the temporary command buffer from.
deviceThe device that has the image.

Definition at line 234 of file texture.cpp.

237{
238 VkCommandBuffer commandBuffer
240 VkBufferImageCopy region {};
241 region.bufferOffset = 0;
242 region.bufferRowLength = 0;
243 region.bufferImageHeight = 0;
244 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
245 region.imageSubresource.mipLevel = 0;
246 region.imageSubresource.baseArrayLayer = 0;
247 region.imageSubresource.layerCount = 1;
248 region.imageOffset = { 0, 0, 0 };
249 region.imageExtent = { width, height, 1 };
250 vkCmdCopyBufferToImage(commandBuffer, buffer, image,
251 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
252 Chronos::Engine::endSingleTimeCommands(&commandBuffer, device, commandPool);
253}

References beginSingleTimeCommands(), Chronos::Engine::Device::device, and endSingleTimeCommands().

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

◆ createBuffer()

void Chronos::Engine::createBuffer ( Chronos::Engine::Device  device,
VkDeviceSize  size,
VkBufferUsageFlags  usage,
VkMemoryPropertyFlags  properties,
VkBuffer *  buffer,
VkDeviceMemory *  bufferMemory 
)

Creates a buffer of a given size, usage and properties.

This function creates a buffer of given size and usage. It then allocates the needed memory for this by finding the needed memory type using findMemoryType.

Parameters
deviceThe device that has the buffer.
sizeThe size of the buffer.
usageThe usage of the buffer.
propertiesThe memory property flags of the buffer.
bufferThe buffer to create.
bufferMemoryThe associcated memory for the buffer.

Definition at line 78 of file helper.cpp.

82{
83 VkBufferCreateInfo bufferInfo {};
84 bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
85 bufferInfo.size = size;
86 bufferInfo.usage = usage;
87 bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
88
89 if (vkCreateBuffer(device.device, &bufferInfo, nullptr, buffer)
90 != VK_SUCCESS) {
91 throw std::runtime_error("failed to create buffer!");
92 }
93
94 VkMemoryRequirements memRequirements;
95 vkGetBufferMemoryRequirements(device.device, *buffer, &memRequirements);
96
97 VkMemoryAllocateInfo allocInfo {};
98 allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
99 allocInfo.allocationSize = memRequirements.size;
100 allocInfo.memoryTypeIndex = findMemoryType(
101 memRequirements.memoryTypeBits, properties, device.physicalDevice);
102
103 if (vkAllocateMemory(device.device, &allocInfo, nullptr, bufferMemory)
104 != VK_SUCCESS) {
105 throw std::runtime_error("failed to allocate buffer memory!");
106 }
107
108 vkBindBufferMemory(device.device, *buffer, *bufferMemory, 0);
109}
VkPhysicalDevice physicalDevice
This is the physical device that is used by Vulkan.
Definition device.hpp:60
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties, VkPhysicalDevice physicalDevice)
Finds suitable memory type for given requrements.
Definition helper.cpp:63

References Chronos::Engine::Device::device, findMemoryType(), and Chronos::Engine::Device::physicalDevice.

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

◆ createCommandBuffer()

std::vector< VkCommandBuffer > Chronos::Engine::createCommandBuffer ( Chronos::Engine::Device  device,
Chronos::Engine::SwapChain  swapChain,
VkCommandPool  commandPool 
)

Creates a set of command buffers for use.

This creates the command buffers for a given swap chain on a given command pool. It creates as many command buffers as there are images in the swap chain.

Parameters
deviceThe device that has the command pool.
swapChainThe swap chain to create the command buffers for.
commandPoolThe command pool to create the command buffers on.
Returns
The created command buffers.

Definition at line 308 of file helper.cpp.

311{
312 std::vector<VkCommandBuffer> commandBuffers;
313 commandBuffers.resize(swapChain.swapChainImageViews.size());
314 VkCommandBufferAllocateInfo allocInfo {};
315 allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
316 allocInfo.commandPool = commandPool;
317 allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
318 allocInfo.commandBufferCount = static_cast<uint32_t>(commandBuffers.size());
319 if (vkAllocateCommandBuffers(
320 device.device, &allocInfo, commandBuffers.data())
321 != VK_SUCCESS) {
322 throw std::runtime_error("failed to allocate command buffers!");
323 }
324 return commandBuffers;
325}
std::vector< VkImageView > swapChainImageViews
Image views of the swapchain textures(images, aka window)

References Chronos::Engine::Device::device, and Chronos::Engine::SwapChain::swapChainImageViews.

Here is the caller graph for this function:

◆ createCommandPool()

VkCommandPool Chronos::Engine::createCommandPool ( Chronos::Engine::Device  device,
VkSurfaceKHR  surface 
)

Creates a command pool for a given device and surface.

Parameters
deviceThe device to create the command pool on.
surfaceThe surface to which we are rendering.
Returns
The created command pool.

Definition at line 157 of file helper.cpp.

159{
160 VkCommandPool commandPool;
161 QueueFamilyIndices queueFamilyIndices
163 VkCommandPoolCreateInfo poolInfo {};
164 poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
165 poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value();
166 poolInfo.flags
167 = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; // Optional
168 if (vkCreateCommandPool(device.device, &poolInfo, nullptr, &commandPool)
169 != VK_SUCCESS) {
170 throw std::runtime_error("failed to create command pool!");
171 }
172 return commandPool;
173}
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 > graphicsFamily
Definition helper.hpp:45

References Chronos::Engine::Device::device, findQueueFamilies(), Chronos::Engine::QueueFamilyIndices::graphicsFamily, and Chronos::Engine::Device::physicalDevice.

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

◆ createFramebuffer()

std::vector< VkFramebuffer > Chronos::Engine::createFramebuffer ( Chronos::Engine::Device  device,
Chronos::Engine::SwapChain  swapChain,
VkRenderPass  renderPass,
bool  msaa 
)

Creates a set of framebuffers for use.

It creates as many framebuffers as there are images in the swap chain.

Parameters
deviceThe device that has the swap chain.
swapChainThe swap chain to create the framebuffers for.
renderPassThe render pass that the framebuffers are going to be used for.
msaaWhether MSAA is enabled or not. This is to attach the necessary MSAA images to the framebuffer.

Definition at line 276 of file helper.cpp.

279{
280 std::vector<VkFramebuffer> framebuffers;
281 framebuffers.resize(swapChain.swapChainImageViews.size());
282 for (size_t i = 0; i < swapChain.swapChainImageViews.size(); i++) {
283 std::vector<VkImageView> attachments;
284 if (msaa && device.msaaSamples != VK_SAMPLE_COUNT_1_BIT) {
285 attachments = { swapChain.colorImageView,
286 swapChain.swapChainImageViews[i] };
287 } else {
288 attachments = { swapChain.swapChainImageViews[i] };
289 }
290 VkFramebufferCreateInfo framebufferInfo {};
291 framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
292 framebufferInfo.renderPass = renderPass;
293 framebufferInfo.attachmentCount
294 = static_cast<uint32_t>(attachments.size());
295 framebufferInfo.pAttachments = attachments.data();
296 framebufferInfo.width = swapChain.swapChainExtent.width;
297 framebufferInfo.height = swapChain.swapChainExtent.height;
298 framebufferInfo.layers = 1;
299 if (vkCreateFramebuffer(
300 device.device, &framebufferInfo, nullptr, &framebuffers[i])
301 != VK_SUCCESS) {
302 throw std::runtime_error("failed to create framebuffer!");
303 }
304 }
305 return framebuffers;
306}
VkSampleCountFlagBits msaaSamples
This sets the MSAA samples count.
Definition device.hpp:80
VkExtent2D swapChainExtent
Dimenisons of the current swapchain.
VkImageView colorImageView
image view of the color attachement

References Chronos::Engine::SwapChain::colorImageView, Chronos::Engine::Device::device, Chronos::Engine::Device::msaaSamples, Chronos::Engine::SwapChain::swapChainExtent, and Chronos::Engine::SwapChain::swapChainImageViews.

Here is the caller graph for this function:

◆ createImage()

void Chronos::Engine::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.

for the image.

Parameters
deviceSevice to create the image on.
widthWidth of the image.
heightHeight of the image.
formatFormat of the image. More information here.
tilingTiling structure of the image. Options are
_IMAGE_TILING_OPTIMAL
and VK_IMAGE_TILING_LINEAR
usageThe usage of the image. Common options are
_IMAGE_USAGE_SAMPLED_BIT
, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
and
_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
.
propertiesThe properties of the image. Common options are
_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
,
_MEMORY_PROPERTY_HOST_VISIBLE_BIT
,
_MEMORY_PROPERTY_HOST_COHERENT_BIT
and
_MEMORY_PROPERTY_HOST_CACHED_BIT
.
imageThe image to be created.
imageMemoryThe memory for the image to be created.
numSamplesThe number of samples for the image. Common options are
_SAMPLE_COUNT_1_BIT
, VK_SAMPLE_COUNT_2_BIT,
_SAMPLE_COUNT_4_BIT
and VK_SAMPLE_COUNT_8_BIT. Generally VK_SAMPLE_COUNT_1_BIT is used unless the image is used with MSAA.

Definition at line 42 of file texture.cpp.

46{
47 VkImageCreateInfo imageInfo {};
48 imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
49 imageInfo.imageType = VK_IMAGE_TYPE_2D;
50 imageInfo.extent.width = width;
51 imageInfo.extent.height = height;
52 imageInfo.extent.depth = 1;
53 imageInfo.mipLevels = 1;
54 imageInfo.arrayLayers = 1;
55 imageInfo.format = format;
56 imageInfo.tiling = tiling;
57 imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
58 imageInfo.usage = usage;
59 imageInfo.samples = numSamples;
60 imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
61
62 if (vkCreateImage(device.device, &imageInfo, nullptr, image)
63 != VK_SUCCESS) {
64 throw std::runtime_error("failed to create image!");
65 }
66
67 VkMemoryRequirements memRequirements;
68 vkGetImageMemoryRequirements(device.device, *image, &memRequirements);
69
70 VkMemoryAllocateInfo allocInfo {};
71 allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
72 allocInfo.allocationSize = memRequirements.size;
73 allocInfo.memoryTypeIndex = Chronos::Engine::findMemoryType(
74 memRequirements.memoryTypeBits, properties, device.physicalDevice);
75
76 if (vkAllocateMemory(device.device, &allocInfo, nullptr, imageMemory)
77 != VK_SUCCESS) {
78 throw std::runtime_error("failed to allocate image memory!");
79 }
80
81 vkBindImageMemory(device.device, *image, *imageMemory, 0);
82}

References Chronos::Engine::Device::device, findMemoryType(), and Chronos::Engine::Device::physicalDevice.

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

◆ createImageView()

VkImageView Chronos::Engine::createImageView ( Chronos::Engine::Device  device,
VkFormat  format,
VkImage  image 
)

Create a VkImageView for a given VkImage.

For each image, we need to create an image view. This is used to specify how the image is to be used.

Parameters
deviceThe device that has the image.
formatThe format of the image.
imageThe image to create the image view for.
Returns
The created image view.

Definition at line 255 of file texture.cpp.

257{
258 VkImageViewCreateInfo viewInfo {};
259 viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
260 viewInfo.image = image;
261 viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
262 viewInfo.format = format;
263 viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
264 viewInfo.subresourceRange.baseMipLevel = 0;
265 viewInfo.subresourceRange.levelCount = 1;
266 viewInfo.subresourceRange.baseArrayLayer = 0;
267 viewInfo.subresourceRange.layerCount = 1;
268
269 VkImageView imageView;
270
271 if (vkCreateImageView(device.device, &viewInfo, nullptr, &imageView)
272 != VK_SUCCESS) {
273 throw std::runtime_error("failed to create texture image view!");
274 }
275 return imageView;
276}

References Chronos::Engine::Device::device.

Here is the caller graph for this function:

◆ createRenderPass()

VkRenderPass Chronos::Engine::createRenderPass ( Chronos::Engine::Device  device,
Chronos::Engine::SwapChain  swapChain,
VkImageLayout  initalLayout,
VkImageLayout  finalLayout,
VkImageLayout  msaaFinalLayout,
bool  msaa,
bool  clearFramebuffer,
bool  dependency 
)

Creates a render pass.

For a given swap chain, layouts, this creates a render pass. Please carefully read the parameters below before using this function to understand what each parameter does.

During the creation of the render pass, the render pass will transition the image from the initial layout to the final layout. If MSAA is enabled, then the render pass will also transition the image from the final layout to the msaa final layout. The other parameters are also detailed below.

Parameters
initalLayoutThe initial layout of the incoming image. If this from the previous frame(no render pass before it) then this is
_IMAGE_LAYOUT_UNDEFINED
, else it is advised to use
_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
.
finalLayoutThe final layout of the outgoing image before MSAA. If this is going to be presented to the screen, then this is
_IMAGE_LAYOUT_PRESENT_SRC_KHR
, else it is advised to use
_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
. If MSAA is enabled, then this is VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, as then msaaFinalLayout is used for the final layout if this is the final render pass.
msaaFinalLayoutThe final layout of the outgoing image if MSAA is enabled. This is due to the fact that MSAA resolves the image, hence it change the layout of the image. If this is going to be presented to the screen, then this is VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, else it is advised to use VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL.
msaaWhether MSAA is enabled or not.
clearFramebufferWhether the framebuffer should be cleared or not. If this is the first render pass, then this should be true. Else it should be false, else the previous contents rendered to the framebuffer from the previous render pass will be cleared.
dependencyWhether the render pass should wait for other render passes to finish. If there are render passes before this, then this should be true. Else it should be false.

Definition at line 175 of file helper.cpp.

179{
180 VkRenderPass renderPass;
181 VkAttachmentDescription colorAttachment {};
182 colorAttachment.format = swapChain.swapChainImageFormat;
183 // if using msaa, set the bits
184 if (msaa && device.msaaSamples != VK_SAMPLE_COUNT_1_BIT) {
185 colorAttachment.samples = device.msaaSamples;
186 } else {
187 colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
188 }
189 // when using multiple render passes, we dont want to clear the framebuffer
190 // each pass
191 if (clearFramebuffer) {
192 colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
193 } else {
194 colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
195 }
196 colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
197 colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
198 colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
199 colorAttachment.initialLayout = initalLayout; // initial layout of image
200 colorAttachment.finalLayout
201 = finalLayout; // final layout of image if not using msaa
202
203 VkAttachmentDescription colorAttachmentResolve {};
204 colorAttachmentResolve.format = swapChain.swapChainImageFormat;
205 colorAttachmentResolve.samples = VK_SAMPLE_COUNT_1_BIT;
206 colorAttachmentResolve.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
207 colorAttachmentResolve.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
208 colorAttachmentResolve.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
209 colorAttachmentResolve.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
210 colorAttachmentResolve.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
211 colorAttachmentResolve.finalLayout
212 = msaaFinalLayout; // final layout if using msaa
213
214 VkAttachmentReference colorAttachmentRef {};
215 colorAttachmentRef.attachment = 0;
216 colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
217
218 VkAttachmentReference colorAttachmentResolveRef {};
219 colorAttachmentResolveRef.attachment = 1;
220 colorAttachmentResolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
221
222 VkSubpassDescription subpass {};
223 subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
224 subpass.colorAttachmentCount = 1;
225 subpass.pColorAttachments = &colorAttachmentRef;
226 if (msaa && device.msaaSamples != VK_SAMPLE_COUNT_1_BIT) {
227 subpass.pResolveAttachments = &colorAttachmentResolveRef;
228 } else {
229 subpass.pResolveAttachments = nullptr;
230 }
231 // if we are using multiple render passes, then we need to wait for other
232 // commands to finish
233 VkSubpassDependency subpassDependencies[2];
234 subpassDependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
235 subpassDependencies[0].dstSubpass = 0;
236 subpassDependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
237 subpassDependencies[0].dstStageMask
238 = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
239 subpassDependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
240 subpassDependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
241 | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
242 subpassDependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
243
244 subpassDependencies[1].srcSubpass = 0;
245 subpassDependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
246 subpassDependencies[1].srcStageMask
247 = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
248 subpassDependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
249 subpassDependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
250 | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
251 subpassDependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
252 subpassDependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
253
254 std::vector<VkAttachmentDescription> attachments = { colorAttachment };
255 if (msaa && device.msaaSamples != VK_SAMPLE_COUNT_1_BIT) {
256 attachments.push_back(colorAttachmentResolve);
257 }
258
259 VkRenderPassCreateInfo renderPassInfo {};
260 renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
261 renderPassInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
262 renderPassInfo.pAttachments = attachments.data();
263 renderPassInfo.subpassCount = 1;
264 renderPassInfo.pSubpasses = &subpass;
265 if (dependency) {
266 renderPassInfo.dependencyCount = 2;
267 renderPassInfo.pDependencies = subpassDependencies;
268 }
269 if (vkCreateRenderPass(device.device, &renderPassInfo, nullptr, &renderPass)
270 != VK_SUCCESS) {
271 throw std::runtime_error("failed to create render pass!");
272 }
273 return renderPass;
274}
VkFormat swapChainImageFormat
Chosen swapchain image format.

References Chronos::Engine::Device::device, Chronos::Engine::Device::msaaSamples, and Chronos::Engine::SwapChain::swapChainImageFormat.

Here is the caller graph for this function:

◆ createTextureSampler()

void Chronos::Engine::createTextureSampler ( Chronos::Engine::Device  device,
VkSampler *  textureSampler 
)

Creates a VkSampler

Parameters
deviceDevice to create the sampler on.
textureSamplerSampler to be created.

Definition at line 278 of file texture.cpp.

280{
281 VkPhysicalDeviceProperties properties {};
282 vkGetPhysicalDeviceProperties(device.physicalDevice, &properties);
283 VkSamplerCreateInfo samplerInfo {};
284 samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
285 samplerInfo.magFilter = VK_FILTER_LINEAR;
286 samplerInfo.minFilter = VK_FILTER_LINEAR;
287 samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
288 samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
289 samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
290 samplerInfo.anisotropyEnable = VK_TRUE;
291 samplerInfo.maxAnisotropy = properties.limits.maxSamplerAnisotropy;
292 samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
293 samplerInfo.unnormalizedCoordinates = VK_FALSE;
294 samplerInfo.compareEnable = VK_FALSE;
295 samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
296 samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
297 samplerInfo.mipLodBias = 0.0f;
298 samplerInfo.minLod = 0.0f;
299 samplerInfo.maxLod = 0.0f;
300 if (vkCreateSampler(device.device, &samplerInfo, nullptr, textureSampler)
301 != VK_SUCCESS) {
302 throw std::runtime_error("failed to create texture sampler!");
303 }
304}

References Chronos::Engine::Device::device, and Chronos::Engine::Device::physicalDevice.

Here is the caller graph for this function:

◆ endSingleTimeCommands()

void Chronos::Engine::endSingleTimeCommands ( VkCommandBuffer *  commandBuffer,
Chronos::Engine::Device  device,
VkCommandPool  commandPool 
)

Ends recording of single time command buffer and destroys it.

Ends recording of the command buffer and destroys the temporary

created using beginSingleTimeCommands. Generally used for transfering data.

Parameters
commandBufferThe command buffer created by
to destroy.
deviceThe device that has the command pool.
commandPoolThe command pool that has the command buffer.

Definition at line 47 of file helper.cpp.

49{
50 vkEndCommandBuffer(*commandBuffer);
51
52 VkSubmitInfo submitInfo {};
53 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
54 submitInfo.commandBufferCount = 1;
55 submitInfo.pCommandBuffers = commandBuffer;
56
57 vkQueueSubmit(device.graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
58 vkQueueWaitIdle(device.graphicsQueue);
59
60 vkFreeCommandBuffers(device.device, commandPool, 1, commandBuffer);
61}
VkQueue graphicsQueue
This is the queue that is used for graphics rendering.
Definition device.hpp:65

References Chronos::Engine::Device::device, and Chronos::Engine::Device::graphicsQueue.

Here is the caller graph for this function:

◆ findMemoryType()

uint32_t Chronos::Engine::findMemoryType ( uint32_t  typeFilter,
VkMemoryPropertyFlags  properties,
VkPhysicalDevice  physicalDevice 
)

Finds suitable memory type for given requrements.

This is used to find a memory type on the physical device(GPU) that is suitable for the buffer that we are creating. It takes in the

and VkMemoryPropertyFlags to find such a memory type.

Parameters
typeFilterThe filter to find the memory type.
propertiesThe properties of the memory type.
physicalDeviceThe physical device to find the memory type on.
Returns
The index of the memory type.

Definition at line 63 of file helper.cpp.

65{
66 VkPhysicalDeviceMemoryProperties memProperties;
67 vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties);
68 for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
69 if ((typeFilter & (1 << i))
70 && (memProperties.memoryTypes[i].propertyFlags & properties)
71 == properties) {
72 return i;
73 }
74 }
75 throw std::runtime_error("failed to find suitable memory type!");
76}
Here is the caller graph for this function:

◆ findQueueFamilies()

Chronos::Engine::QueueFamilyIndices Chronos::Engine::findQueueFamilies ( VkPhysicalDevice  device,
VkSurfaceKHR  surface 
)

Gets the indices of the needed queue families.

It finds the required graphics and presentation queue families on the physical device(GPU). It checks if the given physical device is capable of rendering to the surface that we provide it.

Parameters
deviceThe physical device(GPU) to find the queue families on.
surfaceThe surface to which we are rendering.

Definition at line 126 of file helper.cpp.

128{
130 uint32_t queueFamilyCount = 0;
131 vkGetPhysicalDeviceQueueFamilyProperties(
132 device, &queueFamilyCount, nullptr);
133 // get the queue families
134 std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
135 vkGetPhysicalDeviceQueueFamilyProperties(
136 device, &queueFamilyCount, queueFamilies.data());
137 // check if the queue family has the required properties
138 int i = 0;
139 for (const auto& queueFamily : queueFamilies) {
140 if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
141 indices.graphicsFamily = i;
142 }
143 VkBool32 presentSupport = false;
144 vkGetPhysicalDeviceSurfaceSupportKHR(
145 device, i, surface, &presentSupport);
146 if (presentSupport) {
147 indices.presentFamily = i;
148 }
149 if (indices.isComplete()) {
150 break;
151 }
152 i++;
153 }
154 return indices;
155}
std::optional< uint32_t > presentFamily
Definition helper.hpp:46

References Chronos::Engine::QueueFamilyIndices::graphicsFamily, Chronos::Engine::QueueFamilyIndices::isComplete(), and Chronos::Engine::QueueFamilyIndices::presentFamily.

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

◆ getFontType()

Chronos::Engine::FontTypes Chronos::Engine::getFontType ( std::string  fontType,
int  fontSize 
)

Definition at line 51 of file getFontType.cpp.

53{
54 switch (fontSize) {
55 FONT_CASE(6)
56 FONT_CASE(7)
57 FONT_CASE(8)
58 FONT_CASE(9)
59 FONT_CASE(10)
60 FONT_CASE(11)
61 FONT_CASE(12)
62 FONT_CASE(13)
63 FONT_CASE(14)
64 FONT_CASE(15)
65 FONT_CASE(16)
66 FONT_CASE(17)
67 FONT_CASE(18)
68 FONT_CASE(19)
69 FONT_CASE(20)
70 FONT_CASE(21)
71 FONT_CASE(22)
72 FONT_CASE(23)
73 FONT_CASE(24)
74 FONT_CASE(25)
75 FONT_CASE(26)
76 FONT_CASE(27)
77 FONT_CASE(28)
78 FONT_CASE(29)
79 FONT_CASE(30)
80 FONT_CASE(31)
81 FONT_CASE(32)
82 FONT_CASE(33)
83 FONT_CASE(34)
84 FONT_CASE(35)
85 FONT_CASE(36)
86 FONT_CASE(37)
87 FONT_CASE(38)
88 FONT_CASE(39)
89 FONT_CASE(40)
90 FONT_CASE(41)
91 FONT_CASE(42)
92 FONT_CASE(43)
93 FONT_CASE(44)
94 FONT_CASE(45)
95 FONT_CASE(46)
96 FONT_CASE(47)
97 FONT_CASE(48)
98 FONT_CASE(49)
99 FONT_CASE(50)
100 default:
101 throw std::runtime_error("Font size not found");
102 }
103}
#define FONT_CASE(size)

References FONT_CASE.

Here is the caller graph for this function:

◆ querySwapChainSupport()

Chronos::Engine::SwapChainSupportDetails Chronos::Engine::querySwapChainSupport ( VkPhysicalDevice  device,
VkSurfaceKHR  surface 
)

For a given swapchain mode, it gets the capabilites, formats and present modes.

For a given device and surface, there are multiple available swapchain modes available for use. This gets those details for further use.

Parameters
deviceThe physical device(GPU) on which we are rendering.
surfaceThe rendering surface(basically a vulkan window.)
Returns
The support details of the swapchain.

Definition at line 65 of file swapchain.cpp.

67{
69 vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
70 device, surface, &details.capabilities);
71
72 uint32_t formatCount;
73 vkGetPhysicalDeviceSurfaceFormatsKHR(
74 device, surface, &formatCount, nullptr);
75
76 if (formatCount != 0) {
77 details.formats.resize(formatCount);
78 vkGetPhysicalDeviceSurfaceFormatsKHR(
79 device, surface, &formatCount, details.formats.data());
80 }
81
82 uint32_t presentModeCount;
83 vkGetPhysicalDeviceSurfacePresentModesKHR(
84 device, surface, &presentModeCount, nullptr);
85
86 if (presentModeCount != 0) {
87 details.presentModes.resize(presentModeCount);
88 vkGetPhysicalDeviceSurfacePresentModesKHR(
89 device, surface, &presentModeCount, details.presentModes.data());
90 }
91
92 return details;
93}
Contains the fields to the support details of a physical device.
Definition swapchain.hpp:36
VkSurfaceCapabilitiesKHR capabilities
Definition swapchain.hpp:37
std::vector< VkSurfaceFormatKHR > formats
Definition swapchain.hpp:38
std::vector< VkPresentModeKHR > presentModes
Definition swapchain.hpp:39

References Chronos::Engine::SwapChainSupportDetails::capabilities, Chronos::Engine::SwapChainSupportDetails::formats, and Chronos::Engine::SwapChainSupportDetails::presentModes.

Here is the caller graph for this function:

◆ transitionImageLayout()

void Chronos::Engine::transitionImageLayout ( VkImage  image,
VkImageLayout  oldLayout,
VkImageLayout  newLayout,
VkCommandPool  commandPool,
Chronos::Engine::Device  device 
)

Transiton a VkImage from one layout to another.

Only the following transitions are supported:

  • VK_IMAGE_LAYOUT_UNDEFINED to
    _IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
  • VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL to
    _IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
Parameters
imageThe image to be transitioned.
oldLayoutThe old layout of the image(VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL).
newLayoutThe new layout of the image(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL).

Definition at line 190 of file texture.cpp.

193{
194 VkCommandBuffer commandBuffer
196 VkImageMemoryBarrier barrier {};
197 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
198 barrier.oldLayout = oldLayout;
199 barrier.newLayout = newLayout;
200 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
201 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
202 barrier.image = image;
203 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
204 barrier.subresourceRange.baseMipLevel = 0;
205 barrier.subresourceRange.levelCount = 1;
206 barrier.subresourceRange.baseArrayLayer = 0;
207 barrier.subresourceRange.layerCount = 1;
208 VkPipelineStageFlags sourceStage;
209 VkPipelineStageFlags destinationStage;
210
211 if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED
212 && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
213 barrier.srcAccessMask = 0;
214 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
215
216 sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
217 destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
218 } else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
219 && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
220 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
221 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
222
223 sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
224 destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
225 } else {
226 throw std::invalid_argument("unsupported layout transition!");
227 }
228
229 vkCmdPipelineBarrier(commandBuffer, sourceStage, destinationStage, 0, 0,
230 nullptr, 0, nullptr, 1, &barrier);
231 Chronos::Engine::endSingleTimeCommands(&commandBuffer, device, commandPool);
232}

References beginSingleTimeCommands(), Chronos::Engine::Device::device, and endSingleTimeCommands().

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

Variable Documentation

◆ deviceExtensions

const std::vector<const char*> Chronos::Engine::deviceExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME }

THis contain the device extensions that are needed to be enabled in vulkan.

Definition at line 36 of file device.hpp.

37{ VK_KHR_SWAPCHAIN_EXTENSION_NAME };