TGUI 1.14-dev
Loading...
Searching...
No Matches
BackendRendererVulkan.hpp
1
2//
3// TGUI - Texus' Graphical User Interface
4// Copyright (C) 2012-2026 Bruno Van de Velde (vdv_b@tgui.eu)
5//
6// This software is provided 'as-is', without any express or implied warranty.
7// In no event will the authors be held liable for any damages arising from the use of this software.
8//
9// Permission is granted to anyone to use this software for any purpose,
10// including commercial applications, and to alter it and redistribute it freely,
11// subject to the following restrictions:
12//
13// 1. The origin of this software must not be misrepresented;
14// you must not claim that you wrote the original software.
15// If you use this software in a product, an acknowledgment
16// in the product documentation would be appreciated but is not required.
17//
18// 2. Altered source versions must be plainly marked as such,
19// and must not be misrepresented as being the original software.
20//
21// 3. This notice may not be removed or altered from any source distribution.
22//
24
25#ifndef TGUI_BACKEND_RENDERER_VULKAN_HPP
26#define TGUI_BACKEND_RENDERER_VULKAN_HPP
27
28#include <TGUI/Backend/Renderer/BackendRenderer.hpp>
29#include <TGUI/Backend/Renderer/Vulkan/BackendRenderTargetVulkan.hpp>
30#include <TGUI/Backend/Renderer/Vulkan/BackendTextureVulkan.hpp>
31#include <TGUI/Backend/Renderer/Vulkan/CanvasVulkan.hpp>
32
33#include <functional>
34#include <memory>
35#include <vector>
36#include <vulkan/vulkan.h>
37
39
40namespace tgui
41{
50 {
51 VkInstance instance = VK_NULL_HANDLE;
52 VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
53 std::uint32_t queueFamilyIndex = 0;
54 VkDevice device = VK_NULL_HANDLE;
55 VkQueue queue = VK_NULL_HANDLE;
56
59 PFN_vkGetInstanceProcAddr getInstanceProcAddr = nullptr;
60 };
61
71 class TGUI_API BackendRendererVulkan : public BackendRenderer, public std::enable_shared_from_this<BackendRendererVulkan>
72 {
73 public:
81 struct Functions
82 {
83 // Instance-level functions
84 PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr = nullptr;
85 PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties = nullptr;
86 PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties = nullptr;
87
88 // Instance-level functions from VK_KHR_surface
89 PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR = nullptr;
90 PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR = nullptr;
91 PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR = nullptr;
92 PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR = nullptr;
93
94 // Device-level functions
95 PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers = nullptr;
96 PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets = nullptr;
97 PFN_vkAllocateMemory vkAllocateMemory = nullptr;
98 PFN_vkBeginCommandBuffer vkBeginCommandBuffer = nullptr;
99 PFN_vkBindBufferMemory vkBindBufferMemory = nullptr;
100 PFN_vkBindImageMemory vkBindImageMemory = nullptr;
101 PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass = nullptr;
102 PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets = nullptr;
103 PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer = nullptr;
104 PFN_vkCmdBindPipeline vkCmdBindPipeline = nullptr;
105 PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers = nullptr;
106 PFN_vkCmdClearColorImage vkCmdClearColorImage = nullptr;
107 PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage = nullptr;
108 PFN_vkCmdDrawIndexed vkCmdDrawIndexed = nullptr;
109 PFN_vkCmdEndRenderPass vkCmdEndRenderPass = nullptr;
110 PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier = nullptr;
111 PFN_vkCmdSetScissor vkCmdSetScissor = nullptr;
112 PFN_vkCmdSetViewport vkCmdSetViewport = nullptr;
113 PFN_vkCreateBuffer vkCreateBuffer = nullptr;
114 PFN_vkCreateCommandPool vkCreateCommandPool = nullptr;
115 PFN_vkCreateDescriptorPool vkCreateDescriptorPool = nullptr;
116 PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout = nullptr;
117 PFN_vkCreateFence vkCreateFence = nullptr;
118 PFN_vkCreateFramebuffer vkCreateFramebuffer = nullptr;
119 PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines = nullptr;
120 PFN_vkCreateImage vkCreateImage = nullptr;
121 PFN_vkCreateImageView vkCreateImageView = nullptr;
122 PFN_vkCreatePipelineLayout vkCreatePipelineLayout = nullptr;
123 PFN_vkCreateRenderPass vkCreateRenderPass = nullptr;
124 PFN_vkCreateSampler vkCreateSampler = nullptr;
125 PFN_vkCreateSemaphore vkCreateSemaphore = nullptr;
126 PFN_vkCreateShaderModule vkCreateShaderModule = nullptr;
127 PFN_vkDestroyBuffer vkDestroyBuffer = nullptr;
128 PFN_vkDestroyCommandPool vkDestroyCommandPool = nullptr;
129 PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool = nullptr;
130 PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout = nullptr;
131 PFN_vkDestroyFence vkDestroyFence = nullptr;
132 PFN_vkDestroyFramebuffer vkDestroyFramebuffer = nullptr;
133 PFN_vkDestroyImage vkDestroyImage = nullptr;
134 PFN_vkDestroyImageView vkDestroyImageView = nullptr;
135 PFN_vkDestroyPipeline vkDestroyPipeline = nullptr;
136 PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout = nullptr;
137 PFN_vkDestroyRenderPass vkDestroyRenderPass = nullptr;
138 PFN_vkDestroySampler vkDestroySampler = nullptr;
139 PFN_vkDestroySemaphore vkDestroySemaphore = nullptr;
140 PFN_vkDestroyShaderModule vkDestroyShaderModule = nullptr;
141 PFN_vkEndCommandBuffer vkEndCommandBuffer = nullptr;
142 PFN_vkFreeCommandBuffers vkFreeCommandBuffers = nullptr;
143 PFN_vkFreeDescriptorSets vkFreeDescriptorSets = nullptr;
144 PFN_vkFreeMemory vkFreeMemory = nullptr;
145 PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements = nullptr;
146 PFN_vkGetFenceStatus vkGetFenceStatus = nullptr;
147 PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements = nullptr;
148 PFN_vkMapMemory vkMapMemory = nullptr;
149 PFN_vkQueueSubmit vkQueueSubmit = nullptr;
150 PFN_vkQueueWaitIdle vkQueueWaitIdle = nullptr;
151 PFN_vkResetCommandBuffer vkResetCommandBuffer = nullptr;
152 PFN_vkResetFences vkResetFences = nullptr;
153 PFN_vkUnmapMemory vkUnmapMemory = nullptr;
154 PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets = nullptr;
155 PFN_vkWaitForFences vkWaitForFences = nullptr;
156
157 // Device-level function from the VK_EXT_debug_utils instance extension
158 PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT = nullptr;
159
160 // Device-level functions from VK_KHR_swapchain
161 PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR = nullptr;
162 PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR = nullptr;
163 PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR = nullptr;
164 PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR = nullptr;
165 PFN_vkQueuePresentKHR vkQueuePresentKHR = nullptr;
166 };
167
177
182
187 [[nodiscard]] std::shared_ptr<BackendTexture> createTexture() override;
188
196 [[nodiscard]] unsigned int getMaximumTextureSize() override;
197
203 [[nodiscard]] const VulkanContext& getVulkanContext() const;
204
210 [[nodiscard]] const Functions& getFunctions() const;
211
220 [[nodiscard]] static bool isSrgbFormat(VkFormat format);
221
235 [[nodiscard]] VkPipeline createPipeline(
236 VkRenderPass renderPass,
237 std::uint32_t subpass,
238 VkFormat colorFormat,
239 VkFormat depthFormat,
240 VkFormat stencilFormat,
241 VkSampleCountFlagBits samples) const;
242
250 [[nodiscard]] VkPipelineLayout getPipelineLayout() const;
251
258 [[nodiscard]] VkDescriptorSet getSamplerDescriptorSet(bool smooth) const;
259
269 [[nodiscard]] VkDescriptorSet allocateTextureDescriptorSet(VkImageView imageView, VkDescriptorPool& pool);
270
275 void freeTextureDescriptorSet(VkDescriptorSet descriptorSet, VkDescriptorPool pool);
276
283 [[nodiscard]] bool createBuffer(VkDeviceSize size,
284 VkBufferUsageFlags usage,
285 VkMemoryPropertyFlags memoryProperties,
286 VkBuffer& buffer,
287 VkDeviceMemory& memory) const;
288
295 [[nodiscard]] std::uint32_t findMemoryType(std::uint32_t memoryTypeBits, VkMemoryPropertyFlags properties) const;
296
308 [[nodiscard]] std::uint64_t submitUploadCommands(const std::function<void(VkCommandBuffer)>& recordFunc,
309 VkBuffer stagingBuffer,
310 VkDeviceMemory stagingMemory);
311
318 void waitForUpload(std::uint64_t uploadId);
319
324 void releaseFinishedUploads();
325
332 template <typename HandleType>
333 void setObjectName(VkObjectType objectType, HandleType handle, const char* name) const
334 {
335 if (!m_functions.vkSetDebugUtilsObjectNameEXT || (handle == VK_NULL_HANDLE))
336 return;
337
338 VkDebugUtilsObjectNameInfoEXT nameInfo = {};
339 nameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
340 nameInfo.objectType = objectType;
341 nameInfo.objectHandle = reinterpret_cast<std::uint64_t>(handle);
342 nameInfo.pObjectName = name;
343 m_functions.vkSetDebugUtilsObjectNameEXT(m_vulkanContext.device, &nameInfo);
344 }
345
347
348 private:
349 struct Upload
350 {
351 VkCommandBuffer cmdBuffer = VK_NULL_HANDLE;
352 VkFence fence = VK_NULL_HANDLE; // Unsignaled while the upload slot isn't in use
353 VkBuffer stagingBuffer = VK_NULL_HANDLE;
354 VkDeviceMemory stagingMemory = VK_NULL_HANDLE;
355 std::uint64_t id = 0; // 0 when the upload slot isn't in use
356 };
357
359 // Destroys the staging buffer of an upload that finished executing and marks the upload slot as unused
361 void finishUpload(Upload& upload);
362
364 // Creates the Vulkan objects that are shared between all textures and render targets
366 void createVulkanObjects();
367
369 // Destroys the objects that were created in createVulkanObjects
371 void destroyVulkanObjects();
372
374
375 private:
376 struct DescriptorPool
377 {
378 VkDescriptorPool pool;
379 std::uint32_t allocatedSets;
380 };
381
382 VulkanContext m_vulkanContext;
383 Functions m_functions;
384 VkPhysicalDeviceMemoryProperties m_memoryProperties = {};
385 unsigned int m_maxTextureSize = 0;
386
387 VkShaderModule m_vertexShaderModule = VK_NULL_HANDLE;
388 VkShaderModule m_fragmentShaderModule = VK_NULL_HANDLE;
389 VkDescriptorSetLayout m_textureDescriptorSetLayout = VK_NULL_HANDLE;
390 VkDescriptorSetLayout m_samplerDescriptorSetLayout = VK_NULL_HANDLE;
391 VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
392
393 VkSampler m_samplerNearest = VK_NULL_HANDLE;
394 VkSampler m_samplerLinear = VK_NULL_HANDLE;
395 VkDescriptorPool m_samplerDescriptorPool = VK_NULL_HANDLE;
396 VkDescriptorSet m_samplerDescriptorSetNearest = VK_NULL_HANDLE;
397 VkDescriptorSet m_samplerDescriptorSetLinear = VK_NULL_HANDLE;
398 std::vector<DescriptorPool> m_textureDescriptorPools;
399
400 VkCommandPool m_commandPool = VK_NULL_HANDLE;
401 std::vector<Upload> m_uploads;
402 std::uint64_t m_lastUploadId = 0;
403 };
404} // namespace tgui
405
406#endif // TGUI_BACKEND_RENDERER_VULKAN_HPP
const Functions & getFunctions() const
Returns the Vulkan functions that were loaded by the renderer.
unsigned int getMaximumTextureSize() override
Get the maximum allowed texture size.
BackendRendererVulkan(const VulkanContext &vulkanContext)
Initializes the backend renderer.
~BackendRendererVulkan() override
Destructor.
const VulkanContext & getVulkanContext() const
Returns the Vulkan objects that were passed to the constructor of this object.
std::shared_ptr< BackendTexture > createTexture() override
Creates a new empty texture object.
Base class for the backend renderer, which is responsible for creating text and texture objects.
Definition BackendRenderer.hpp:41
Namespace that contains all TGUI functions and classes.
Definition AbsoluteOrRelativeValue.hpp:37
Vulkan functions that are used by TGUI.
Definition BackendRendererVulkan.hpp:82
Vulkan objects that TGUI needs to render.
Definition BackendRendererVulkan.hpp:50
VkDevice device
Logical device used for rendering.
Definition BackendRendererVulkan.hpp:54
VkPhysicalDevice physicalDevice
Physical device on which the device was created.
Definition BackendRendererVulkan.hpp:52
std::uint32_t queueFamilyIndex
Queue family of the queue.
Definition BackendRendererVulkan.hpp:53
VkInstance instance
Instance that was used to create the device.
Definition BackendRendererVulkan.hpp:51
PFN_vkGetInstanceProcAddr getInstanceProcAddr
Definition BackendRendererVulkan.hpp:59
VkQueue queue
Queue that is used for rendering.
Definition BackendRendererVulkan.hpp:55