HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
gui_device_vulkan.hpp
1// Copyright Take Vos 2019-2020.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "gui_device.hpp"
8#include "gui_system_globals.hpp"
9#include "pipeline_flat_device_shared.hpp"
10#include "pipeline_image_device_shared.hpp"
11#include "pipeline_box_device_shared.hpp"
12#include "pipeline_SDF_device_shared.hpp"
13#include "pipeline_tone_mapper_device_shared.hpp"
14#include <vulkan/vulkan.hpp>
15#include <vk_mem_alloc.h>
16
17namespace tt {
18class URL;
19}
20
21namespace tt {
22
23class gui_device_vulkan final : public gui_device {
24public:
25 vk::PhysicalDeviceType deviceType = vk::PhysicalDeviceType::eOther;
26 vk::PhysicalDeviceProperties physicalProperties;
27
28 uint32_t graphicsQueueFamilyIndex = 0;
29 uint32_t presentQueueFamilyIndex = 0;
30 uint32_t computeQueueFamilyIndex = 0;
31 uint32_t graphicsQueueIndex = 0;
32 uint32_t presentQueueIndex = 0;
33 uint32_t computeQueueIndex = 0;
34 vk::Queue graphicsQueue;
35 vk::Queue presentQueue;
36 vk::Queue computeQueue;
37 vk::CommandPool graphicsCommandPool;
38 vk::CommandPool presentCommandPool;
39 vk::CommandPool computeCommandPool;
40
51 vk::Buffer quadIndexBuffer;
52 VmaAllocation quadIndexBufferAllocation = {};
53
59
63
64 bool supportsLazyTransientImages = false;
65 vk::ImageUsageFlags transientImageUsageFlags = vk::ImageUsageFlags{};
66 VmaMemoryUsage lazyMemoryUsage = VMA_MEMORY_USAGE_GPU_ONLY;
67
72
76 mutable vk::SurfaceFormatKHR bestSurfaceFormat = {};
77
81 mutable vk::PresentModeKHR bestSurfacePresentMode = vk::PresentModeKHR::eFifo;
82
83 gui_device_vulkan(gui_system &system, vk::PhysicalDevice physicalDevice);
85
86 gui_device_vulkan(const gui_device_vulkan &) = delete;
87 gui_device_vulkan &operator=(const gui_device_vulkan &) = delete;
89 gui_device_vulkan &operator=(gui_device_vulkan &&) = delete;
90
91 void initialize_device(gui_window const &window) override;
92
93 int score(vk::SurfaceKHR surface) const;
94
95 int score(gui_window const &window) const override;
96
105
107 createBuffer(const vk::BufferCreateInfo &bufferCreateInfo, const VmaAllocationCreateInfo &allocationCreateInfo) const;
108
109 void destroyBuffer(const vk::Buffer &buffer, const VmaAllocation &allocation) const;
110
112 createImage(const vk::ImageCreateInfo &imageCreateInfo, const VmaAllocationCreateInfo &allocationCreateInfo) const;
113 void destroyImage(const vk::Image &image, const VmaAllocation &allocation) const;
114
115 vk::CommandBuffer beginSingleTimeCommands() const;
116 void endSingleTimeCommands(vk::CommandBuffer commandBuffer) const;
117
118 static void transition_layout(
119 vk::CommandBuffer command_buffer,
120 vk::Image image,
121 vk::Format format,
122 vk::ImageLayout src_layout,
123 vk::ImageLayout dst_layout);
124 void transition_layout(vk::Image image, vk::Format format, vk::ImageLayout src_layout, vk::ImageLayout dst_layout) const;
125
126 void copyImage(
127 vk::Image srcImage,
128 vk::ImageLayout srcLayout,
129 vk::Image dstImage,
130 vk::ImageLayout dstLayout,
131 vk::ArrayProxy<vk::ImageCopy const> regions) const;
132 void clearColorImage(
133 vk::Image image,
134 vk::ImageLayout layout,
135 vk::ClearColorValue const &color,
136 vk::ArrayProxy<const vk::ImageSubresourceRange> ranges) const;
137
138 template<typename T>
139 std::span<T> mapMemory(const VmaAllocation &allocation) const
140 {
141 ttlet lock = std::scoped_lock(gui_system_mutex);
142
143 void *mapping;
144 ttlet result = static_cast<vk::Result>(vmaMapMemory(allocator, allocation, &mapping));
145
146 VmaAllocationInfo allocationInfo;
147 vmaGetAllocationInfo(allocator, allocation, &allocationInfo);
148
149 // Should we launder the pointer? The GPU has created the objects, not the C++ application.
150 T *mappingT = reinterpret_cast<T *>(mapping);
151 ttlet mappingSpan = std::span<T>(mappingT, allocationInfo.size / sizeof(T));
152
153 return vk::createResultValue(result, mappingSpan, "tt::gui_device_vulkan::mapMemory");
154 }
155
156 void unmapMemory(const VmaAllocation &allocation) const;
157
158 void flushAllocation(const VmaAllocation &allocation, VkDeviceSize offset, VkDeviceSize size) const
159 {
160 ttlet lock = std::scoped_lock(gui_system_mutex);
161
162 ttlet alignment = physicalProperties.limits.nonCoherentAtomSize;
163
164 ttlet alignedOffset = (offset / alignment) * alignment;
165 ttlet adjustedSize = size + (offset - alignedOffset);
166 ttlet alignedSize = ((adjustedSize + (alignment - 1)) / alignment) * alignment;
167
168 vmaFlushAllocation(allocator, allocation, alignedOffset, alignedSize);
169 }
170
171 vk::ShaderModule loadShader(uint32_t const *data, size_t size) const;
172
173 vk::ShaderModule loadShader(std::span<std::byte const> shaderObjectBytes) const;
174
175 vk::ShaderModule loadShader(URL const &shaderObjectLocation) const;
176
177 void waitIdle() const
178 {
179 ttlet lock = std::scoped_lock(gui_system_mutex);
180 return intrinsic.waitIdle();
181 }
182
183 vk::Result waitForFences(vk::ArrayProxy<const vk::Fence> fences, vk::Bool32 waitAll, uint64_t timeout) const
184 {
185 ttlet lock = std::scoped_lock(gui_system_mutex);
186 return intrinsic.waitForFences(fences, waitAll, timeout);
187 }
188
189 vk::Result acquireNextImageKHR(
190 vk::SwapchainKHR swapchain,
191 uint64_t timeout,
192 vk::Semaphore semaphore,
193 vk::Fence fence,
194 uint32_t *pImageIndex) const
195 {
196 ttlet lock = std::scoped_lock(gui_system_mutex);
197 return intrinsic.acquireNextImageKHR(swapchain, timeout, semaphore, fence, pImageIndex);
198 }
199
200 void resetFences(vk::ArrayProxy<const vk::Fence> fences) const
201 {
202 ttlet lock = std::scoped_lock(gui_system_mutex);
203 return intrinsic.resetFences(fences);
204 }
205
206 vk::Result createSwapchainKHR(
207 const vk::SwapchainCreateInfoKHR *pCreateInfo,
208 const vk::AllocationCallbacks *pAllocator,
209 vk::SwapchainKHR *pSwapchain) const
210 {
211 ttlet lock = std::scoped_lock(gui_system_mutex);
212 return intrinsic.createSwapchainKHR(pCreateInfo, pAllocator, pSwapchain);
213 }
214
215 std::vector<vk::Image> getSwapchainImagesKHR(vk::SwapchainKHR swapchain) const
216 {
217 ttlet lock = std::scoped_lock(gui_system_mutex);
218 return intrinsic.getSwapchainImagesKHR(swapchain);
219 }
220
221 vk::ImageView createImageView(const vk::ImageViewCreateInfo &createInfo) const
222 {
223 ttlet lock = std::scoped_lock(gui_system_mutex);
224 return intrinsic.createImageView(createInfo);
225 }
226
227 vk::Framebuffer createFramebuffer(const vk::FramebufferCreateInfo &createInfo) const
228 {
229 ttlet lock = std::scoped_lock(gui_system_mutex);
230 return intrinsic.createFramebuffer(createInfo);
231 }
232
233 vk::RenderPass createRenderPass(const vk::RenderPassCreateInfo &createInfo) const
234 {
235 ttlet lock = std::scoped_lock(gui_system_mutex);
236 return intrinsic.createRenderPass(createInfo);
237 }
238
239 vk::Semaphore createSemaphore(const vk::SemaphoreCreateInfo &createInfo) const
240 {
241 ttlet lock = std::scoped_lock(gui_system_mutex);
242 return intrinsic.createSemaphore(createInfo);
243 }
244
245 vk::Fence createFence(const vk::FenceCreateInfo &createInfo) const
246 {
247 ttlet lock = std::scoped_lock(gui_system_mutex);
248 return intrinsic.createFence(createInfo);
249 }
250
251 vk::DescriptorSetLayout createDescriptorSetLayout(const vk::DescriptorSetLayoutCreateInfo &createInfo) const
252 {
253 ttlet lock = std::scoped_lock(gui_system_mutex);
254 return intrinsic.createDescriptorSetLayout(createInfo);
255 }
256
257 vk::DescriptorPool createDescriptorPool(const vk::DescriptorPoolCreateInfo &createInfo) const
258 {
259 ttlet lock = std::scoped_lock(gui_system_mutex);
260 return intrinsic.createDescriptorPool(createInfo);
261 }
262
263 vk::PipelineLayout createPipelineLayout(const vk::PipelineLayoutCreateInfo &createInfo) const
264 {
265 ttlet lock = std::scoped_lock(gui_system_mutex);
266 return intrinsic.createPipelineLayout(createInfo);
267 }
268
269 vk::Pipeline createGraphicsPipeline(vk::PipelineCache pipelineCache, const vk::GraphicsPipelineCreateInfo &createInfo) const
270 {
271 ttlet lock = std::scoped_lock(gui_system_mutex);
272 return intrinsic.createGraphicsPipeline(pipelineCache, createInfo).value;
273 }
274
275 vk::Sampler createSampler(const vk::SamplerCreateInfo &createInfo) const
276 {
277 ttlet lock = std::scoped_lock(gui_system_mutex);
278 return intrinsic.createSampler(createInfo);
279 }
280
281 std::vector<vk::DescriptorSet> allocateDescriptorSets(const vk::DescriptorSetAllocateInfo &allocateInfo) const
282 {
283 ttlet lock = std::scoped_lock(gui_system_mutex);
284 return intrinsic.allocateDescriptorSets(allocateInfo);
285 }
286
287 std::vector<vk::CommandBuffer> allocateCommandBuffers(const vk::CommandBufferAllocateInfo &allocateInfo) const
288 {
289 ttlet lock = std::scoped_lock(gui_system_mutex);
290 return intrinsic.allocateCommandBuffers(allocateInfo);
291 }
292
293 void updateDescriptorSets(
294 vk::ArrayProxy<const vk::WriteDescriptorSet> descriptorWrites,
295 vk::ArrayProxy<const vk::CopyDescriptorSet> descriptorCopies) const
296 {
297 ttlet lock = std::scoped_lock(gui_system_mutex);
298 return intrinsic.updateDescriptorSets(descriptorWrites, descriptorCopies);
299 }
300
301 void freeCommandBuffers(vk::CommandPool commandPool, vk::ArrayProxy<const vk::CommandBuffer> commandBuffers) const
302 {
303 ttlet lock = std::scoped_lock(gui_system_mutex);
304 return intrinsic.freeCommandBuffers(commandPool, commandBuffers);
305 }
306
307 template<typename T>
308 void destroy(T x) const
309 {
310 ttlet lock = std::scoped_lock(gui_system_mutex);
311 intrinsic.destroy(x);
312 }
313
314 vk::SurfaceCapabilitiesKHR getSurfaceCapabilitiesKHR(vk::SurfaceKHR surface) const
315 {
316 ttlet lock = std::scoped_lock(gui_system_mutex);
317 return physicalIntrinsic.getSurfaceCapabilitiesKHR(surface);
318 }
319
320protected:
321 vk::PhysicalDevice physicalIntrinsic;
322 vk::Device intrinsic;
323 VmaAllocator allocator;
324
325private:
326 void initialize_quad_index_buffer();
327 void destroy_quad_index_buffer();
328};
329
330} // namespace tt
This is a RGBA floating point color.
Definition color.hpp:39
Definition gui_device.hpp:22
Definition gui_device_vulkan.hpp:23
void initialize_device(gui_window const &window) override
std::vector< std::pair< uint32_t, uint8_t > > find_best_queue_family_indices(vk::SurfaceKHR surface) const
int score(gui_window const &window) const override
vk::PresentModeKHR bestSurfacePresentMode
Definition gui_device_vulkan.hpp:81
std::vector< std::pair< uint32_t, uint8_t > > queueFamilyIndicesAndCapabilities
Definition gui_device_vulkan.hpp:71
vk::SurfaceFormatKHR bestSurfaceFormat
Definition gui_device_vulkan.hpp:76
vk::Buffer quadIndexBuffer
Shared index buffer containing indices for drawing quads.
Definition gui_device_vulkan.hpp:51
std::vector< const char * > requiredExtensions
Definition gui_device_vulkan.hpp:62
Vulkan gui_device controller.
Definition gui_system.hpp:24
Definition gui_window.hpp:37
T lock(T... args)