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 <vma/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
106 std::pair<vk::Buffer, VmaAllocation> createBuffer(const vk::BufferCreateInfo &bufferCreateInfo, const VmaAllocationCreateInfo &allocationCreateInfo) const;
107
108 void destroyBuffer(const vk::Buffer &buffer, const VmaAllocation &allocation) const;
109
110 std::pair<vk::Image, VmaAllocation> createImage(const vk::ImageCreateInfo &imageCreateInfo, const VmaAllocationCreateInfo &allocationCreateInfo) const;
111 void destroyImage(const vk::Image &image, const VmaAllocation &allocation) const;
112
113 vk::CommandBuffer beginSingleTimeCommands() const;
114 void endSingleTimeCommands(vk::CommandBuffer commandBuffer) const;
115
116 void transitionLayout(vk::Image image, vk::Format format, vk::ImageLayout srcLayout, vk::ImageLayout dstLayout) const;
117 void copyImage(vk::Image srcImage, vk::ImageLayout srcLayout, vk::Image dstImage, vk::ImageLayout dstLayout, vk::ArrayProxy<vk::ImageCopy const> regions) const;
118 void clearColorImage(vk::Image image, vk::ImageLayout layout, vk::ClearColorValue const &color, vk::ArrayProxy<const vk::ImageSubresourceRange> ranges) const;
119
120 template <typename T>
121 std::span<T> mapMemory(const VmaAllocation &allocation) const {
122 ttlet lock = std::scoped_lock(gui_system_mutex);
123
124 void *mapping;
125 ttlet result = static_cast<vk::Result>(vmaMapMemory(allocator, allocation, &mapping));
126
127 VmaAllocationInfo allocationInfo;
128 vmaGetAllocationInfo(allocator, allocation, &allocationInfo);
129
130 // Should we launder the pointer? The GPU has created the objects, not the C++ application.
131 T *mappingT = reinterpret_cast<T *>(mapping);
132 ttlet mappingSpan = std::span<T>(mappingT, allocationInfo.size / sizeof (T));
133
134 return vk::createResultValue(result, mappingSpan, "tt::gui_device_vulkan::mapMemory");
135 }
136
137 void unmapMemory(const VmaAllocation &allocation) const;
138
139 void flushAllocation(const VmaAllocation &allocation, VkDeviceSize offset, VkDeviceSize size) const {
140 ttlet lock = std::scoped_lock(gui_system_mutex);
141
142 ttlet alignment = physicalProperties.limits.nonCoherentAtomSize;
143
144 ttlet alignedOffset = (offset / alignment) * alignment;
145 ttlet adjustedSize = size + (offset - alignedOffset);
146 ttlet alignedSize = ((adjustedSize + (alignment - 1)) / alignment) * alignment;
147
148 vmaFlushAllocation(allocator, allocation, alignedOffset, alignedSize);
149 }
150
151 vk::ShaderModule loadShader(uint32_t const *data, size_t size) const;
152
153 vk::ShaderModule loadShader(std::span<std::byte const> shaderObjectBytes) const;
154
155 vk::ShaderModule loadShader(URL const &shaderObjectLocation) const;
156
157
158 void waitIdle() const {
159 ttlet lock = std::scoped_lock(gui_system_mutex);
160 return intrinsic.waitIdle();
161 }
162
163 vk::Result waitForFences(vk::ArrayProxy<const vk::Fence> fences, vk::Bool32 waitAll, uint64_t timeout) const {
164 ttlet lock = std::scoped_lock(gui_system_mutex);
165 return intrinsic.waitForFences(fences, waitAll, timeout);
166 }
167
168 vk::Result acquireNextImageKHR(vk::SwapchainKHR swapchain, uint64_t timeout, vk::Semaphore semaphore, vk::Fence fence, uint32_t* pImageIndex) const {
169 ttlet lock = std::scoped_lock(gui_system_mutex);
170 return intrinsic.acquireNextImageKHR(swapchain, timeout, semaphore, fence, pImageIndex);
171 }
172
173 void resetFences(vk::ArrayProxy<const vk::Fence> fences) const {
174 ttlet lock = std::scoped_lock(gui_system_mutex);
175 return intrinsic.resetFences(fences);
176 }
177
178 vk::Result createSwapchainKHR(const vk::SwapchainCreateInfoKHR* pCreateInfo, const vk::AllocationCallbacks* pAllocator, vk::SwapchainKHR* pSwapchain) const {
179 ttlet lock = std::scoped_lock(gui_system_mutex);
180 return intrinsic.createSwapchainKHR(pCreateInfo, pAllocator, pSwapchain);
181 }
182
183 std::vector<vk::Image> getSwapchainImagesKHR(vk::SwapchainKHR swapchain) const {
184 ttlet lock = std::scoped_lock(gui_system_mutex);
185 return intrinsic.getSwapchainImagesKHR(swapchain);
186 }
187
188 vk::ImageView createImageView(const vk::ImageViewCreateInfo& createInfo) const {
189 ttlet lock = std::scoped_lock(gui_system_mutex);
190 return intrinsic.createImageView(createInfo);
191 }
192
193 vk::Framebuffer createFramebuffer(const vk::FramebufferCreateInfo& createInfo) const {
194 ttlet lock = std::scoped_lock(gui_system_mutex);
195 return intrinsic.createFramebuffer(createInfo);
196 }
197
198 vk::RenderPass createRenderPass(const vk::RenderPassCreateInfo& createInfo) const {
199 ttlet lock = std::scoped_lock(gui_system_mutex);
200 return intrinsic.createRenderPass(createInfo);
201 }
202
203 vk::Semaphore createSemaphore(const vk::SemaphoreCreateInfo& createInfo) const {
204 ttlet lock = std::scoped_lock(gui_system_mutex);
205 return intrinsic.createSemaphore(createInfo);
206 }
207
208 vk::Fence createFence(const vk::FenceCreateInfo& createInfo) const {
209 ttlet lock = std::scoped_lock(gui_system_mutex);
210 return intrinsic.createFence(createInfo);
211 }
212
213 vk::DescriptorSetLayout createDescriptorSetLayout(const vk::DescriptorSetLayoutCreateInfo& createInfo) const {
214 ttlet lock = std::scoped_lock(gui_system_mutex);
215 return intrinsic.createDescriptorSetLayout(createInfo);
216 }
217
218 vk::DescriptorPool createDescriptorPool(const vk::DescriptorPoolCreateInfo& createInfo) const {
219 ttlet lock = std::scoped_lock(gui_system_mutex);
220 return intrinsic.createDescriptorPool(createInfo);
221 }
222
223 vk::PipelineLayout createPipelineLayout(const vk::PipelineLayoutCreateInfo& createInfo) const {
224 ttlet lock = std::scoped_lock(gui_system_mutex);
225 return intrinsic.createPipelineLayout(createInfo);
226 }
227
228 vk::Pipeline createGraphicsPipeline(vk::PipelineCache pipelineCache, const vk::GraphicsPipelineCreateInfo& createInfo) const {
229 ttlet lock = std::scoped_lock(gui_system_mutex);
230 return intrinsic.createGraphicsPipeline(pipelineCache, createInfo);
231 }
232
233 vk::Sampler createSampler(const vk::SamplerCreateInfo& createInfo) const {
234 ttlet lock = std::scoped_lock(gui_system_mutex);
235 return intrinsic.createSampler(createInfo);
236 }
237
238 std::vector<vk::DescriptorSet> allocateDescriptorSets(const vk::DescriptorSetAllocateInfo& allocateInfo) const {
239 ttlet lock = std::scoped_lock(gui_system_mutex);
240 return intrinsic.allocateDescriptorSets(allocateInfo);
241 }
242
243 std::vector<vk::CommandBuffer> allocateCommandBuffers(const vk::CommandBufferAllocateInfo& allocateInfo) const {
244 ttlet lock = std::scoped_lock(gui_system_mutex);
245 return intrinsic.allocateCommandBuffers(allocateInfo);
246 }
247
248 void updateDescriptorSets(vk::ArrayProxy<const vk::WriteDescriptorSet> descriptorWrites, vk::ArrayProxy<const vk::CopyDescriptorSet> descriptorCopies) const {
249 ttlet lock = std::scoped_lock(gui_system_mutex);
250 return intrinsic.updateDescriptorSets(descriptorWrites, descriptorCopies);
251 }
252
253 void freeCommandBuffers(vk::CommandPool commandPool, vk::ArrayProxy<const vk::CommandBuffer> commandBuffers) const {
254 ttlet lock = std::scoped_lock(gui_system_mutex);
255 return intrinsic.freeCommandBuffers(commandPool, commandBuffers);
256 }
257
258 template<typename T>
259 void destroy(T x) const {
260 ttlet lock = std::scoped_lock(gui_system_mutex);
261 intrinsic.destroy(x);
262 }
263
264 vk::SurfaceCapabilitiesKHR getSurfaceCapabilitiesKHR(vk::SurfaceKHR surface) const {
265 ttlet lock = std::scoped_lock(gui_system_mutex);
266 return physicalIntrinsic.getSurfaceCapabilitiesKHR(surface);
267 }
268
269protected:
270 vk::PhysicalDevice physicalIntrinsic;
271 vk::Device intrinsic;
272 VmaAllocator allocator;
273
274private:
275 void initialize_quad_index_buffer();
276 void destroy_quad_index_buffer();
277};
278
279}
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:39
T lock(T... args)