1/**************************************************************************/
2/* openxr_vulkan_extension.cpp */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#include "openxr_vulkan_extension.h"
32
33#include "../openxr_util.h"
34
35#include "core/string/print_string.h"
36#include "servers/rendering/renderer_rd/effects/copy_effects.h"
37#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
38#include "servers/rendering/rendering_server_globals.h"
39#include "servers/rendering_server.h"
40
41OpenXRVulkanExtension::OpenXRVulkanExtension() {
42 VulkanContext::set_vulkan_hooks(this);
43}
44
45OpenXRVulkanExtension::~OpenXRVulkanExtension() {
46 VulkanContext::set_vulkan_hooks(nullptr);
47}
48
49HashMap<String, bool *> OpenXRVulkanExtension::get_requested_extensions() {
50 HashMap<String, bool *> request_extensions;
51
52 request_extensions[XR_KHR_VULKAN_ENABLE2_EXTENSION_NAME] = nullptr; // must be available
53
54 return request_extensions;
55}
56
57void OpenXRVulkanExtension::on_instance_created(const XrInstance p_instance) {
58 ERR_FAIL_NULL(OpenXRAPI::get_singleton());
59
60 // Obtain pointers to functions we're accessing here, they are (not yet) part of core.
61
62 EXT_INIT_XR_FUNC(xrGetVulkanGraphicsRequirements2KHR);
63 EXT_INIT_XR_FUNC(xrCreateVulkanInstanceKHR);
64 EXT_INIT_XR_FUNC(xrGetVulkanGraphicsDevice2KHR);
65 EXT_INIT_XR_FUNC(xrCreateVulkanDeviceKHR);
66 EXT_INIT_XR_FUNC(xrEnumerateSwapchainImages);
67}
68
69bool OpenXRVulkanExtension::check_graphics_api_support(XrVersion p_desired_version) {
70 ERR_FAIL_NULL_V(OpenXRAPI::get_singleton(), false);
71
72 XrGraphicsRequirementsVulkan2KHR vulkan_requirements = {
73 XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN2_KHR, // type
74 nullptr, // next
75 0, // minApiVersionSupported
76 0 // maxApiVersionSupported
77 };
78
79 XrResult result = xrGetVulkanGraphicsRequirements2KHR(OpenXRAPI::get_singleton()->get_instance(), OpenXRAPI::get_singleton()->get_system_id(), &vulkan_requirements);
80 if (XR_FAILED(result)) {
81 print_line("OpenXR: Failed to get vulkan graphics requirements [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
82 return false;
83 }
84
85 // #ifdef DEBUG
86 print_line("OpenXR: XrGraphicsRequirementsVulkan2KHR:");
87 print_line(" - minApiVersionSupported: ", OpenXRUtil::make_xr_version_string(vulkan_requirements.minApiVersionSupported));
88 print_line(" - maxApiVersionSupported: ", OpenXRUtil::make_xr_version_string(vulkan_requirements.maxApiVersionSupported));
89 // #endif
90
91 if (p_desired_version < vulkan_requirements.minApiVersionSupported) {
92 print_line("OpenXR: Requested Vulkan version does not meet the minimum version this runtime supports.");
93 print_line("- desired_version ", OpenXRUtil::make_xr_version_string(p_desired_version));
94 print_line("- minApiVersionSupported ", OpenXRUtil::make_xr_version_string(vulkan_requirements.minApiVersionSupported));
95 print_line("- maxApiVersionSupported ", OpenXRUtil::make_xr_version_string(vulkan_requirements.maxApiVersionSupported));
96 return false;
97 }
98
99 if (p_desired_version > vulkan_requirements.maxApiVersionSupported) {
100 print_line("OpenXR: Requested Vulkan version exceeds the maximum version this runtime has been tested on and is known to support.");
101 print_line("- desired_version ", OpenXRUtil::make_xr_version_string(p_desired_version));
102 print_line("- minApiVersionSupported ", OpenXRUtil::make_xr_version_string(vulkan_requirements.minApiVersionSupported));
103 print_line("- maxApiVersionSupported ", OpenXRUtil::make_xr_version_string(vulkan_requirements.maxApiVersionSupported));
104 }
105
106 return true;
107}
108
109bool OpenXRVulkanExtension::create_vulkan_instance(const VkInstanceCreateInfo *p_vulkan_create_info, VkInstance *r_instance) {
110 // get the vulkan version we are creating
111 uint32_t vulkan_version = p_vulkan_create_info->pApplicationInfo->apiVersion;
112 uint32_t major_version = VK_VERSION_MAJOR(vulkan_version);
113 uint32_t minor_version = VK_VERSION_MINOR(vulkan_version);
114 uint32_t patch_version = VK_VERSION_PATCH(vulkan_version);
115 XrVersion desired_version = XR_MAKE_VERSION(major_version, minor_version, patch_version);
116
117 // check if this is supported
118 if (!check_graphics_api_support(desired_version)) {
119 return false;
120 }
121
122 XrVulkanInstanceCreateInfoKHR xr_vulkan_instance_info = {
123 XR_TYPE_VULKAN_INSTANCE_CREATE_INFO_KHR, // type
124 nullptr, // next
125 OpenXRAPI::get_singleton()->get_system_id(), // systemId
126 0, // createFlags
127 vkGetInstanceProcAddr, // pfnGetInstanceProcAddr
128 p_vulkan_create_info, // vulkanCreateInfo
129 nullptr, // vulkanAllocator
130 };
131
132 VkResult vk_result = VK_SUCCESS;
133 XrResult result = xrCreateVulkanInstanceKHR(OpenXRAPI::get_singleton()->get_instance(), &xr_vulkan_instance_info, &vulkan_instance, &vk_result);
134 if (XR_FAILED(result)) {
135 print_line("OpenXR: Failed to create vulkan instance [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
136 return false;
137 }
138
139 ERR_FAIL_COND_V_MSG(vk_result == VK_ERROR_INCOMPATIBLE_DRIVER, false,
140 "Cannot find a compatible Vulkan installable client driver (ICD).\n\n"
141 "vkCreateInstance Failure");
142 ERR_FAIL_COND_V_MSG(vk_result == VK_ERROR_EXTENSION_NOT_PRESENT, false,
143 "Cannot find a specified extension library.\n"
144 "Make sure your layers path is set appropriately.\n"
145 "vkCreateInstance Failure");
146 ERR_FAIL_COND_V_MSG(vk_result, false,
147 "vkCreateInstance failed.\n\n"
148 "Do you have a compatible Vulkan installable client driver (ICD) installed?\n"
149 "Please look at the Getting Started guide for additional information.\n"
150 "vkCreateInstance Failure");
151
152 *r_instance = vulkan_instance;
153
154 return true;
155}
156
157bool OpenXRVulkanExtension::get_physical_device(VkPhysicalDevice *r_device) {
158 ERR_FAIL_NULL_V(OpenXRAPI::get_singleton(), false);
159
160 XrVulkanGraphicsDeviceGetInfoKHR get_info = {
161 XR_TYPE_VULKAN_GRAPHICS_DEVICE_GET_INFO_KHR, // type
162 nullptr, // next
163 OpenXRAPI::get_singleton()->get_system_id(), // systemId
164 vulkan_instance, // vulkanInstance
165 };
166
167 XrResult result = xrGetVulkanGraphicsDevice2KHR(OpenXRAPI::get_singleton()->get_instance(), &get_info, &vulkan_physical_device);
168 if (XR_FAILED(result)) {
169 print_line("OpenXR: Failed to obtain vulkan physical device [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
170 return false;
171 }
172
173 *r_device = vulkan_physical_device;
174
175 return true;
176}
177
178bool OpenXRVulkanExtension::create_vulkan_device(const VkDeviceCreateInfo *p_device_create_info, VkDevice *r_device) {
179 ERR_FAIL_NULL_V(OpenXRAPI::get_singleton(), false);
180
181 // the first entry in our queue list should be the one we need to remember...
182 vulkan_queue_family_index = p_device_create_info->pQueueCreateInfos[0].queueFamilyIndex;
183 vulkan_queue_index = 0; // ??
184
185 XrVulkanDeviceCreateInfoKHR create_info = {
186 XR_TYPE_VULKAN_DEVICE_CREATE_INFO_KHR, // type
187 nullptr, // next
188 OpenXRAPI::get_singleton()->get_system_id(), // systemId
189 0, // createFlags
190 vkGetInstanceProcAddr, // pfnGetInstanceProcAddr
191 vulkan_physical_device, // vulkanPhysicalDevice
192 p_device_create_info, // vulkanCreateInfo
193 nullptr // vulkanAllocator
194 };
195
196 VkResult vk_result = VK_SUCCESS;
197 XrResult result = xrCreateVulkanDeviceKHR(OpenXRAPI::get_singleton()->get_instance(), &create_info, &vulkan_device, &vk_result);
198 if (XR_FAILED(result)) {
199 print_line("OpenXR: Failed to create vulkan device [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
200 return false;
201 }
202
203 if (vk_result != VK_SUCCESS) {
204 print_line("OpenXR: Failed to create vulkan device [vulkan error", vk_result, "]");
205 }
206
207 *r_device = vulkan_device;
208
209 return true;
210}
211
212XrGraphicsBindingVulkanKHR OpenXRVulkanExtension::graphics_binding_vulkan;
213
214void *OpenXRVulkanExtension::set_session_create_and_get_next_pointer(void *p_next_pointer) {
215 graphics_binding_vulkan.type = XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR;
216 graphics_binding_vulkan.next = p_next_pointer;
217 graphics_binding_vulkan.instance = vulkan_instance;
218 graphics_binding_vulkan.physicalDevice = vulkan_physical_device;
219 graphics_binding_vulkan.device = vulkan_device;
220 graphics_binding_vulkan.queueFamilyIndex = vulkan_queue_family_index;
221 graphics_binding_vulkan.queueIndex = vulkan_queue_index;
222
223 return &graphics_binding_vulkan;
224}
225
226void OpenXRVulkanExtension::get_usable_swapchain_formats(Vector<int64_t> &p_usable_swap_chains) {
227 // We might want to do more here especially if we keep things in linear color space
228 // Possibly add in R10G10B10A2 as an option if we're using the mobile renderer.
229 p_usable_swap_chains.push_back(VK_FORMAT_R8G8B8A8_SRGB);
230 p_usable_swap_chains.push_back(VK_FORMAT_B8G8R8A8_SRGB);
231 p_usable_swap_chains.push_back(VK_FORMAT_R8G8B8A8_UINT);
232 p_usable_swap_chains.push_back(VK_FORMAT_B8G8R8A8_UINT);
233}
234
235void OpenXRVulkanExtension::get_usable_depth_formats(Vector<int64_t> &p_usable_swap_chains) {
236 p_usable_swap_chains.push_back(VK_FORMAT_D24_UNORM_S8_UINT);
237 p_usable_swap_chains.push_back(VK_FORMAT_D32_SFLOAT_S8_UINT);
238 p_usable_swap_chains.push_back(VK_FORMAT_D32_SFLOAT);
239}
240
241bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) {
242 XrSwapchainImageVulkanKHR *images = nullptr;
243
244 RenderingServer *rendering_server = RenderingServer::get_singleton();
245 ERR_FAIL_NULL_V(rendering_server, false);
246 RenderingDevice *rendering_device = rendering_server->get_rendering_device();
247 ERR_FAIL_NULL_V(rendering_device, false);
248
249 uint32_t swapchain_length;
250 XrResult result = xrEnumerateSwapchainImages(p_swapchain, 0, &swapchain_length, nullptr);
251 if (XR_FAILED(result)) {
252 print_line("OpenXR: Failed to get swapchaim image count [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
253 return false;
254 }
255
256 images = (XrSwapchainImageVulkanKHR *)memalloc(sizeof(XrSwapchainImageVulkanKHR) * swapchain_length);
257 ERR_FAIL_NULL_V_MSG(images, false, "OpenXR Couldn't allocate memory for swap chain image");
258
259 for (uint64_t i = 0; i < swapchain_length; i++) {
260 images[i].type = XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR;
261 images[i].next = nullptr;
262 images[i].image = VK_NULL_HANDLE;
263 }
264
265 result = xrEnumerateSwapchainImages(p_swapchain, swapchain_length, &swapchain_length, (XrSwapchainImageBaseHeader *)images);
266 if (XR_FAILED(result)) {
267 print_line("OpenXR: Failed to get swapchaim images [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
268 memfree(images);
269 return false;
270 }
271
272 // SwapchainGraphicsData *data = (SwapchainGraphicsData *)memalloc(sizeof(SwapchainGraphicsData));
273 SwapchainGraphicsData *data = memnew(SwapchainGraphicsData);
274 if (data == nullptr) {
275 print_line("OpenXR: Failed to allocate memory for swapchain data");
276 memfree(images);
277 return false;
278 }
279 *r_swapchain_graphics_data = data;
280 data->is_multiview = (p_array_size > 1);
281
282 RenderingDevice::DataFormat format = RenderingDevice::DATA_FORMAT_R8G8B8A8_SRGB;
283 RenderingDevice::TextureSamples samples = RenderingDevice::TEXTURE_SAMPLES_1;
284 uint64_t usage_flags = RenderingDevice::TEXTURE_USAGE_SAMPLING_BIT;
285
286 switch (p_swapchain_format) {
287 case VK_FORMAT_R8G8B8A8_SRGB:
288 // Even though this is an sRGB framebuffer format we're using UNORM here.
289 // The reason here is because Godot does a linear to sRGB conversion while
290 // with the sRGB format, this conversion would be doubled by the hardware.
291 // This also means we're reading the values as is for our preview on screen.
292 // The OpenXR runtime however is still treating this as an sRGB format and
293 // will thus do an sRGB -> Linear conversion as expected.
294 // format = RenderingDevice::DATA_FORMAT_R8G8B8A8_SRGB;
295 format = RenderingDevice::DATA_FORMAT_R8G8B8A8_UNORM;
296 usage_flags |= RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
297 break;
298 case VK_FORMAT_B8G8R8A8_SRGB:
299 // format = RenderingDevice::DATA_FORMAT_B8G8R8A8_SRGB;
300 format = RenderingDevice::DATA_FORMAT_B8G8R8A8_UNORM;
301 usage_flags |= RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
302 break;
303 case VK_FORMAT_R8G8B8A8_UINT:
304 format = RenderingDevice::DATA_FORMAT_R8G8B8A8_UINT;
305 usage_flags |= RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
306 break;
307 case VK_FORMAT_B8G8R8A8_UINT:
308 format = RenderingDevice::DATA_FORMAT_B8G8R8A8_UINT;
309 usage_flags |= RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
310 break;
311 case VK_FORMAT_D32_SFLOAT:
312 format = RenderingDevice::DATA_FORMAT_D32_SFLOAT;
313 usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
314 break;
315 case VK_FORMAT_D24_UNORM_S8_UINT:
316 format = RenderingDevice::DATA_FORMAT_D24_UNORM_S8_UINT;
317 usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
318 break;
319 case VK_FORMAT_D32_SFLOAT_S8_UINT:
320 format = RenderingDevice::DATA_FORMAT_D32_SFLOAT_S8_UINT;
321 usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
322 break;
323 default:
324 // continue with our default value
325 print_line("Unsupported swapchain format ", p_swapchain_format);
326 break;
327 }
328
329 switch (p_sample_count) {
330 case 1:
331 samples = RenderingDevice::TEXTURE_SAMPLES_1;
332 break;
333 case 2:
334 samples = RenderingDevice::TEXTURE_SAMPLES_2;
335 break;
336 case 4:
337 samples = RenderingDevice::TEXTURE_SAMPLES_4;
338 break;
339 case 8:
340 samples = RenderingDevice::TEXTURE_SAMPLES_8;
341 break;
342 case 16:
343 samples = RenderingDevice::TEXTURE_SAMPLES_16;
344 break;
345 case 32:
346 samples = RenderingDevice::TEXTURE_SAMPLES_32;
347 break;
348 case 64:
349 samples = RenderingDevice::TEXTURE_SAMPLES_64;
350 break;
351 default:
352 // continue with our default value
353 print_line("Unsupported sample count ", p_sample_count);
354 break;
355 }
356
357 Vector<RID> texture_rids;
358
359 // create Godot texture objects for each entry in our swapchain
360 for (uint64_t i = 0; i < swapchain_length; i++) {
361 RID image_rid = rendering_device->texture_create_from_extension(
362 p_array_size == 1 ? RenderingDevice::TEXTURE_TYPE_2D : RenderingDevice::TEXTURE_TYPE_2D_ARRAY,
363 format,
364 samples,
365 usage_flags,
366 (uint64_t)images[i].image,
367 p_width,
368 p_height,
369 1,
370 p_array_size);
371
372 texture_rids.push_back(image_rid);
373 }
374
375 data->texture_rids = texture_rids;
376
377 memfree(images);
378
379 return true;
380}
381
382bool OpenXRVulkanExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
383 // Even though this is a Vulkan renderer we're using OpenGL coordinate systems
384 OpenXRUtil::XrMatrix4x4f matrix;
385 OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, OpenXRUtil::GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far);
386
387 for (int j = 0; j < 4; j++) {
388 for (int i = 0; i < 4; i++) {
389 r_camera_matrix.columns[j][i] = matrix.m[j * 4 + i];
390 }
391 }
392
393 return true;
394}
395
396RID OpenXRVulkanExtension::get_texture(void *p_swapchain_graphics_data, int p_image_index) {
397 SwapchainGraphicsData *data = (SwapchainGraphicsData *)p_swapchain_graphics_data;
398 ERR_FAIL_NULL_V(data, RID());
399
400 ERR_FAIL_INDEX_V(p_image_index, data->texture_rids.size(), RID());
401 return data->texture_rids[p_image_index];
402}
403
404void OpenXRVulkanExtension::cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) {
405 if (*p_swapchain_graphics_data == nullptr) {
406 return;
407 }
408
409 SwapchainGraphicsData *data = (SwapchainGraphicsData *)*p_swapchain_graphics_data;
410
411 RenderingServer *rendering_server = RenderingServer::get_singleton();
412 ERR_FAIL_NULL(rendering_server);
413 RenderingDevice *rendering_device = rendering_server->get_rendering_device();
414 ERR_FAIL_NULL(rendering_device);
415
416 for (int i = 0; i < data->texture_rids.size(); i++) {
417 // This should clean up our RIDs and associated texture objects but shouldn't destroy the images, they are owned by our XrSwapchain
418 rendering_device->free(data->texture_rids[i]);
419 }
420 data->texture_rids.clear();
421
422 memdelete(data);
423 *p_swapchain_graphics_data = nullptr;
424}
425
426#define ENUM_TO_STRING_CASE(e) \
427 case e: { \
428 return String(#e); \
429 } break;
430
431String OpenXRVulkanExtension::get_swapchain_format_name(int64_t p_swapchain_format) const {
432 // This really should be in vulkan_context...
433 VkFormat format = VkFormat(p_swapchain_format);
434 switch (format) {
435 ENUM_TO_STRING_CASE(VK_FORMAT_UNDEFINED)
436 ENUM_TO_STRING_CASE(VK_FORMAT_R4G4_UNORM_PACK8)
437 ENUM_TO_STRING_CASE(VK_FORMAT_R4G4B4A4_UNORM_PACK16)
438 ENUM_TO_STRING_CASE(VK_FORMAT_B4G4R4A4_UNORM_PACK16)
439 ENUM_TO_STRING_CASE(VK_FORMAT_R5G6B5_UNORM_PACK16)
440 ENUM_TO_STRING_CASE(VK_FORMAT_B5G6R5_UNORM_PACK16)
441 ENUM_TO_STRING_CASE(VK_FORMAT_R5G5B5A1_UNORM_PACK16)
442 ENUM_TO_STRING_CASE(VK_FORMAT_B5G5R5A1_UNORM_PACK16)
443 ENUM_TO_STRING_CASE(VK_FORMAT_A1R5G5B5_UNORM_PACK16)
444 ENUM_TO_STRING_CASE(VK_FORMAT_R8_UNORM)
445 ENUM_TO_STRING_CASE(VK_FORMAT_R8_SNORM)
446 ENUM_TO_STRING_CASE(VK_FORMAT_R8_USCALED)
447 ENUM_TO_STRING_CASE(VK_FORMAT_R8_SSCALED)
448 ENUM_TO_STRING_CASE(VK_FORMAT_R8_UINT)
449 ENUM_TO_STRING_CASE(VK_FORMAT_R8_SINT)
450 ENUM_TO_STRING_CASE(VK_FORMAT_R8_SRGB)
451 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8_UNORM)
452 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8_SNORM)
453 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8_USCALED)
454 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8_SSCALED)
455 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8_UINT)
456 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8_SINT)
457 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8_SRGB)
458 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8_UNORM)
459 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8_SNORM)
460 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8_USCALED)
461 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8_SSCALED)
462 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8_UINT)
463 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8_SINT)
464 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8_SRGB)
465 ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8_UNORM)
466 ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8_SNORM)
467 ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8_USCALED)
468 ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8_SSCALED)
469 ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8_UINT)
470 ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8_SINT)
471 ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8_SRGB)
472 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8A8_UNORM)
473 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8A8_SNORM)
474 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8A8_USCALED)
475 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8A8_SSCALED)
476 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8A8_UINT)
477 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8A8_SINT)
478 ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8A8_SRGB)
479 ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8A8_UNORM)
480 ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8A8_SNORM)
481 ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8A8_USCALED)
482 ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8A8_SSCALED)
483 ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8A8_UINT)
484 ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8A8_SINT)
485 ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8A8_SRGB)
486 ENUM_TO_STRING_CASE(VK_FORMAT_A8B8G8R8_UNORM_PACK32)
487 ENUM_TO_STRING_CASE(VK_FORMAT_A8B8G8R8_SNORM_PACK32)
488 ENUM_TO_STRING_CASE(VK_FORMAT_A8B8G8R8_USCALED_PACK32)
489 ENUM_TO_STRING_CASE(VK_FORMAT_A8B8G8R8_SSCALED_PACK32)
490 ENUM_TO_STRING_CASE(VK_FORMAT_A8B8G8R8_UINT_PACK32)
491 ENUM_TO_STRING_CASE(VK_FORMAT_A8B8G8R8_SINT_PACK32)
492 ENUM_TO_STRING_CASE(VK_FORMAT_A8B8G8R8_SRGB_PACK32)
493 ENUM_TO_STRING_CASE(VK_FORMAT_A2R10G10B10_UNORM_PACK32)
494 ENUM_TO_STRING_CASE(VK_FORMAT_A2R10G10B10_SNORM_PACK32)
495 ENUM_TO_STRING_CASE(VK_FORMAT_A2R10G10B10_USCALED_PACK32)
496 ENUM_TO_STRING_CASE(VK_FORMAT_A2R10G10B10_SSCALED_PACK32)
497 ENUM_TO_STRING_CASE(VK_FORMAT_A2R10G10B10_UINT_PACK32)
498 ENUM_TO_STRING_CASE(VK_FORMAT_A2R10G10B10_SINT_PACK32)
499 ENUM_TO_STRING_CASE(VK_FORMAT_A2B10G10R10_UNORM_PACK32)
500 ENUM_TO_STRING_CASE(VK_FORMAT_A2B10G10R10_SNORM_PACK32)
501 ENUM_TO_STRING_CASE(VK_FORMAT_A2B10G10R10_USCALED_PACK32)
502 ENUM_TO_STRING_CASE(VK_FORMAT_A2B10G10R10_SSCALED_PACK32)
503 ENUM_TO_STRING_CASE(VK_FORMAT_A2B10G10R10_UINT_PACK32)
504 ENUM_TO_STRING_CASE(VK_FORMAT_A2B10G10R10_SINT_PACK32)
505 ENUM_TO_STRING_CASE(VK_FORMAT_R16_UNORM)
506 ENUM_TO_STRING_CASE(VK_FORMAT_R16_SNORM)
507 ENUM_TO_STRING_CASE(VK_FORMAT_R16_USCALED)
508 ENUM_TO_STRING_CASE(VK_FORMAT_R16_SSCALED)
509 ENUM_TO_STRING_CASE(VK_FORMAT_R16_UINT)
510 ENUM_TO_STRING_CASE(VK_FORMAT_R16_SINT)
511 ENUM_TO_STRING_CASE(VK_FORMAT_R16_SFLOAT)
512 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16_UNORM)
513 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16_SNORM)
514 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16_USCALED)
515 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16_SSCALED)
516 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16_UINT)
517 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16_SINT)
518 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16_SFLOAT)
519 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16_UNORM)
520 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16_SNORM)
521 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16_USCALED)
522 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16_SSCALED)
523 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16_UINT)
524 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16_SINT)
525 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16_SFLOAT)
526 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16A16_UNORM)
527 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16A16_SNORM)
528 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16A16_USCALED)
529 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16A16_SSCALED)
530 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16A16_UINT)
531 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16A16_SINT)
532 ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16A16_SFLOAT)
533 ENUM_TO_STRING_CASE(VK_FORMAT_R32_UINT)
534 ENUM_TO_STRING_CASE(VK_FORMAT_R32_SINT)
535 ENUM_TO_STRING_CASE(VK_FORMAT_R32_SFLOAT)
536 ENUM_TO_STRING_CASE(VK_FORMAT_R32G32_UINT)
537 ENUM_TO_STRING_CASE(VK_FORMAT_R32G32_SINT)
538 ENUM_TO_STRING_CASE(VK_FORMAT_R32G32_SFLOAT)
539 ENUM_TO_STRING_CASE(VK_FORMAT_R32G32B32_UINT)
540 ENUM_TO_STRING_CASE(VK_FORMAT_R32G32B32_SINT)
541 ENUM_TO_STRING_CASE(VK_FORMAT_R32G32B32_SFLOAT)
542 ENUM_TO_STRING_CASE(VK_FORMAT_R32G32B32A32_UINT)
543 ENUM_TO_STRING_CASE(VK_FORMAT_R32G32B32A32_SINT)
544 ENUM_TO_STRING_CASE(VK_FORMAT_R32G32B32A32_SFLOAT)
545 ENUM_TO_STRING_CASE(VK_FORMAT_R64_UINT)
546 ENUM_TO_STRING_CASE(VK_FORMAT_R64_SINT)
547 ENUM_TO_STRING_CASE(VK_FORMAT_R64_SFLOAT)
548 ENUM_TO_STRING_CASE(VK_FORMAT_R64G64_UINT)
549 ENUM_TO_STRING_CASE(VK_FORMAT_R64G64_SINT)
550 ENUM_TO_STRING_CASE(VK_FORMAT_R64G64_SFLOAT)
551 ENUM_TO_STRING_CASE(VK_FORMAT_R64G64B64_UINT)
552 ENUM_TO_STRING_CASE(VK_FORMAT_R64G64B64_SINT)
553 ENUM_TO_STRING_CASE(VK_FORMAT_R64G64B64_SFLOAT)
554 ENUM_TO_STRING_CASE(VK_FORMAT_R64G64B64A64_UINT)
555 ENUM_TO_STRING_CASE(VK_FORMAT_R64G64B64A64_SINT)
556 ENUM_TO_STRING_CASE(VK_FORMAT_R64G64B64A64_SFLOAT)
557 ENUM_TO_STRING_CASE(VK_FORMAT_B10G11R11_UFLOAT_PACK32)
558 ENUM_TO_STRING_CASE(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)
559 ENUM_TO_STRING_CASE(VK_FORMAT_D16_UNORM)
560 ENUM_TO_STRING_CASE(VK_FORMAT_X8_D24_UNORM_PACK32)
561 ENUM_TO_STRING_CASE(VK_FORMAT_D32_SFLOAT)
562 ENUM_TO_STRING_CASE(VK_FORMAT_S8_UINT)
563 ENUM_TO_STRING_CASE(VK_FORMAT_D16_UNORM_S8_UINT)
564 ENUM_TO_STRING_CASE(VK_FORMAT_D24_UNORM_S8_UINT)
565 ENUM_TO_STRING_CASE(VK_FORMAT_D32_SFLOAT_S8_UINT)
566 ENUM_TO_STRING_CASE(VK_FORMAT_BC1_RGB_UNORM_BLOCK)
567 ENUM_TO_STRING_CASE(VK_FORMAT_BC1_RGB_SRGB_BLOCK)
568 ENUM_TO_STRING_CASE(VK_FORMAT_BC1_RGBA_UNORM_BLOCK)
569 ENUM_TO_STRING_CASE(VK_FORMAT_BC1_RGBA_SRGB_BLOCK)
570 ENUM_TO_STRING_CASE(VK_FORMAT_BC2_UNORM_BLOCK)
571 ENUM_TO_STRING_CASE(VK_FORMAT_BC2_SRGB_BLOCK)
572 ENUM_TO_STRING_CASE(VK_FORMAT_BC3_UNORM_BLOCK)
573 ENUM_TO_STRING_CASE(VK_FORMAT_BC3_SRGB_BLOCK)
574 ENUM_TO_STRING_CASE(VK_FORMAT_BC4_UNORM_BLOCK)
575 ENUM_TO_STRING_CASE(VK_FORMAT_BC4_SNORM_BLOCK)
576 ENUM_TO_STRING_CASE(VK_FORMAT_BC5_UNORM_BLOCK)
577 ENUM_TO_STRING_CASE(VK_FORMAT_BC5_SNORM_BLOCK)
578 ENUM_TO_STRING_CASE(VK_FORMAT_BC6H_UFLOAT_BLOCK)
579 ENUM_TO_STRING_CASE(VK_FORMAT_BC6H_SFLOAT_BLOCK)
580 ENUM_TO_STRING_CASE(VK_FORMAT_BC7_UNORM_BLOCK)
581 ENUM_TO_STRING_CASE(VK_FORMAT_BC7_SRGB_BLOCK)
582 ENUM_TO_STRING_CASE(VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK)
583 ENUM_TO_STRING_CASE(VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK)
584 ENUM_TO_STRING_CASE(VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK)
585 ENUM_TO_STRING_CASE(VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK)
586 ENUM_TO_STRING_CASE(VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK)
587 ENUM_TO_STRING_CASE(VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK)
588 ENUM_TO_STRING_CASE(VK_FORMAT_EAC_R11_UNORM_BLOCK)
589 ENUM_TO_STRING_CASE(VK_FORMAT_EAC_R11_SNORM_BLOCK)
590 ENUM_TO_STRING_CASE(VK_FORMAT_EAC_R11G11_UNORM_BLOCK)
591 ENUM_TO_STRING_CASE(VK_FORMAT_EAC_R11G11_SNORM_BLOCK)
592 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_4x4_UNORM_BLOCK)
593 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_4x4_SRGB_BLOCK)
594 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_5x4_UNORM_BLOCK)
595 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_5x4_SRGB_BLOCK)
596 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_5x5_UNORM_BLOCK)
597 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_5x5_SRGB_BLOCK)
598 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_6x5_UNORM_BLOCK)
599 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_6x5_SRGB_BLOCK)
600 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_6x6_UNORM_BLOCK)
601 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_6x6_SRGB_BLOCK)
602 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_8x5_UNORM_BLOCK)
603 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_8x5_SRGB_BLOCK)
604 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_8x6_UNORM_BLOCK)
605 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_8x6_SRGB_BLOCK)
606 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_8x8_UNORM_BLOCK)
607 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_8x8_SRGB_BLOCK)
608 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x5_UNORM_BLOCK)
609 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x5_SRGB_BLOCK)
610 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x6_UNORM_BLOCK)
611 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x6_SRGB_BLOCK)
612 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x8_UNORM_BLOCK)
613 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x8_SRGB_BLOCK)
614 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x10_UNORM_BLOCK)
615 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x10_SRGB_BLOCK)
616 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_12x10_UNORM_BLOCK)
617 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_12x10_SRGB_BLOCK)
618 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_12x12_UNORM_BLOCK)
619 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_12x12_SRGB_BLOCK)
620 ENUM_TO_STRING_CASE(VK_FORMAT_G8B8G8R8_422_UNORM)
621 ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8G8_422_UNORM)
622 ENUM_TO_STRING_CASE(VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM)
623 ENUM_TO_STRING_CASE(VK_FORMAT_G8_B8R8_2PLANE_420_UNORM)
624 ENUM_TO_STRING_CASE(VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM)
625 ENUM_TO_STRING_CASE(VK_FORMAT_G8_B8R8_2PLANE_422_UNORM)
626 ENUM_TO_STRING_CASE(VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM)
627 ENUM_TO_STRING_CASE(VK_FORMAT_R10X6_UNORM_PACK16)
628 ENUM_TO_STRING_CASE(VK_FORMAT_R10X6G10X6_UNORM_2PACK16)
629 ENUM_TO_STRING_CASE(VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16)
630 ENUM_TO_STRING_CASE(VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16)
631 ENUM_TO_STRING_CASE(VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16)
632 ENUM_TO_STRING_CASE(VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16)
633 ENUM_TO_STRING_CASE(VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16)
634 ENUM_TO_STRING_CASE(VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16)
635 ENUM_TO_STRING_CASE(VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16)
636 ENUM_TO_STRING_CASE(VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16)
637 ENUM_TO_STRING_CASE(VK_FORMAT_R12X4_UNORM_PACK16)
638 ENUM_TO_STRING_CASE(VK_FORMAT_R12X4G12X4_UNORM_2PACK16)
639 ENUM_TO_STRING_CASE(VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16)
640 ENUM_TO_STRING_CASE(VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16)
641 ENUM_TO_STRING_CASE(VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16)
642 ENUM_TO_STRING_CASE(VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16)
643 ENUM_TO_STRING_CASE(VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16)
644 ENUM_TO_STRING_CASE(VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16)
645 ENUM_TO_STRING_CASE(VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16)
646 ENUM_TO_STRING_CASE(VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16)
647 ENUM_TO_STRING_CASE(VK_FORMAT_G16B16G16R16_422_UNORM)
648 ENUM_TO_STRING_CASE(VK_FORMAT_B16G16R16G16_422_UNORM)
649 ENUM_TO_STRING_CASE(VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM)
650 ENUM_TO_STRING_CASE(VK_FORMAT_G16_B16R16_2PLANE_420_UNORM)
651 ENUM_TO_STRING_CASE(VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM)
652 ENUM_TO_STRING_CASE(VK_FORMAT_G16_B16R16_2PLANE_422_UNORM)
653 ENUM_TO_STRING_CASE(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM)
654 ENUM_TO_STRING_CASE(VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG)
655 ENUM_TO_STRING_CASE(VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG)
656 ENUM_TO_STRING_CASE(VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG)
657 ENUM_TO_STRING_CASE(VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG)
658 ENUM_TO_STRING_CASE(VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG)
659 ENUM_TO_STRING_CASE(VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG)
660 ENUM_TO_STRING_CASE(VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG)
661 ENUM_TO_STRING_CASE(VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG)
662 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT)
663 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT)
664 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT)
665 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT)
666 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT)
667 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT)
668 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT)
669 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT)
670 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT)
671 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT)
672 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT)
673 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT)
674 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT)
675 ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT)
676 ENUM_TO_STRING_CASE(VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT)
677 ENUM_TO_STRING_CASE(VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT)
678 ENUM_TO_STRING_CASE(VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT)
679 ENUM_TO_STRING_CASE(VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT)
680 ENUM_TO_STRING_CASE(VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT)
681 ENUM_TO_STRING_CASE(VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT)
682 ENUM_TO_STRING_CASE(VK_FORMAT_MAX_ENUM)
683 default: {
684 return String("Swapchain format ") + String::num_int64(int64_t(p_swapchain_format));
685 } break;
686 }
687}
688