Monado OpenXR Runtime
vk_helpers.h
Go to the documentation of this file.
1 // Copyright 2019-2020, Collabora, Ltd.
2 // SPDX-License-Identifier: BSL-1.0
3 /*!
4  * @file
5  * @brief Common Vulkan code header.
6  * @author Jakob Bornecrantz <jakob@collabora.com>
7  * @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
8  * @ingroup aux_vk
9  */
10 
11 #pragma once
12 
13 #include "xrt/xrt_compositor.h"
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
20 
21 /*
22  *
23  * Structs
24  *
25  */
26 
27 /*!
28  * A bundle of Vulkan functions and objects, used by both @ref comp and @ref
29  * comp_client. Note that they both have different instances of the object and
30  * as such VkInstance and so on.
31  *
32  * @ingroup aux_vk
33  */
34 struct vk_bundle
35 {
36  bool print;
37 
38  VkInstance instance;
39  VkPhysicalDevice physical_device;
40  VkDevice device;
41  uint32_t queue_family_index;
42  uint32_t queue_index;
43 
44  VkDebugReportCallbackEXT debug_report_cb;
45 
46  VkPhysicalDeviceMemoryProperties device_memory_props;
47 
48  VkCommandPool cmd_pool;
49 
50  // clang-format off
51  // Loader functions
52  PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
53  PFN_vkCreateInstance vkCreateInstance;
54 
55  // Instance functions.
56  PFN_vkDestroyInstance vkDestroyInstance;
57  PFN_vkCreateDevice vkCreateDevice;
58  PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
59  PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
60  PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
61  PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
62 
63 #ifdef VK_USE_PLATFORM_XCB_KHR
64  PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR;
65 #endif
66 
67 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
68  PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;
69 #endif
70 
71 #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
72  PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR;
73  PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR;
74 
75  // This doesn't strictly require VK_USE_PLATFORM_XLIB_XRANDR_EXT,
76  // but it's only used in the NVIDIA X direct mode path that does require it.
77  PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR;
78  PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR;
79  PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR;
80  PFN_vkAcquireXlibDisplayEXT vkAcquireXlibDisplayEXT;
81  PFN_vkReleaseDisplayEXT vkReleaseDisplayEXT;
82  PFN_vkGetRandROutputDisplayEXT vkGetRandROutputDisplayEXT;
83 #endif
84 
85 
86  // Physical device functions.
87  PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties;
88  PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties;
89  PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
90 
91  PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
92  PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
93  PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
94  PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
95 
96 
97  // Device functions.
98  PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
99  PFN_vkDestroyDevice vkDestroyDevice;
100  PFN_vkDeviceWaitIdle vkDeviceWaitIdle;
101 
102  PFN_vkAllocateMemory vkAllocateMemory;
103  PFN_vkFreeMemory vkFreeMemory;
104  PFN_vkMapMemory vkMapMemory;
105  PFN_vkUnmapMemory vkUnmapMemory;
106  PFN_vkGetMemoryFdKHR vkGetMemoryFdKHR;
107 
108  PFN_vkCreateBuffer vkCreateBuffer;
109  PFN_vkDestroyBuffer vkDestroyBuffer;
110  PFN_vkBindBufferMemory vkBindBufferMemory;
111  PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements;
112 
113  PFN_vkCreateImage vkCreateImage;
114  PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements;
115  PFN_vkBindImageMemory vkBindImageMemory;
116  PFN_vkDestroyImage vkDestroyImage;
117  PFN_vkCreateImageView vkCreateImageView;
118  PFN_vkDestroyImageView vkDestroyImageView;
119 
120  PFN_vkCreateSampler vkCreateSampler;
121  PFN_vkDestroySampler vkDestroySampler;
122 
123  PFN_vkCreateShaderModule vkCreateShaderModule;
124  PFN_vkDestroyShaderModule vkDestroyShaderModule;
125 
126  PFN_vkCreateCommandPool vkCreateCommandPool;
127  PFN_vkDestroyCommandPool vkDestroyCommandPool;
128  PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers;
129  PFN_vkBeginCommandBuffer vkBeginCommandBuffer;
130  PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier;
131  PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass;
132  PFN_vkCmdSetScissor vkCmdSetScissor;
133  PFN_vkCmdSetViewport vkCmdSetViewport;
134  PFN_vkCmdClearColorImage vkCmdClearColorImage;
135  PFN_vkCmdEndRenderPass vkCmdEndRenderPass;
136  PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets;
137  PFN_vkCmdBindPipeline vkCmdBindPipeline;
138  PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers;
139  PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer;
140  PFN_vkCmdDraw vkCmdDraw;
141  PFN_vkCmdDrawIndexed vkCmdDrawIndexed;
142  PFN_vkEndCommandBuffer vkEndCommandBuffer;
143  PFN_vkFreeCommandBuffers vkFreeCommandBuffers;
144 
145  PFN_vkCreateRenderPass vkCreateRenderPass;
146  PFN_vkDestroyRenderPass vkDestroyRenderPass;
147  PFN_vkCreateFramebuffer vkCreateFramebuffer;
148  PFN_vkDestroyFramebuffer vkDestroyFramebuffer;
149  PFN_vkCreatePipelineCache vkCreatePipelineCache;
150  PFN_vkDestroyPipelineCache vkDestroyPipelineCache;
151  PFN_vkCreateDescriptorPool vkCreateDescriptorPool;
152  PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool;
153  PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets;
154  PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines;
155  PFN_vkDestroyPipeline vkDestroyPipeline;
156  PFN_vkCreatePipelineLayout vkCreatePipelineLayout;
157  PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout;
158  PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout;
159  PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets;
160  PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout;
161 
162  PFN_vkGetDeviceQueue vkGetDeviceQueue;
163  PFN_vkQueueSubmit vkQueueSubmit;
164  PFN_vkQueueWaitIdle vkQueueWaitIdle;
165 
166  PFN_vkCreateSemaphore vkCreateSemaphore;
167  PFN_vkDestroySemaphore vkDestroySemaphore;
168 
169  PFN_vkCreateFence vkCreateFence;
170  PFN_vkWaitForFences vkWaitForFences;
171  PFN_vkDestroyFence vkDestroyFence;
172 
173  PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR;
174  PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
175  PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
176  PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
177  PFN_vkQueuePresentKHR vkQueuePresentKHR;
178  // clang-format on
179 };
180 
181 
182 /*
183  *
184  * String helper functions.
185  *
186  */
187 
188 const char *
189 vk_result_string(VkResult code);
190 
191 const char *
192 vk_color_format_string(VkFormat code);
193 
194 const char *
195 vk_present_mode_string(VkPresentModeKHR code);
196 
197 const char *
198 vk_power_state_string(VkDisplayPowerStateEXT code);
199 
200 const char *
201 vk_color_space_string(VkColorSpaceKHR code);
202 
203 
204 /*
205  *
206  * Function and helpers.
207  *
208  */
209 
210 #define VK_DEBUG(vk, ...) \
211  do { \
212  if (vk->print) { \
213  fprintf(stderr, "%s - ", __func__); \
214  fprintf(stderr, __VA_ARGS__); \
215  fprintf(stderr, "\n"); \
216  } \
217  } while (false)
218 
219 #define VK_ERROR(vk, ...) \
220  do { \
221  fprintf(stderr, "%s - ", __func__); \
222  fprintf(stderr, __VA_ARGS__); \
223  fprintf(stderr, "\n"); \
224  } while (false)
225 
226 /*!
227  * @ingroup aux_vk
228  */
229 void
230 vk_init_validation_callback(struct vk_bundle *vk);
231 
232 /*!
233  * @ingroup aux_vk
234  */
235 void
236 vk_destroy_validation_callback(struct vk_bundle *vk);
237 
238 /*!
239  * @ingroup aux_vk
240  */
241 VkResult
242 vk_get_loader_functions(struct vk_bundle *vk, PFN_vkGetInstanceProcAddr g);
243 
244 /*!
245  * @ingroup aux_vk
246  */
247 VkResult
248 vk_get_instance_functions(struct vk_bundle *vk);
249 
250 /*!
251  * @ingroup aux_vk
252  */
253 VkResult
254 vk_init_cmd_pool(struct vk_bundle *vk);
255 
256 /*!
257  * @ingroup aux_vk
258  */
259 VkResult
260 vk_create_device(struct vk_bundle *vk, int forced_index);
261 
262 /*!
263  * Initialize a bundle with objects given to us by client code,
264  * used by @ref client_vk_compositor in @ref comp_client.
265  *
266  * @ingroup aux_vk
267  */
268 VkResult
269 vk_init_from_given(struct vk_bundle *vk,
270  PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr,
271  VkInstance instance,
272  VkPhysicalDevice physical_device,
273  VkDevice device,
274  uint32_t queue_family_index,
275  uint32_t queue_index);
276 
277 /*!
278  * @ingroup aux_vk
279  */
280 bool
281 vk_get_memory_type(struct vk_bundle *vk,
282  uint32_t type_bits,
283  VkMemoryPropertyFlags memory_props,
284  uint32_t *out_type_id);
285 
286 /*!
287  * Allocate memory for an image and bind it to that image.
288  *
289  * Handles the following steps:
290  *
291  * - calling vkGetImageMemoryRequirements
292  * - comparing against the max_size
293  * - getting the memory type (as dictated by the VkMemoryRequirements and
294  * VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
295  * - calling vkAllocateMemory
296  * - calling vkBindImageMemory
297  * - calling vkDestroyMemory in case of an error.
298  *
299  * If this fails, it cleans up the VkDeviceMemory.
300  *
301  * @param vk Vulkan bundle
302  * @param image The VkImage to allocate for and bind.
303  * @param max_size The maximum value you'll allow for
304  * VkMemoryRequirements::size. Pass SIZE_MAX if you will accept any size
305  * that works.
306  * @param pNext_for_allocate (Optional) a pointer to use in the pNext chain of
307  * VkMemoryAllocateInfo.
308  * @param out_mem Output parameter: will be set to the allocated memory if
309  * everything succeeds. Not modified if there is an error.
310  * @param out_size (Optional) pointer to receive the value of
311  * VkMemoryRequirements::size.
312  *
313  * If this fails, you may want to destroy your VkImage as well, since this
314  * routine is usually used in combination with vkCreateImage.
315  *
316  * @ingroup aux_vk
317  */
318 VkResult
320  VkImage image,
321  size_t max_size,
322  const void *pNext_for_allocate,
323  VkDeviceMemory *out_mem,
324  VkDeviceSize *out_size);
325 
326 /*!
327  * @ingroup aux_vk
328  */
329 VkResult
330 vk_create_image_from_fd(struct vk_bundle *vk,
331  enum xrt_swapchain_usage_bits swapchain_usage,
332  int64_t format,
333  uint32_t width,
334  uint32_t height,
335  uint32_t array_size,
336  uint32_t mip_count,
337  struct xrt_image_fd *image_fd,
338  VkImage *out_image,
339  VkDeviceMemory *out_mem);
340 
341 /*!
342  * @ingroup aux_vk
343  */
344 VkResult
345 vk_create_image_simple(struct vk_bundle *vk,
346  uint32_t width,
347  uint32_t height,
348  VkFormat format,
349  VkDeviceMemory *out_mem,
350  VkImage *out_image);
351 
352 /*!
353  * @ingroup aux_vk
354  */
355 VkResult
356 vk_create_sampler(struct vk_bundle *vk, VkSampler *out_sampler);
357 
358 /*!
359  * @ingroup aux_vk
360  */
361 VkResult
362 vk_create_view(struct vk_bundle *vk,
363  VkImage image,
364  VkFormat format,
365  VkImageSubresourceRange subresource_range,
366  VkImageView *out_view);
367 
368 /*!
369  * @ingroup aux_vk
370  */
371 VkResult
372 vk_init_cmd_buffer(struct vk_bundle *vk, VkCommandBuffer *out_cmd_buffer);
373 
374 /*!
375  * @ingroup aux_vk
376  */
377 VkResult
378 vk_set_image_layout(struct vk_bundle *vk,
379  VkCommandBuffer cmd_buffer,
380  VkImage image,
381  VkAccessFlags src_access_mask,
382  VkAccessFlags dst_access_mask,
383  VkImageLayout old_layout,
384  VkImageLayout new_layout,
385  VkImageSubresourceRange subresource_range);
386 
387 /*!
388  * @ingroup aux_vk
389  */
390 VkResult
391 vk_submit_cmd_buffer(struct vk_bundle *vk, VkCommandBuffer cmd_buffer);
392 
393 
394 #ifdef __cplusplus
395 }
396 #endif
Include all of the Vulkan headers in one place.
xrt_swapchain_usage_bits
Usage of the swapchain images.
Definition: xrt_compositor.h:48
Header defining a XRT graphics provider.
VkResult vk_alloc_and_bind_image_memory(struct vk_bundle *vk, VkImage image, size_t max_size, const void *pNext_for_allocate, VkDeviceMemory *out_mem, VkDeviceSize *out_size)
Allocate memory for an image and bind it to that image.
Definition: vk_helpers.c:150
VkResult vk_create_device(struct vk_bundle *vk, int forced_index)
Definition: vk_helpers.c:948
VkResult vk_init_from_given(struct vk_bundle *vk, PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr, VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, uint32_t queue_family_index, uint32_t queue_index)
Initialize a bundle with objects given to us by client code, used by client_vk_compositor in Composit...
Definition: vk_helpers.c:1023
A bundle of Vulkan functions and objects, used by both Compositor and Compositor client code...
Definition: vk_helpers.h:34
A single image of a fd based swapchain.
Definition: xrt_compositor.h:450