HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
GUIDevice_vulkan.hpp
1// Copyright 2019 Pokitec
2// All rights reserved.
3
4#pragma once
5
6#include "TTauri/GUI/GUIDevice_base.hpp"
7#include "TTauri/GUI/PipelineFlat_DeviceShared.hpp"
8#include "TTauri/GUI/PipelineImage_DeviceShared.hpp"
9#include "TTauri/GUI/PipelineBox_DeviceShared.hpp"
10#include "TTauri/GUI/PipelineSDF_DeviceShared.hpp"
11#include "TTauri/GUI/PipelineToneMapper_DeviceShared.hpp"
12#include "TTauri/GUI/globals.hpp"
13#include <vulkan/vulkan.hpp>
14#include <vma/vk_mem_alloc.h>
15
16namespace tt {
17class URL;
18}
19
20namespace tt {
21
22class GUIDevice_vulkan final : public GUIDevice_base {
23protected:
24 vk::PhysicalDevice physicalIntrinsic;
25 vk::Device intrinsic;
26 VmaAllocator allocator;
27
28private:
29 void initializeQuadIndexBuffer();
30 void destroyQuadIndexBuffer();
31
32public:
33 vk::PhysicalDeviceType deviceType = vk::PhysicalDeviceType::eOther;
34 vk::PhysicalDeviceProperties physicalProperties;
35
36 uint32_t graphicsQueueFamilyIndex = 0;
37 uint32_t presentQueueFamilyIndex = 0;
38 uint32_t computeQueueFamilyIndex = 0;
39 uint32_t graphicsQueueIndex = 0;
40 uint32_t presentQueueIndex = 0;
41 uint32_t computeQueueIndex = 0;
42 vk::Queue graphicsQueue;
43 vk::Queue presentQueue;
44 vk::Queue computeQueue;
45 vk::CommandPool graphicsCommandPool;
46 vk::CommandPool presentCommandPool;
47 vk::CommandPool computeCommandPool;
48
59 vk::Buffer quadIndexBuffer;
60 VmaAllocation quadIndexBufferAllocation = {};
61
67
71
72 bool supportsLazyTransientImages = false;
73 vk::ImageUsageFlags transientImageUsageFlags = vk::ImageUsageFlags{};
74 VmaMemoryUsage lazyMemoryUsage = VMA_MEMORY_USAGE_GPU_ONLY;
75
80
84 mutable vk::SurfaceFormatKHR bestSurfaceFormat = {};
85
89 mutable vk::PresentModeKHR bestSurfacePresentMode = vk::PresentModeKHR::eFifo;
90
91 GUIDevice_vulkan(vk::PhysicalDevice physicalDevice);
93
94 GUIDevice_vulkan(const GUIDevice_vulkan &) = delete;
95 GUIDevice_vulkan &operator=(const GUIDevice_vulkan &) = delete;
97 GUIDevice_vulkan &operator=(GUIDevice_vulkan &&) = delete;
98
99 void initializeDevice(Window const &window) override;
100
101 int score(vk::SurfaceKHR surface) const;
102
103 int score(Window const &window) const override;
104
113
114 std::pair<vk::Buffer, VmaAllocation> createBuffer(const vk::BufferCreateInfo &bufferCreateInfo, const VmaAllocationCreateInfo &allocationCreateInfo) const;
115
116 void destroyBuffer(const vk::Buffer &buffer, const VmaAllocation &allocation) const;
117
118 std::pair<vk::Image, VmaAllocation> createImage(const vk::ImageCreateInfo &imageCreateInfo, const VmaAllocationCreateInfo &allocationCreateInfo) const;
119 void destroyImage(const vk::Image &image, const VmaAllocation &allocation) const;
120
121 vk::CommandBuffer beginSingleTimeCommands() const;
122 void endSingleTimeCommands(vk::CommandBuffer commandBuffer) const;
123
124 void transitionLayout(vk::Image image, vk::Format format, vk::ImageLayout srcLayout, vk::ImageLayout dstLayout) const;
125 void copyImage(vk::Image srcImage, vk::ImageLayout srcLayout, vk::Image dstImage, vk::ImageLayout dstLayout, vk::ArrayProxy<vk::ImageCopy const> regions) const;
126 void clearColorImage(vk::Image image, vk::ImageLayout layout, vk::ClearColorValue const &color, vk::ArrayProxy<const vk::ImageSubresourceRange> ranges) const;
127
128 template <typename T>
129 nonstd::span<T> mapMemory(const VmaAllocation &allocation) const {
130 auto lock = std::scoped_lock(guiMutex);
131
132 void *mapping;
133 ttlet result = static_cast<vk::Result>(vmaMapMemory(allocator, allocation, &mapping));
134
135 VmaAllocationInfo allocationInfo;
136 vmaGetAllocationInfo(allocator, allocation, &allocationInfo);
137
138 // Should we launder the pointer? The GPU has created the objects, not the C++ application.
139 T *mappingT = reinterpret_cast<T *>(mapping);
140 ttlet mappingSpan = nonstd::span<T>(mappingT, allocationInfo.size / sizeof (T));
141
142 return vk::createResultValue(result, mappingSpan, "tt::GUIDevice_vulkan::mapMemory");
143 }
144
145 void unmapMemory(const VmaAllocation &allocation) const;
146
147 void flushAllocation(const VmaAllocation &allocation, VkDeviceSize offset, VkDeviceSize size) const {
148 auto lock = std::scoped_lock(guiMutex);
149
150 ttlet alignment = physicalProperties.limits.nonCoherentAtomSize;
151
152 ttlet alignedOffset = (offset / alignment) * alignment;
153 ttlet adjustedSize = size + (offset - alignedOffset);
154 ttlet alignedSize = ((adjustedSize + (alignment - 1)) / alignment) * alignment;
155
156 vmaFlushAllocation(allocator, allocation, alignedOffset, alignedSize);
157 }
158
159 vk::ShaderModule loadShader(uint32_t const *data, size_t size) const;
160
161 vk::ShaderModule loadShader(nonstd::span<std::byte const> shaderObjectBytes) const;
162
163 vk::ShaderModule loadShader(URL const &shaderObjectLocation) const;
164
165
166 void waitIdle() const {
167 auto lock = std::scoped_lock(guiMutex);
168 return intrinsic.waitIdle();
169 }
170
171 vk::Result waitForFences(vk::ArrayProxy<const vk::Fence> fences, vk::Bool32 waitAll, uint64_t timeout) const {
172 auto lock = std::scoped_lock(guiMutex);
173 return intrinsic.waitForFences(fences, waitAll, timeout);
174 }
175
176 vk::Result acquireNextImageKHR(vk::SwapchainKHR swapchain, uint64_t timeout, vk::Semaphore semaphore, vk::Fence fence, uint32_t* pImageIndex) const {
177 auto lock = std::scoped_lock(guiMutex);
178 return intrinsic.acquireNextImageKHR(swapchain, timeout, semaphore, fence, pImageIndex);
179 }
180
181 void resetFences(vk::ArrayProxy<const vk::Fence> fences) const {
182 auto lock = std::scoped_lock(guiMutex);
183 return intrinsic.resetFences(fences);
184 }
185
186 vk::Result createSwapchainKHR(const vk::SwapchainCreateInfoKHR* pCreateInfo, const vk::AllocationCallbacks* pAllocator, vk::SwapchainKHR* pSwapchain) const {
187 auto lock = std::scoped_lock(guiMutex);
188 return intrinsic.createSwapchainKHR(pCreateInfo, pAllocator, pSwapchain);
189 }
190
191 std::vector<vk::Image> getSwapchainImagesKHR(vk::SwapchainKHR swapchain) const {
192 auto lock = std::scoped_lock(guiMutex);
193 return intrinsic.getSwapchainImagesKHR(swapchain);
194 }
195
196 vk::ImageView createImageView(const vk::ImageViewCreateInfo& createInfo) const {
197 auto lock = std::scoped_lock(guiMutex);
198 return intrinsic.createImageView(createInfo);
199 }
200
201 vk::Framebuffer createFramebuffer(const vk::FramebufferCreateInfo& createInfo) const {
202 auto lock = std::scoped_lock(guiMutex);
203 return intrinsic.createFramebuffer(createInfo);
204 }
205
206 vk::RenderPass createRenderPass(const vk::RenderPassCreateInfo& createInfo) const {
207 auto lock = std::scoped_lock(guiMutex);
208 return intrinsic.createRenderPass(createInfo);
209 }
210
211 vk::Semaphore createSemaphore(const vk::SemaphoreCreateInfo& createInfo) const {
212 auto lock = std::scoped_lock(guiMutex);
213 return intrinsic.createSemaphore(createInfo);
214 }
215
216 vk::Fence createFence(const vk::FenceCreateInfo& createInfo) const {
217 auto lock = std::scoped_lock(guiMutex);
218 return intrinsic.createFence(createInfo);
219 }
220
221 vk::DescriptorSetLayout createDescriptorSetLayout(const vk::DescriptorSetLayoutCreateInfo& createInfo) const {
222 auto lock = std::scoped_lock(guiMutex);
223 return intrinsic.createDescriptorSetLayout(createInfo);
224 }
225
226 vk::DescriptorPool createDescriptorPool(const vk::DescriptorPoolCreateInfo& createInfo) const {
227 auto lock = std::scoped_lock(guiMutex);
228 return intrinsic.createDescriptorPool(createInfo);
229 }
230
231 vk::PipelineLayout createPipelineLayout(const vk::PipelineLayoutCreateInfo& createInfo) const {
232 auto lock = std::scoped_lock(guiMutex);
233 return intrinsic.createPipelineLayout(createInfo);
234 }
235
236 vk::Pipeline createGraphicsPipeline(vk::PipelineCache pipelineCache, const vk::GraphicsPipelineCreateInfo& createInfo) const {
237 auto lock = std::scoped_lock(guiMutex);
238 return intrinsic.createGraphicsPipeline(pipelineCache, createInfo);
239 }
240
241 vk::Sampler createSampler(const vk::SamplerCreateInfo& createInfo) const {
242 auto lock = std::scoped_lock(guiMutex);
243 return intrinsic.createSampler(createInfo);
244 }
245
246 std::vector<vk::DescriptorSet> allocateDescriptorSets(const vk::DescriptorSetAllocateInfo& allocateInfo) const {
247 auto lock = std::scoped_lock(guiMutex);
248 return intrinsic.allocateDescriptorSets(allocateInfo);
249 }
250
251 std::vector<vk::CommandBuffer> allocateCommandBuffers(const vk::CommandBufferAllocateInfo& allocateInfo) const {
252 auto lock = std::scoped_lock(guiMutex);
253 return intrinsic.allocateCommandBuffers(allocateInfo);
254 }
255
256 void updateDescriptorSets(vk::ArrayProxy<const vk::WriteDescriptorSet> descriptorWrites, vk::ArrayProxy<const vk::CopyDescriptorSet> descriptorCopies) const {
257 auto lock = std::scoped_lock(guiMutex);
258 return intrinsic.updateDescriptorSets(descriptorWrites, descriptorCopies);
259 }
260
261 void freeCommandBuffers(vk::CommandPool commandPool, vk::ArrayProxy<const vk::CommandBuffer> commandBuffers) const {
262 auto lock = std::scoped_lock(guiMutex);
263 return intrinsic.freeCommandBuffers(commandPool, commandBuffers);
264 }
265
266 template<typename T>
267 void destroy(T x) const {
268 auto lock = std::scoped_lock(guiMutex);
269 intrinsic.destroy(x);
270 }
271
272 vk::SurfaceCapabilitiesKHR getSurfaceCapabilitiesKHR(vk::SurfaceKHR surface) const {
273 auto lock = std::scoped_lock(guiMutex);
274 return physicalIntrinsic.getSurfaceCapabilitiesKHR(surface);
275 }
276
277
278};
279
280}
Definition GUIDevice_base.hpp:19
Definition GUIDevice_vulkan.hpp:22
vk::Buffer quadIndexBuffer
Shared index buffer containing indices for drawing quads.
Definition GUIDevice_vulkan.hpp:59
std::vector< const char * > requiredExtensions
Definition GUIDevice_vulkan.hpp:70
void initializeDevice(Window const &window) override
int score(Window const &window) const override
vk::PresentModeKHR bestSurfacePresentMode
Definition GUIDevice_vulkan.hpp:89
vk::SurfaceFormatKHR bestSurfaceFormat
Definition GUIDevice_vulkan.hpp:84
std::vector< std::pair< uint32_t, uint8_t > > findBestQueueFamilyIndices(vk::SurfaceKHR surface) const
std::vector< std::pair< uint32_t, uint8_t > > queueFamilyIndicesAndCapabilities
Definition GUIDevice_vulkan.hpp:79
Definition Window_vulkan_win32.hpp:15
T lock(T... args)