|
KarmaEngine
Game Engine for practical learning and research purposes
|
Vulkan API has the following concepts. More...
#include <VulkanContext.h>
Public Member Functions | |
| VulkanContext (GLFWwindow *windowHandle) | |
| A constructor to set the m_vulkanRendererAPI (using static_cast, or compilet time cast). Also checks the validity of windowHandle. | |
| virtual | ~VulkanContext () override |
| Destructor of vulkan context. Does the following. | |
| virtual void | Init () override |
| Initializes VulkanContext by creating appropriate Vulkan and glslang specific instruments and allocating resources accordingly. | |
| virtual void | SwapBuffers () override |
| In Vulkan there is no default framebuffer, hence we need to explicitly swap the buffers in the swapchain. | |
| virtual bool | OnWindowResize (WindowResizeEvent &event) override |
| Calls glViewport function which specifies the affine transformation of x and y from normalized device coordinates to window coordinates. | |
| void | CreateInstance () |
| Creates Vulkan Instance which is the connection between application, which is a Game Engine, and Vulkan library. | |
| void | PrintAvailableExtensions () |
| Prints all the available extensions supported by the system's Vulkan implementation. | |
| void | PrintAvailablePhysicalDevices (const std::vector< VkPhysicalDevice > &physicalDevices) |
| Prints all the available physical devices (graphics cards) supported by the system's Vulkan implementation. | |
| bool | CheckValidationLayerSupport () |
| std::vector< const char * > | GetRequiredExtensions (VkInstanceCreateFlags &flagsToBeSet) |
| void | SetupDebugMessenger () |
| void | PopulateDebugMessengerCreateInfo (VkDebugUtilsMessengerCreateInfoEXT &createInfo) |
| VkResult | CreateDebugUtilsMessengerEXT (VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pDebugMessenger) |
| void | DestroyDebugUtilsMessengerEXT (VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks *pAllocator) |
| void | CreateSurface () |
| Platform agnostic creation of surface to present rendered images to. Typically they are backed by the category of glfw windows (on Linux, MacOS, and Windows). | |
| void | PickPhysicalDevice () |
| Picks the appropriate physical device (graphics card) for the Engine to use based on suitability. | |
| bool | IsDeviceSuitable (VkPhysicalDevice device) |
| Checks if the physical device (graphics card) is suitable for the Engine to use based on. | |
| QueueFamilyIndices | FindQueueFamilies (VkPhysicalDevice device) |
| Queries the graphics card for available queue families and compares against the availability of graphics and presentation queues. | |
| void | CreateLogicalDevice () |
| The so called logical device for interfacing with the physical device. All the machinery (swapchain, graphicspipeline, and all that) are created from logical device. Following is done: | |
| void | CreateSwapChain () |
| Vulkan does not have the concept of a "default framebuffer", hence it requires an infrastructure that will own the buffers we will render to before we visualize them on the screen. This infrastructure is known as the swap chain and must be created explicitly in Vulkan. The swap chain is essentially a queue of images that are waiting to be presented to the screen. Our backend will acquire such an image to draw to it, and then return it to the queue. Then swapchain will have to sync the presentation of image with refresh rate of the monitor. | |
| bool | CheckDeviceExtensionSupport (VkPhysicalDevice device) |
| Looks for extension properties supported by the GPU. | |
| SwapChainSupportDetails | QuerySwapChainSupport (VkPhysicalDevice device) |
| Uses Two-Pass Query to gather surface formats (physical device and surface paired color space or pixel format data) and present modes data. | |
| VkSurfaceFormatKHR | ChooseSwapSurfaceFormat (const std::vector< VkSurfaceFormatKHR > &availableFormats) |
| Chooses the best surface format (pixel format and color space) for the swapchain from the available formats. | |
| VkPresentModeKHR | ChooseSwapPresentMode (const std::vector< VkPresentModeKHR > &availablePresentModes) |
| Chooses the best presentation mode for the swapchain from the available present modes. | |
| VkExtent2D | ChooseSwapExtent (const VkSurfaceCapabilitiesKHR &capabilities) |
| Chooses the swap extent (resolution of the swapchain images) based on the capabilities of the surface and the actual window size. | |
| uint32_t | FindMemoryType (uint32_t typeFilter, VkMemoryPropertyFlags properties) |
| Finds a suitable memory type on the physical device (graphics card) based on the type filter and desired properties. | |
| void | CreateImageViews () |
| An image view is quite literally a view into an image. It describes how to access the image and which part of the image to access, for example if it should be treated as a 2D texture depth texture without any mipmapping levels. ImageView is a wrapper around render target. | |
| void | CreateRenderPass () |
| A VkRenderPass is a Vulkan object that encapsulates the state needed to setup the “target” for rendering, and the state of the images we will be rendering to. The "targets" are also known as render targets and include the attachments like colorattachment and depthattachment that describe where the rendering output will go to. | |
| void | CreateFrameBuffers () |
| Framebuffers are collections of specific memory attachments that a render pass instance uses. They represent the actual memory that the rendering operations will write to. | |
| void | CreateCommandPool () |
| Command pools are opaque objects that command buffer memory is allocated from, and which allow the implementation to amortize the cost of resource creation. | |
| void | CreateDepthResources () |
| Creates the depth resources (image, imageview, and memory) for depth buffering in 3D rendering. | |
| VkFormat | FindSupportedFormat (const std::vector< VkFormat > &candidates, VkImageTiling tiling, VkFormatFeatureFlags features) |
| Finds a supported format from the list of candidate formats based on the desired tiling and features. Used in depth resource creation. | |
| VkFormat | FindDepthFormat () |
| Finds a suitable depth format for depth buffering. | |
| bool | HasStencilComponent (VkFormat format) |
| Checks if the given format has a stencil component. | |
| void | TransitionImageLayout (VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout) |
| Transitions the layout of an image from oldLayout to newLayout. | |
| void | CopyBufferToImage (VkBuffer buffer, VkImage image, uint32_t width, uint32_t height) |
| Copies data from a buffer to an image. | |
| void | RecreateSwapChain () |
| Recreates the swapchain, typically in response to window resizing or other events that invalidate the current swapchain. | |
| void | CleanupSwapChain () |
| Cleans up the swapchain and its associated resources. | |
| void | SetVSync (bool bEnable) |
| Enables or disables vertical synchronization (VSync) for the swapchain. | |
| void | Initializeglslang () |
| Initializes the glslang library for shader compilation and processing. | |
| void | RegisterUBO (const std::shared_ptr< VulkanUniformBuffer > &ubo) |
| Registers a VulkanUniformBuffer for management by the VulkanContext. | |
| void | ClearUBO () |
| Clears all registered VulkanUniformBuffers, freeing their resources. | |
| void | RecreateUBO () |
| Recreates all registered VulkanUniformBuffers, typically in response to swapchain recreation. | |
| void | UploadUBO (size_t frameIndex) |
| Uploads data to the registered VulkanUniformBuffers for the specified frame index. | |
| VkDevice | GetLogicalDevice () const |
| VkPhysicalDevice | GetPhysicalDevice () const |
| VkExtent2D | GetSwapChainExtent () const |
| VkRenderPass | GetRenderPass () const |
| const std::vector< VkFramebuffer > & | GetSwapChainFrameBuffer () const |
| VkSwapchainKHR | GetSwapChain () const |
| const std::vector< VkImage > & | GetSwapChainImages () const |
| VkFormat | GetSwapChainImageFormat () const |
| const std::vector< VkImageView > & | GetSwapChainImageViews () const |
| VkSurfaceFormatKHR | GetSurfaceFormat () const |
| VkQueue | GetGraphicsQueue () const |
| VkQueue | GetPresentQueue () const |
| VkCommandPool | GetCommandPool () const |
| VkImageView | GetDepthImageView () const |
| const VkPhysicalDeviceFeatures & | GetSupportedDeviceFeatures () const |
| VkInstance | GetInstance () const |
| uint32_t | GetImageCount () const |
| uint32_t | GetMinImageCount () const |
| VkSurfaceKHR | GetSurface () const |
| VkPresentModeKHR | GetPresentMode () const |
| Public Member Functions inherited from Karma::GraphicsContext | |
| virtual | ~GraphicsContext () |
| A destructor. | |
Vulkan API has the following concepts.
Host : is CPU the host?
| Karma::VulkanContext::VulkanContext | ( | GLFWwindow * | windowHandle | ) |
A constructor to set the m_vulkanRendererAPI (using static_cast, or compilet time cast). Also checks the validity of windowHandle.
| windowHandle | The glfw window handle |
|
overridevirtual |
Destructor of vulkan context. Does the following.
| bool Karma::VulkanContext::CheckDeviceExtensionSupport | ( | VkPhysicalDevice | device | ) |
Looks for extension properties supported by the GPU.
Calls vkEnumerateDeviceExtensionProperties for list of supported extensions for instance VK_KHR_swapchain which is required for, well, swapchain
@
| VkExtent2D Karma::VulkanContext::ChooseSwapExtent | ( | const VkSurfaceCapabilitiesKHR & | capabilities | ) |
Chooses the swap extent (resolution of the swapchain images) based on the capabilities of the surface and the actual window size.
| capabilities | The surface capabilities (from QuerySwapChainSupport()) |
| VkPresentModeKHR Karma::VulkanContext::ChooseSwapPresentMode | ( | const std::vector< VkPresentModeKHR > & | availablePresentModes | ) |
Chooses the best presentation mode for the swapchain from the available present modes.
Basically looks for VK_PRESENT_MODE_MAILBOX_KHR (triple buffering) first, then VK_PRESENT_MODE_IMMEDIATE_KHR (tearing possible), and finally defaults to VK_PRESENT_MODE_FIFO_KHR (always available, v-sync)
| availablePresentModes | The available presentation modes (from QuerySwapChainSupport()) |
| VkSurfaceFormatKHR Karma::VulkanContext::ChooseSwapSurfaceFormat | ( | const std::vector< VkSurfaceFormatKHR > & | availableFormats | ) |
Chooses the best surface format (pixel format and color space) for the swapchain from the available formats.
Basically looks for VK_FORMAT_B8G8R8A8_SRGB and VK_COLOR_SPACE_SRGB_NONLINEAR_KHR combination.
VK_FORMAT_B8G8R8A8_SRGB : represents a 32-bit format with 8 bits for each of the blue, green, red, and alpha channels in sRGB color space. This format is widely used for swapchain images and color attachments.
VK_COLOR_SPACE_SRGB_NONLINEAR_KHR : represents the sRGB color space with a nonlinear gamma curve. This color space is commonly used for displaying images on standard monitors.
| availableFormats | The available surface formats (from QuerySwapChainSupport()) |
| void Karma::VulkanContext::CleanupSwapChain | ( | ) |
Cleans up the swapchain and its associated resources.
This involves destroying the framebuffers, image views, and the swapchain itself.
| void Karma::VulkanContext::ClearUBO | ( | ) |
Clears all registered VulkanUniformBuffers, freeing their resources.
| void Karma::VulkanContext::CopyBufferToImage | ( | VkBuffer | buffer, |
| VkImage | image, | ||
| uint32_t | width, | ||
| uint32_t | height ) |
Copies data from a buffer to an image.
This is typically used for uploading texture data from a staging buffer to a Vulkan image.
| buffer | The source buffer containing the data |
| image | The destination image |
| width | The width of the image |
| height | The height of the image |
| void Karma::VulkanContext::CreateCommandPool | ( | ) |
Command pools are opaque objects that command buffer memory is allocated from, and which allow the implementation to amortize the cost of resource creation.
| void Karma::VulkanContext::CreateDepthResources | ( | ) |
Creates the depth resources (image, imageview, and memory) for depth buffering in 3D rendering.
| void Karma::VulkanContext::CreateFrameBuffers | ( | ) |
Framebuffers are collections of specific memory attachments that a render pass instance uses. They represent the actual memory that the rendering operations will write to.
| void Karma::VulkanContext::CreateImageViews | ( | ) |
An image view is quite literally a view into an image. It describes how to access the image and which part of the image to access, for example if it should be treated as a 2D texture depth texture without any mipmapping levels. ImageView is a wrapper around render target.
| void Karma::VulkanContext::CreateInstance | ( | ) |
Creates Vulkan Instance which is the connection between application, which is a Game Engine, and Vulkan library.
| void Karma::VulkanContext::CreateLogicalDevice | ( | ) |
The so called logical device for interfacing with the physical device. All the machinery (swapchain, graphicspipeline, and all that) are created from logical device. Following is done:
| void Karma::VulkanContext::CreateRenderPass | ( | ) |
A VkRenderPass is a Vulkan object that encapsulates the state needed to setup the “target” for rendering, and the state of the images we will be rendering to. The "targets" are also known as render targets and include the attachments like colorattachment and depthattachment that describe where the rendering output will go to.
| void Karma::VulkanContext::CreateSurface | ( | ) |
Platform agnostic creation of surface to present rendered images to. Typically they are backed by the category of glfw windows (on Linux, MacOS, and Windows).
| void Karma::VulkanContext::CreateSwapChain | ( | ) |
Vulkan does not have the concept of a "default framebuffer", hence it requires an infrastructure that will own the buffers we will render to before we visualize them on the screen. This infrastructure is known as the swap chain and must be created explicitly in Vulkan. The swap chain is essentially a queue of images that are waiting to be presented to the screen. Our backend will acquire such an image to draw to it, and then return it to the queue. Then swapchain will have to sync the presentation of image with refresh rate of the monitor.
| VkFormat Karma::VulkanContext::FindDepthFormat | ( | ) |
Finds a suitable depth format for depth buffering.
| uint32_t Karma::VulkanContext::FindMemoryType | ( | uint32_t | typeFilter, |
| VkMemoryPropertyFlags | properties ) |
Finds a suitable memory type on the physical device (graphics card) based on the type filter and desired properties.
| typeFilter | Bitmask specifying the acceptable memory types |
| properties | Desired memory properties (like VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT for CPU access) |
| QueueFamilyIndices Karma::VulkanContext::FindQueueFamilies | ( | VkPhysicalDevice | device | ) |
Queries the graphics card for available queue families and compares against the availability of graphics and presentation queues.
| device | The graphics card to be queired for queue family |
| VkFormat Karma::VulkanContext::FindSupportedFormat | ( | const std::vector< VkFormat > & | candidates, |
| VkImageTiling | tiling, | ||
| VkFormatFeatureFlags | features ) |
Finds a supported format from the list of candidate formats based on the desired tiling and features. Used in depth resource creation.
| bool Karma::VulkanContext::HasStencilComponent | ( | VkFormat | format | ) |
Checks if the given format has a stencil component.
Sees if the format is VK_FORMAT_D32_SFLOAT_S8_UINT or VK_FORMAT_D24_UNORM_S8_UINT
| format | The format to be checked |
|
overridevirtual |
Initializes VulkanContext by creating appropriate Vulkan and glslang specific instruments and allocating resources accordingly.
Implements Karma::GraphicsContext.
| void Karma::VulkanContext::Initializeglslang | ( | ) |
Initializes the glslang library for shader compilation and processing.
| bool Karma::VulkanContext::IsDeviceSuitable | ( | VkPhysicalDevice | device | ) |
Checks if the physical device (graphics card) is suitable for the Engine to use based on.
avaibality of required queue families (graphics and presentation), required device extensions (like VK_KHR_swapchain), sampler anisotropy support (which is anisotropic filtering support in samplers, allowing higher-quality texture sampling at oblique angles to reduce blurring and aliasing artifacts seen in standard bilinear filtering.)
| device | The graphics card to be checked for suitability |
|
inlineoverridevirtual |
Calls glViewport function which specifies the affine transformation of x and y from normalized device coordinates to window coordinates.
Implements Karma::GraphicsContext.
| void Karma::VulkanContext::PickPhysicalDevice | ( | ) |
Picks the appropriate physical device (graphics card) for the Engine to use based on suitability.
| void Karma::VulkanContext::PrintAvailableExtensions | ( | ) |
Prints all the available extensions supported by the system's Vulkan implementation.
For instance VK_KHR_Surface or VK_KHR_get_physical_device_properties2.
| void Karma::VulkanContext::PrintAvailablePhysicalDevices | ( | const std::vector< VkPhysicalDevice > & | physicalDevices | ) |
Prints all the available physical devices (graphics cards) supported by the system's Vulkan implementation.
| SwapChainSupportDetails Karma::VulkanContext::QuerySwapChainSupport | ( | VkPhysicalDevice | device | ) |
Uses Two-Pass Query to gather surface formats (physical device and surface paired color space or pixel format data) and present modes data.
| void Karma::VulkanContext::RecreateSwapChain | ( | ) |
Recreates the swapchain, typically in response to window resizing or other events that invalidate the current swapchain.
This involves cleaning up the existing swapchain and its associated resources, and then creating a new swapchain with updated parameters.
| void Karma::VulkanContext::RecreateUBO | ( | ) |
Recreates all registered VulkanUniformBuffers, typically in response to swapchain recreation.
| void Karma::VulkanContext::RegisterUBO | ( | const std::shared_ptr< VulkanUniformBuffer > & | ubo | ) |
Registers a VulkanUniformBuffer for management by the VulkanContext.
| void Karma::VulkanContext::SetVSync | ( | bool | bEnable | ) |
Enables or disables vertical synchronization (VSync) for the swapchain.
VSync synchronizes the frame rate of the application with the refresh rate of the monitor to prevent screen tearing.
| bEnable | True to enable VSync, false to disable |
|
overridevirtual |
In Vulkan there is no default framebuffer, hence we need to explicitly swap the buffers in the swapchain.
For instance, acquire an image from the swapchain, execute the command buffer with that image as attachment in the framebuffer, and return the image to the swapchain for presentation. All these are done in VulkanRendererAPI::SubmitCommandBuffers(). So no need to do anything here.
Implements Karma::GraphicsContext.
| void Karma::VulkanContext::TransitionImageLayout | ( | VkImage | image, |
| VkFormat | format, | ||
| VkImageLayout | oldLayout, | ||
| VkImageLayout | newLayout ) |
Transitions the layout of an image from oldLayout to newLayout.
Image layout transitions are crucial in Vulkan to ensure that images are in the correct state for different operations, such as rendering, sampling, or transferring data.
| image | The image to be transitioned |
| format | The format of the image |
| oldLayout | The current layout of the image |
| newLayout | The desired layout of the image |
| void Karma::VulkanContext::UploadUBO | ( | size_t | frameIndex | ) |
Uploads data to the registered VulkanUniformBuffers for the specified frame index.
Typically called during rendering to update uniform buffer data for the current frame like so
| frameIndex | The index of the frame for which to upload UBO data |