2 * Copyright (c) 2015-2019 The Khronos Group Inc.
3 * Copyright (c) 2015-2019 Valve Corporation
4 * Copyright (c) 2015-2019 LunarG, Inc.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
19 * Author: David Pinedo <david@lunarg.com>
20 * Author: Mark Lobodzinski <mark@lunarg.com>
21 * Author: Rene Lindsay <rene@lunarg.com>
22 * Author: Jeremy Kniager <jeremyk@lunarg.com>
23 * Author: Shannon McPherson <shannon@lunarg.com>
24 * Author: Bob Ellison <bob@lunarg.com>
28 #ifndef _POSIX_C_SOURCE
29 #define _POSIX_C_SOURCE 200809L
32 #define strndup(p, n) strdup(p)
47 #if defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR)
48 #include <X11/Xutil.h>
51 #if defined(VK_USE_PLATFORM_MACOS_MVK)
52 #include "metal_view.h"
55 #include <vulkan/vulkan.h>
57 #define ERR(err) fprintf(stderr, "%s:%d: failed with %s\n", __FILE__, __LINE__, VkResultString(err));
61 #define snprintf _snprintf
62 #define strdup _strdup
64 // Returns nonzero if the console is used only for this process. Will return
65 // zero if another process (such as cmd.exe) is also attached.
66 static int ConsoleIsExclusive(void) {
68 DWORD num_pids = GetConsoleProcessList(pids, ARRAYSIZE(pids));
72 #define WAIT_FOR_CONSOLE_DESTROY \
74 if (ConsoleIsExclusive()) Sleep(INFINITE); \
77 #define WAIT_FOR_CONSOLE_DESTROY
80 #define ERR_EXIT(err) \
85 WAIT_FOR_CONSOLE_DESTROY; \
89 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
91 #define MAX_QUEUE_TYPES 5
92 #define APP_SHORT_NAME "vulkaninfo"
94 static bool html_output = false;
95 static bool human_readable_output = true;
96 static bool json_output = false;
97 static uint32_t selected_gpu = 0;
99 struct VkStructureHeader {
100 VkStructureType sType;
104 struct pNextChainBuildingBlockInfo {
105 VkStructureType sType;
109 struct LayerExtensionList {
110 VkLayerProperties layer_properties;
111 uint32_t extension_count;
112 VkExtensionProperties *extension_properties;
117 uint32_t instance_version;
118 uint32_t vulkan_major;
119 uint32_t vulkan_minor;
120 uint32_t vulkan_patch;
122 uint32_t global_layer_count;
123 struct LayerExtensionList *global_layers;
124 uint32_t global_extension_count;
125 VkExtensionProperties *global_extensions; // Instance Extensions
127 const char **inst_extensions;
128 uint32_t inst_extensions_count;
130 // Functions from vkGetInstanceProcAddress
131 PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
132 PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
133 PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
134 PFN_vkGetPhysicalDeviceSurfaceFormats2KHR vkGetPhysicalDeviceSurfaceFormats2KHR;
135 PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
136 PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR;
137 PFN_vkGetPhysicalDeviceFormatProperties2KHR vkGetPhysicalDeviceFormatProperties2KHR;
138 PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR vkGetPhysicalDeviceQueueFamilyProperties2KHR;
139 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR;
140 PFN_vkGetPhysicalDeviceMemoryProperties2KHR vkGetPhysicalDeviceMemoryProperties2KHR;
141 PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR vkGetPhysicalDeviceSurfaceCapabilities2KHR;
142 PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT vkGetPhysicalDeviceSurfaceCapabilities2EXT;
144 VkSurfaceCapabilitiesKHR surface_capabilities;
145 VkSurfaceCapabilities2KHR surface_capabilities2;
146 VkSharedPresentSurfaceCapabilitiesKHR shared_surface_capabilities;
147 VkSurfaceCapabilities2EXT surface_capabilities2_ext;
149 VkSurfaceKHR surface;
152 #ifdef VK_USE_PLATFORM_WIN32_KHR
153 HINSTANCE h_instance; // Windows Instance
154 HWND h_wnd; // window handle
156 #ifdef VK_USE_PLATFORM_XCB_KHR
157 xcb_connection_t *xcb_connection;
158 xcb_screen_t *xcb_screen;
159 xcb_window_t xcb_window;
161 #ifdef VK_USE_PLATFORM_XLIB_KHR
162 Display *xlib_display;
165 #ifdef VK_USE_PLATFORM_ANDROID_KHR // TODO
166 struct ANativeWindow *window;
168 #ifdef VK_USE_PLATFORM_MACOS_MVK
171 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
172 struct wl_display *wayland_display;
173 struct wl_surface *wayland_surface;
179 VkPhysicalDevice obj;
181 VkPhysicalDeviceProperties props;
182 VkPhysicalDeviceProperties2KHR props2;
184 uint32_t queue_count;
185 VkQueueFamilyProperties *queue_props;
186 VkQueueFamilyProperties2KHR *queue_props2;
187 VkDeviceQueueCreateInfo *queue_reqs;
189 struct AppInstance *inst;
191 VkPhysicalDeviceMemoryProperties memory_props;
192 VkPhysicalDeviceMemoryProperties2KHR memory_props2;
194 VkPhysicalDeviceFeatures features;
195 VkPhysicalDeviceFeatures2KHR features2;
196 VkPhysicalDevice limits;
198 uint32_t device_extension_count;
199 VkExtensionProperties *device_extensions;
202 // return most severe flag only
203 static const char *DebugReportFlagString(const VkDebugReportFlagsEXT flags) {
205 case VK_DEBUG_REPORT_ERROR_BIT_EXT:
207 case VK_DEBUG_REPORT_WARNING_BIT_EXT:
209 case VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT:
211 case VK_DEBUG_REPORT_INFORMATION_BIT_EXT:
213 case VK_DEBUG_REPORT_DEBUG_BIT_EXT:
220 static VKAPI_ATTR VkBool32 VKAPI_CALL DbgCallback(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType,
221 uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix,
222 const char *pMsg, void *pUserData) {
223 fprintf(stderr, "%s: [%s] Code %d : %s\n", DebugReportFlagString(msgFlags), pLayerPrefix, msgCode, pMsg);
226 // True is reserved for layer developers, and MAY mean calls are not distributed down the layer chain after validation error.
227 // False SHOULD always be returned by apps:
231 static const char *VkResultString(VkResult err) {
242 STR(VK_ERROR_OUT_OF_HOST_MEMORY);
243 STR(VK_ERROR_OUT_OF_DEVICE_MEMORY);
244 STR(VK_ERROR_INITIALIZATION_FAILED);
245 STR(VK_ERROR_DEVICE_LOST);
246 STR(VK_ERROR_MEMORY_MAP_FAILED);
247 STR(VK_ERROR_LAYER_NOT_PRESENT);
248 STR(VK_ERROR_EXTENSION_NOT_PRESENT);
249 STR(VK_ERROR_FEATURE_NOT_PRESENT);
250 STR(VK_ERROR_INCOMPATIBLE_DRIVER);
251 STR(VK_ERROR_TOO_MANY_OBJECTS);
252 STR(VK_ERROR_FORMAT_NOT_SUPPORTED);
253 STR(VK_ERROR_FRAGMENTED_POOL);
254 STR(VK_ERROR_OUT_OF_POOL_MEMORY);
255 STR(VK_ERROR_INVALID_EXTERNAL_HANDLE);
256 STR(VK_ERROR_SURFACE_LOST_KHR);
257 STR(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR);
258 STR(VK_SUBOPTIMAL_KHR);
259 STR(VK_ERROR_OUT_OF_DATE_KHR);
260 STR(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR);
261 STR(VK_ERROR_VALIDATION_FAILED_EXT);
262 STR(VK_ERROR_INVALID_SHADER_NV);
263 STR(VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT);
264 STR(VK_ERROR_FRAGMENTATION_EXT);
265 STR(VK_ERROR_NOT_PERMITTED_EXT);
268 return "UNKNOWN_RESULT";
272 static const char *VkPhysicalDeviceTypeString(VkPhysicalDeviceType type) {
275 case VK_PHYSICAL_DEVICE_TYPE_##r: \
284 return "UNKNOWN_DEVICE";
288 static const char *VkFormatString(VkFormat fmt) {
291 case VK_FORMAT_##r: \
294 STR(R4G4_UNORM_PACK8);
295 STR(R4G4B4A4_UNORM_PACK16);
296 STR(B4G4R4A4_UNORM_PACK16);
297 STR(R5G6B5_UNORM_PACK16);
298 STR(B5G6R5_UNORM_PACK16);
299 STR(R5G5B5A1_UNORM_PACK16);
300 STR(B5G5R5A1_UNORM_PACK16);
301 STR(A1R5G5B5_UNORM_PACK16);
332 STR(R8G8B8A8_USCALED);
333 STR(R8G8B8A8_SSCALED);
339 STR(B8G8R8A8_USCALED);
340 STR(B8G8R8A8_SSCALED);
344 STR(A8B8G8R8_UNORM_PACK32);
345 STR(A8B8G8R8_SNORM_PACK32);
346 STR(A8B8G8R8_USCALED_PACK32);
347 STR(A8B8G8R8_SSCALED_PACK32);
348 STR(A8B8G8R8_UINT_PACK32);
349 STR(A8B8G8R8_SINT_PACK32);
350 STR(A8B8G8R8_SRGB_PACK32);
351 STR(A2R10G10B10_UNORM_PACK32);
352 STR(A2R10G10B10_SNORM_PACK32);
353 STR(A2R10G10B10_USCALED_PACK32);
354 STR(A2R10G10B10_SSCALED_PACK32);
355 STR(A2R10G10B10_UINT_PACK32);
356 STR(A2R10G10B10_SINT_PACK32);
357 STR(A2B10G10R10_UNORM_PACK32);
358 STR(A2B10G10R10_SNORM_PACK32);
359 STR(A2B10G10R10_USCALED_PACK32);
360 STR(A2B10G10R10_SSCALED_PACK32);
361 STR(A2B10G10R10_UINT_PACK32);
362 STR(A2B10G10R10_SINT_PACK32);
377 STR(R16G16B16_UNORM);
378 STR(R16G16B16_SNORM);
379 STR(R16G16B16_USCALED);
380 STR(R16G16B16_SSCALED);
383 STR(R16G16B16_SFLOAT);
384 STR(R16G16B16A16_UNORM);
385 STR(R16G16B16A16_SNORM);
386 STR(R16G16B16A16_USCALED);
387 STR(R16G16B16A16_SSCALED);
388 STR(R16G16B16A16_UINT);
389 STR(R16G16B16A16_SINT);
390 STR(R16G16B16A16_SFLOAT);
399 STR(R32G32B32_SFLOAT);
400 STR(R32G32B32A32_UINT);
401 STR(R32G32B32A32_SINT);
402 STR(R32G32B32A32_SFLOAT);
411 STR(R64G64B64_SFLOAT);
412 STR(R64G64B64A64_UINT);
413 STR(R64G64B64A64_SINT);
414 STR(R64G64B64A64_SFLOAT);
415 STR(B10G11R11_UFLOAT_PACK32);
416 STR(E5B9G9R9_UFLOAT_PACK32);
418 STR(X8_D24_UNORM_PACK32);
421 STR(D16_UNORM_S8_UINT);
422 STR(D24_UNORM_S8_UINT);
423 STR(D32_SFLOAT_S8_UINT);
424 STR(BC1_RGB_UNORM_BLOCK);
425 STR(BC1_RGB_SRGB_BLOCK);
426 STR(BC1_RGBA_UNORM_BLOCK);
427 STR(BC1_RGBA_SRGB_BLOCK);
428 STR(BC2_UNORM_BLOCK);
430 STR(BC3_UNORM_BLOCK);
432 STR(BC4_UNORM_BLOCK);
433 STR(BC4_SNORM_BLOCK);
434 STR(BC5_UNORM_BLOCK);
435 STR(BC5_SNORM_BLOCK);
436 STR(BC6H_UFLOAT_BLOCK);
437 STR(BC6H_SFLOAT_BLOCK);
438 STR(BC7_UNORM_BLOCK);
440 STR(ETC2_R8G8B8_UNORM_BLOCK);
441 STR(ETC2_R8G8B8_SRGB_BLOCK);
442 STR(ETC2_R8G8B8A1_UNORM_BLOCK);
443 STR(ETC2_R8G8B8A1_SRGB_BLOCK);
444 STR(ETC2_R8G8B8A8_UNORM_BLOCK);
445 STR(ETC2_R8G8B8A8_SRGB_BLOCK);
446 STR(EAC_R11_UNORM_BLOCK);
447 STR(EAC_R11_SNORM_BLOCK);
448 STR(EAC_R11G11_UNORM_BLOCK);
449 STR(EAC_R11G11_SNORM_BLOCK);
450 STR(ASTC_4x4_UNORM_BLOCK);
451 STR(ASTC_4x4_SRGB_BLOCK);
452 STR(ASTC_5x4_UNORM_BLOCK);
453 STR(ASTC_5x4_SRGB_BLOCK);
454 STR(ASTC_5x5_UNORM_BLOCK);
455 STR(ASTC_5x5_SRGB_BLOCK);
456 STR(ASTC_6x5_UNORM_BLOCK);
457 STR(ASTC_6x5_SRGB_BLOCK);
458 STR(ASTC_6x6_UNORM_BLOCK);
459 STR(ASTC_6x6_SRGB_BLOCK);
460 STR(ASTC_8x5_UNORM_BLOCK);
461 STR(ASTC_8x5_SRGB_BLOCK);
462 STR(ASTC_8x6_UNORM_BLOCK);
463 STR(ASTC_8x6_SRGB_BLOCK);
464 STR(ASTC_8x8_UNORM_BLOCK);
465 STR(ASTC_8x8_SRGB_BLOCK);
466 STR(ASTC_10x5_UNORM_BLOCK);
467 STR(ASTC_10x5_SRGB_BLOCK);
468 STR(ASTC_10x6_UNORM_BLOCK);
469 STR(ASTC_10x6_SRGB_BLOCK);
470 STR(ASTC_10x8_UNORM_BLOCK);
471 STR(ASTC_10x8_SRGB_BLOCK);
472 STR(ASTC_10x10_UNORM_BLOCK);
473 STR(ASTC_10x10_SRGB_BLOCK);
474 STR(ASTC_12x10_UNORM_BLOCK);
475 STR(ASTC_12x10_SRGB_BLOCK);
476 STR(ASTC_12x12_UNORM_BLOCK);
477 STR(ASTC_12x12_SRGB_BLOCK);
478 STR(G8B8G8R8_422_UNORM);
479 STR(B8G8R8G8_422_UNORM);
480 STR(G8_B8_R8_3PLANE_420_UNORM);
481 STR(G8_B8R8_2PLANE_420_UNORM);
482 STR(G8_B8_R8_3PLANE_422_UNORM);
483 STR(G8_B8R8_2PLANE_422_UNORM);
484 STR(G8_B8_R8_3PLANE_444_UNORM);
485 STR(R10X6_UNORM_PACK16);
486 STR(R10X6G10X6_UNORM_2PACK16);
487 STR(R10X6G10X6B10X6A10X6_UNORM_4PACK16);
488 STR(G10X6B10X6G10X6R10X6_422_UNORM_4PACK16);
489 STR(B10X6G10X6R10X6G10X6_422_UNORM_4PACK16);
490 STR(G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16);
491 STR(G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16);
492 STR(G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16);
493 STR(G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16);
494 STR(G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16);
495 STR(R12X4_UNORM_PACK16);
496 STR(R12X4G12X4_UNORM_2PACK16);
497 STR(R12X4G12X4B12X4A12X4_UNORM_4PACK16);
498 STR(G12X4B12X4G12X4R12X4_422_UNORM_4PACK16);
499 STR(B12X4G12X4R12X4G12X4_422_UNORM_4PACK16);
500 STR(G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16);
501 STR(G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16);
502 STR(G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16);
503 STR(G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16);
504 STR(G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16);
505 STR(G16B16G16R16_422_UNORM);
506 STR(B16G16R16G16_422_UNORM);
507 STR(G16_B16_R16_3PLANE_420_UNORM);
508 STR(G16_B16R16_2PLANE_420_UNORM);
509 STR(G16_B16_R16_3PLANE_422_UNORM);
510 STR(G16_B16R16_2PLANE_422_UNORM);
511 STR(G16_B16_R16_3PLANE_444_UNORM);
512 STR(PVRTC1_2BPP_UNORM_BLOCK_IMG);
513 STR(PVRTC1_4BPP_UNORM_BLOCK_IMG);
514 STR(PVRTC2_2BPP_UNORM_BLOCK_IMG);
515 STR(PVRTC2_4BPP_UNORM_BLOCK_IMG);
516 STR(PVRTC1_2BPP_SRGB_BLOCK_IMG);
517 STR(PVRTC1_4BPP_SRGB_BLOCK_IMG);
518 STR(PVRTC2_2BPP_SRGB_BLOCK_IMG);
519 STR(PVRTC2_4BPP_SRGB_BLOCK_IMG);
522 return "UNKNOWN_FORMAT";
525 #if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \
526 defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_WAYLAND_KHR)
527 static const char *VkPresentModeString(VkPresentModeKHR mode) {
530 case VK_PRESENT_MODE_##r: \
535 STR(FIFO_RELAXED_KHR);
536 STR(SHARED_DEMAND_REFRESH_KHR);
537 STR(SHARED_CONTINUOUS_REFRESH_KHR);
540 return "UNKNOWN_FORMAT";
545 static bool CheckExtensionEnabled(const char *extension_to_check, const char **extension_list, uint32_t extension_count) {
546 for (uint32_t i = 0; i < extension_count; ++i) {
547 if (!strcmp(extension_to_check, extension_list[i])) {
554 static bool CheckPhysicalDeviceExtensionIncluded(const char *extension_to_check, VkExtensionProperties *extension_list,
555 uint32_t extension_count) {
556 for (uint32_t i = 0; i < extension_count; ++i) {
557 if (!strcmp(extension_to_check, extension_list[i].extensionName)) {
564 static void buildpNextChain(struct VkStructureHeader *first, const struct pNextChainBuildingBlockInfo *chain_info,
565 uint32_t chain_info_len) {
566 struct VkStructureHeader *place = first;
568 for (uint32_t i = 0; i < chain_info_len; i++) {
569 place->pNext = malloc(chain_info[i].mem_size);
571 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
573 memset(place->pNext, 0, chain_info[i].mem_size);
574 place = place->pNext;
575 place->sType = chain_info[i].sType;
581 static void freepNextChain(struct VkStructureHeader *first) {
582 struct VkStructureHeader *place = first;
583 struct VkStructureHeader *next = NULL;
592 static void ExtractVersion(uint32_t version, uint32_t *major, uint32_t *minor, uint32_t *patch) {
593 *major = version >> 22;
594 *minor = (version >> 12) & 0x3ff;
595 *patch = version & 0xfff;
598 static void AppGetPhysicalDeviceLayerExtensions(struct AppGpu *gpu, char *layer_name, uint32_t *extension_count,
599 VkExtensionProperties **extension_properties) {
601 uint32_t ext_count = 0;
602 VkExtensionProperties *ext_ptr = NULL;
604 /* repeat get until VK_INCOMPLETE goes away */
606 err = vkEnumerateDeviceExtensionProperties(gpu->obj, layer_name, &ext_count, NULL);
607 if (err) ERR_EXIT(err);
612 ext_ptr = malloc(ext_count * sizeof(VkExtensionProperties));
613 err = vkEnumerateDeviceExtensionProperties(gpu->obj, layer_name, &ext_count, ext_ptr);
614 } while (err == VK_INCOMPLETE);
615 if (err) ERR_EXIT(err);
617 *extension_count = ext_count;
618 *extension_properties = ext_ptr;
621 static void AppGetGlobalLayerExtensions(char *layer_name, uint32_t *extension_count, VkExtensionProperties **extension_properties) {
623 uint32_t ext_count = 0;
624 VkExtensionProperties *ext_ptr = NULL;
626 /* repeat get until VK_INCOMPLETE goes away */
628 // gets the extension count if the last parameter is NULL
629 err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, NULL);
630 if (err) ERR_EXIT(err);
635 ext_ptr = malloc(ext_count * sizeof(VkExtensionProperties));
636 // gets the extension properties if the last parameter is not NULL
637 err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, ext_ptr);
638 } while (err == VK_INCOMPLETE);
639 if (err) ERR_EXIT(err);
640 *extension_count = ext_count;
641 *extension_properties = ext_ptr;
644 /* Gets a list of layer and instance extensions */
645 static void AppGetInstanceExtensions(struct AppInstance *inst) {
651 VkLayerProperties *global_layer_properties = NULL;
652 struct LayerExtensionList *global_layers = NULL;
655 err = vkEnumerateInstanceLayerProperties(&count, NULL);
656 if (err) ERR_EXIT(err);
658 if (global_layer_properties) {
659 free(global_layer_properties);
661 global_layer_properties = malloc(sizeof(VkLayerProperties) * count);
662 assert(global_layer_properties);
667 global_layers = malloc(sizeof(struct LayerExtensionList) * count);
668 assert(global_layers);
670 err = vkEnumerateInstanceLayerProperties(&count, global_layer_properties);
671 } while (err == VK_INCOMPLETE);
672 if (err) ERR_EXIT(err);
674 inst->global_layer_count = count;
675 inst->global_layers = global_layers;
677 for (uint32_t i = 0; i < inst->global_layer_count; ++i) {
678 VkLayerProperties *src_info = &global_layer_properties[i];
679 struct LayerExtensionList *dst_info = &inst->global_layers[i];
680 memcpy(&dst_info->layer_properties, src_info, sizeof(VkLayerProperties));
682 // Save away layer extension info for report
683 // Gets layer extensions, if first parameter is not NULL
684 AppGetGlobalLayerExtensions(src_info->layerName, &dst_info->extension_count, &dst_info->extension_properties);
686 free(global_layer_properties);
688 // Collect global extensions
689 inst->global_extension_count = 0;
690 // Gets instance extensions, if no layer was specified in the first
692 AppGetGlobalLayerExtensions(NULL, &inst->global_extension_count, &inst->global_extensions);
695 // Prints opening code for html output file
696 void PrintHtmlHeader(FILE *out) {
697 fprintf(out, "<!doctype html>\n");
698 fprintf(out, "<html>\n");
699 fprintf(out, "\t<head>\n");
700 fprintf(out, "\t\t<title>vulkaninfo</title>\n");
701 fprintf(out, "\t\t<style type='text/css'>\n");
702 fprintf(out, "\t\thtml {\n");
703 fprintf(out, "\t\t\tbackground-color: #0b1e48;\n");
704 fprintf(out, "\t\t\tbackground-image: url(\"https://vulkan.lunarg.com/img/bg-starfield.jpg\");\n");
705 fprintf(out, "\t\t\tbackground-position: center;\n");
706 fprintf(out, "\t\t\t-webkit-background-size: cover;\n");
707 fprintf(out, "\t\t\t-moz-background-size: cover;\n");
708 fprintf(out, "\t\t\t-o-background-size: cover;\n");
709 fprintf(out, "\t\t\tbackground-size: cover;\n");
710 fprintf(out, "\t\t\tbackground-attachment: fixed;\n");
711 fprintf(out, "\t\t\tbackground-repeat: no-repeat;\n");
712 fprintf(out, "\t\t\theight: 100%%;\n");
713 fprintf(out, "\t\t}\n");
714 fprintf(out, "\t\t#header {\n");
715 fprintf(out, "\t\t\tz-index: -1;\n");
716 fprintf(out, "\t\t}\n");
717 fprintf(out, "\t\t#header>img {\n");
718 fprintf(out, "\t\t\tposition: absolute;\n");
719 fprintf(out, "\t\t\twidth: 160px;\n");
720 fprintf(out, "\t\t\tmargin-left: -280px;\n");
721 fprintf(out, "\t\t\ttop: -10px;\n");
722 fprintf(out, "\t\t\tleft: 50%%;\n");
723 fprintf(out, "\t\t}\n");
724 fprintf(out, "\t\t#header>h1 {\n");
725 fprintf(out, "\t\t\tfont-family: Arial, \"Helvetica Neue\", Helvetica, sans-serif;\n");
726 fprintf(out, "\t\t\tfont-size: 44px;\n");
727 fprintf(out, "\t\t\tfont-weight: 200;\n");
728 fprintf(out, "\t\t\ttext-shadow: 4px 4px 5px #000;\n");
729 fprintf(out, "\t\t\tcolor: #eee;\n");
730 fprintf(out, "\t\t\tposition: absolute;\n");
731 fprintf(out, "\t\t\twidth: 400px;\n");
732 fprintf(out, "\t\t\tmargin-left: -80px;\n");
733 fprintf(out, "\t\t\ttop: 8px;\n");
734 fprintf(out, "\t\t\tleft: 50%%;\n");
735 fprintf(out, "\t\t}\n");
736 fprintf(out, "\t\tbody {\n");
737 fprintf(out, "\t\t\tfont-family: Consolas, monaco, monospace;\n");
738 fprintf(out, "\t\t\tfont-size: 14px;\n");
739 fprintf(out, "\t\t\tline-height: 20px;\n");
740 fprintf(out, "\t\t\tcolor: #eee;\n");
741 fprintf(out, "\t\t\theight: 100%%;\n");
742 fprintf(out, "\t\t\tmargin: 0;\n");
743 fprintf(out, "\t\t\toverflow: hidden;\n");
744 fprintf(out, "\t\t}\n");
745 fprintf(out, "\t\t#wrapper {\n");
746 fprintf(out, "\t\t\tbackground-color: rgba(0, 0, 0, 0.7);\n");
747 fprintf(out, "\t\t\tborder: 1px solid #446;\n");
748 fprintf(out, "\t\t\tbox-shadow: 0px 0px 10px #000;\n");
749 fprintf(out, "\t\t\tpadding: 8px 12px;\n\n");
750 fprintf(out, "\t\t\tdisplay: inline-block;\n");
751 fprintf(out, "\t\t\tposition: absolute;\n");
752 fprintf(out, "\t\t\ttop: 80px;\n");
753 fprintf(out, "\t\t\tbottom: 25px;\n");
754 fprintf(out, "\t\t\tleft: 50px;\n");
755 fprintf(out, "\t\t\tright: 50px;\n");
756 fprintf(out, "\t\t\toverflow: auto;\n");
757 fprintf(out, "\t\t}\n");
758 fprintf(out, "\t\tdetails>details {\n");
759 fprintf(out, "\t\t\tmargin-left: 22px;\n");
760 fprintf(out, "\t\t}\n");
761 fprintf(out, "\t\tdetails>summary:only-child::-webkit-details-marker {\n");
762 fprintf(out, "\t\t\tdisplay: none;\n");
763 fprintf(out, "\t\t}\n");
764 fprintf(out, "\t\t.var, .type, .val {\n");
765 fprintf(out, "\t\t\tdisplay: inline;\n");
766 fprintf(out, "\t\t}\n");
767 fprintf(out, "\t\t.var {\n");
768 fprintf(out, "\t\t}\n");
769 fprintf(out, "\t\t.type {\n");
770 fprintf(out, "\t\t\tcolor: #acf;\n");
771 fprintf(out, "\t\t\tmargin: 0 12px;\n");
772 fprintf(out, "\t\t}\n");
773 fprintf(out, "\t\t.val {\n");
774 fprintf(out, "\t\t\tcolor: #afa;\n");
775 fprintf(out, "\t\t\tbackground: #222;\n");
776 fprintf(out, "\t\t\ttext-align: right;\n");
777 fprintf(out, "\t\t}\n");
778 fprintf(out, "\t\t</style>\n");
779 fprintf(out, "\t</head>\n");
780 fprintf(out, "\t<body>\n");
781 fprintf(out, "\t\t<div id='header'>\n");
782 fprintf(out, "\t\t\t<h1>vulkaninfo</h1>\n");
783 fprintf(out, "\t\t</div>\n");
784 fprintf(out, "\t\t<div id='wrapper'>\n");
787 // Prints closing code for html output file
788 void PrintHtmlFooter(FILE *out) {
789 fprintf(out, "\t\t</div>\n");
790 fprintf(out, "\t</body>\n");
791 fprintf(out, "</html>");
794 // Prints opening code for json output file
795 void PrintJsonHeader(const int vulkan_major, const int vulkan_minor, const int vulkan_patch) {
797 printf("\t\"$schema\": \"https://schema.khronos.org/vulkan/devsim_1_0_0.json#\",\n");
798 printf("\t\"comments\": {\n");
799 printf("\t\t\"desc\": \"JSON configuration file describing GPU %u. Generated using the vulkaninfo program.\",\n", selected_gpu);
800 printf("\t\t\"vulkanApiVersion\": \"%d.%d.%d\"\n", vulkan_major, vulkan_minor, vulkan_patch);
804 // Checks if current argument specifies json output, interprets/updates gpu selection
805 bool CheckForJsonOption(const char *arg) {
806 if (strncmp("--json", arg, 6) == 0 || strcmp(arg, "-j") == 0) {
807 if (strlen(arg) > 7 && strncmp("--json=", arg, 7) == 0) {
808 selected_gpu = strtol(arg + 7, NULL, 10);
810 human_readable_output = false;
818 static void AppCompileInstanceExtensionsToEnable(struct AppInstance *inst) {
819 // Get all supported Instance extensions (excl. layer-provided ones)
820 inst->inst_extensions_count = inst->global_extension_count;
821 inst->inst_extensions = malloc(sizeof(char *) * inst->inst_extensions_count);
822 if (!inst->inst_extensions) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
824 for (uint32_t i = 0; i < inst->global_extension_count; ++i) {
825 inst->inst_extensions[i] = inst->global_extensions[i].extensionName;
829 static void AppLoadInstanceCommands(struct AppInstance *inst) {
830 #define LOAD_INSTANCE_VK_CMD(cmd) inst->cmd = (PFN_##cmd)vkGetInstanceProcAddr(inst->instance, #cmd)
832 LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceSupportKHR);
833 LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
834 LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceFormatsKHR);
835 LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceFormats2KHR);
836 LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfacePresentModesKHR);
837 LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceProperties2KHR);
838 LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceFormatProperties2KHR);
839 LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceQueueFamilyProperties2KHR);
840 LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceFeatures2KHR);
841 LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceMemoryProperties2KHR);
842 LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceCapabilities2KHR);
843 LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceCapabilities2EXT);
845 #undef LOAD_INSTANCE_VK_CMD
848 static void AppCreateInstance(struct AppInstance *inst) {
849 PFN_vkEnumerateInstanceVersion enumerate_instance_version =
850 (PFN_vkEnumerateInstanceVersion)vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceVersion");
852 if (!enumerate_instance_version) {
853 inst->instance_version = VK_API_VERSION_1_0;
855 const VkResult err = enumerate_instance_version(&inst->instance_version);
856 if (err) ERR_EXIT(err);
859 inst->vulkan_major = VK_VERSION_MAJOR(inst->instance_version);
860 inst->vulkan_minor = VK_VERSION_MINOR(inst->instance_version);
861 inst->vulkan_patch = VK_VERSION_PATCH(VK_HEADER_VERSION);
863 AppGetInstanceExtensions(inst);
865 const VkDebugReportCallbackCreateInfoEXT dbg_info = {.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
866 .flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT,
867 .pfnCallback = DbgCallback};
869 const VkApplicationInfo app_info = {.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
870 .pApplicationName = APP_SHORT_NAME,
871 .applicationVersion = 1,
872 .apiVersion = VK_API_VERSION_1_0};
874 AppCompileInstanceExtensionsToEnable(inst);
875 const VkInstanceCreateInfo inst_info = {.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
877 .pApplicationInfo = &app_info,
878 .enabledExtensionCount = inst->inst_extensions_count,
879 .ppEnabledExtensionNames = inst->inst_extensions};
881 VkResult err = vkCreateInstance(&inst_info, NULL, &inst->instance);
882 if (err == VK_ERROR_INCOMPATIBLE_DRIVER) {
883 fprintf(stderr, "Cannot create Vulkan instance.\n");
889 AppLoadInstanceCommands(inst);
892 static void AppDestroyInstance(struct AppInstance *inst) {
893 free(inst->global_extensions);
894 for (uint32_t i = 0; i < inst->global_layer_count; ++i) {
895 free(inst->global_layers[i].extension_properties);
897 free(inst->global_layers);
898 free((char **)inst->inst_extensions);
899 vkDestroyInstance(inst->instance, NULL);
902 static void AppGpuInit(struct AppGpu *gpu, struct AppInstance *inst, uint32_t id, VkPhysicalDevice obj) {
905 memset(gpu, 0, sizeof(*gpu));
911 vkGetPhysicalDeviceProperties(gpu->obj, &gpu->props);
913 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
914 gpu->inst->inst_extensions_count)) {
915 struct pNextChainBuildingBlockInfo chain_info[] = {
916 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT,
917 .mem_size = sizeof(VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT)},
918 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR,
919 .mem_size = sizeof(VkPhysicalDevicePointClippingPropertiesKHR)},
920 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR,
921 .mem_size = sizeof(VkPhysicalDevicePushDescriptorPropertiesKHR)},
922 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT,
923 .mem_size = sizeof(VkPhysicalDeviceDiscardRectanglePropertiesEXT)},
924 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR,
925 .mem_size = sizeof(VkPhysicalDeviceMultiviewPropertiesKHR)},
926 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR,
927 .mem_size = sizeof(VkPhysicalDeviceMaintenance3PropertiesKHR)},
928 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR, .mem_size = sizeof(VkPhysicalDeviceIDPropertiesKHR)},
929 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR,
930 .mem_size = sizeof(VkPhysicalDeviceDriverPropertiesKHR)},
931 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR,
932 .mem_size = sizeof(VkPhysicalDeviceFloatControlsPropertiesKHR)},
933 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT,
934 .mem_size = sizeof(VkPhysicalDevicePCIBusInfoPropertiesEXT)},
935 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT,
936 .mem_size = sizeof(VkPhysicalDeviceTransformFeedbackPropertiesEXT)},
937 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT,
938 .mem_size = sizeof(VkPhysicalDeviceFragmentDensityMapPropertiesEXT)}};
940 uint32_t chain_info_len = ARRAY_SIZE(chain_info);
942 gpu->props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
943 buildpNextChain((struct VkStructureHeader *)&gpu->props2, chain_info, chain_info_len);
945 inst->vkGetPhysicalDeviceProperties2KHR(gpu->obj, &gpu->props2);
948 /* get queue count */
949 vkGetPhysicalDeviceQueueFamilyProperties(gpu->obj, &gpu->queue_count, NULL);
951 gpu->queue_props = malloc(sizeof(gpu->queue_props[0]) * gpu->queue_count);
953 if (!gpu->queue_props) {
954 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
956 vkGetPhysicalDeviceQueueFamilyProperties(gpu->obj, &gpu->queue_count, gpu->queue_props);
958 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
959 gpu->inst->inst_extensions_count)) {
960 gpu->queue_props2 = malloc(sizeof(gpu->queue_props2[0]) * gpu->queue_count);
962 if (!gpu->queue_props2) {
963 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
966 for (i = 0; i < gpu->queue_count; ++i) {
967 gpu->queue_props2[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR;
968 gpu->queue_props2[i].pNext = NULL;
971 inst->vkGetPhysicalDeviceQueueFamilyProperties2KHR(gpu->obj, &gpu->queue_count, gpu->queue_props2);
974 /* set up queue requests */
975 gpu->queue_reqs = malloc(sizeof(*gpu->queue_reqs) * gpu->queue_count);
976 if (!gpu->queue_reqs) {
977 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
979 for (i = 0; i < gpu->queue_count; ++i) {
980 float *queue_priorities = NULL;
981 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
982 gpu->inst->inst_extensions_count)) {
983 queue_priorities = malloc(gpu->queue_props2[i].queueFamilyProperties.queueCount * sizeof(float));
985 queue_priorities = malloc(gpu->queue_props[i].queueCount * sizeof(float));
987 if (!queue_priorities) {
988 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
991 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
992 gpu->inst->inst_extensions_count)) {
993 memset(queue_priorities, 0, gpu->queue_props2[i].queueFamilyProperties.queueCount * sizeof(float));
995 memset(queue_priorities, 0, gpu->queue_props[i].queueCount * sizeof(float));
998 gpu->queue_reqs[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
999 gpu->queue_reqs[i].pNext = NULL;
1000 gpu->queue_reqs[i].flags = 0;
1001 gpu->queue_reqs[i].queueFamilyIndex = i;
1003 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
1004 gpu->inst->inst_extensions_count)) {
1005 gpu->queue_reqs[i].queueCount = gpu->queue_props2[i].queueFamilyProperties.queueCount;
1007 gpu->queue_reqs[i].queueCount = gpu->queue_props[i].queueCount;
1010 gpu->queue_reqs[i].pQueuePriorities = queue_priorities;
1013 vkGetPhysicalDeviceMemoryProperties(gpu->obj, &gpu->memory_props);
1015 vkGetPhysicalDeviceFeatures(gpu->obj, &gpu->features);
1017 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
1018 gpu->inst->inst_extensions_count)) {
1019 gpu->memory_props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR;
1020 gpu->memory_props2.pNext = NULL;
1022 inst->vkGetPhysicalDeviceMemoryProperties2KHR(gpu->obj, &gpu->memory_props2);
1024 struct pNextChainBuildingBlockInfo chain_info[] = {
1025 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR,
1026 .mem_size = sizeof(VkPhysicalDevice8BitStorageFeaturesKHR)},
1027 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR,
1028 .mem_size = sizeof(VkPhysicalDevice16BitStorageFeaturesKHR)},
1029 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR,
1030 .mem_size = sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR)},
1031 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR,
1032 .mem_size = sizeof(VkPhysicalDeviceVariablePointerFeaturesKHR)},
1033 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT,
1034 .mem_size = sizeof(VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT)},
1035 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR,
1036 .mem_size = sizeof(VkPhysicalDeviceMultiviewFeaturesKHR)},
1037 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR,
1038 .mem_size = sizeof(VkPhysicalDeviceFloat16Int8FeaturesKHR)},
1039 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR,
1040 .mem_size = sizeof(VkPhysicalDeviceShaderAtomicInt64FeaturesKHR)},
1041 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT,
1042 .mem_size = sizeof(VkPhysicalDeviceTransformFeedbackFeaturesEXT)},
1043 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT,
1044 .mem_size = sizeof(VkPhysicalDeviceScalarBlockLayoutFeaturesEXT)},
1045 {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT,
1046 .mem_size = sizeof(VkPhysicalDeviceFragmentDensityMapFeaturesEXT)}};
1048 uint32_t chain_info_len = ARRAY_SIZE(chain_info);
1050 gpu->features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
1051 buildpNextChain((struct VkStructureHeader *)&gpu->features2, chain_info, chain_info_len);
1053 inst->vkGetPhysicalDeviceFeatures2KHR(gpu->obj, &gpu->features2);
1056 AppGetPhysicalDeviceLayerExtensions(gpu, NULL, &gpu->device_extension_count, &gpu->device_extensions);
1059 static void AppGpuDestroy(struct AppGpu *gpu) {
1060 free(gpu->device_extensions);
1062 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
1063 gpu->inst->inst_extensions_count)) {
1064 freepNextChain(gpu->features2.pNext);
1067 for (uint32_t i = 0; i < gpu->queue_count; ++i) {
1068 free((void *)gpu->queue_reqs[i].pQueuePriorities);
1070 free(gpu->queue_reqs);
1072 free(gpu->queue_props);
1073 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
1074 gpu->inst->inst_extensions_count)) {
1075 free(gpu->queue_props2);
1077 freepNextChain(gpu->props2.pNext);
1081 //-----------------------------------------------------------
1083 //---------------------------Win32---------------------------
1084 #ifdef VK_USE_PLATFORM_WIN32_KHR
1086 // MS-Windows event handling function:
1087 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return (DefWindowProc(hWnd, uMsg, wParam, lParam)); }
1089 static void AppCreateWin32Window(struct AppInstance *inst) {
1090 inst->h_instance = GetModuleHandle(NULL);
1092 WNDCLASSEX win_class;
1094 // Initialize the window class structure:
1095 win_class.cbSize = sizeof(WNDCLASSEX);
1096 win_class.style = CS_HREDRAW | CS_VREDRAW;
1097 win_class.lpfnWndProc = WndProc;
1098 win_class.cbClsExtra = 0;
1099 win_class.cbWndExtra = 0;
1100 win_class.hInstance = inst->h_instance;
1101 win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
1102 win_class.hCursor = LoadCursor(NULL, IDC_ARROW);
1103 win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
1104 win_class.lpszMenuName = NULL;
1105 win_class.lpszClassName = APP_SHORT_NAME;
1106 win_class.hInstance = inst->h_instance;
1107 win_class.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
1108 // Register window class:
1109 if (!RegisterClassEx(&win_class)) {
1110 // It didn't work, so try to give a useful error:
1111 fprintf(stderr, "Failed to register the window class!\n");
1114 // Create window with the registered class:
1115 RECT wr = {0, 0, inst->width, inst->height};
1116 AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
1117 inst->h_wnd = CreateWindowEx(0,
1118 APP_SHORT_NAME, // class name
1119 APP_SHORT_NAME, // app name
1120 // WS_VISIBLE | WS_SYSMENU |
1121 WS_OVERLAPPEDWINDOW, // window style
1122 100, 100, // x/y coords
1123 wr.right - wr.left, // width
1124 wr.bottom - wr.top, // height
1125 NULL, // handle to parent
1126 NULL, // handle to menu
1127 inst->h_instance, // hInstance
1128 NULL); // no extra parameters
1130 // It didn't work, so try to give a useful error:
1131 fprintf(stderr, "Failed to create a window!\n");
1136 static void AppCreateWin32Surface(struct AppInstance *inst) {
1137 VkWin32SurfaceCreateInfoKHR createInfo;
1138 createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
1139 createInfo.pNext = NULL;
1140 createInfo.flags = 0;
1141 createInfo.hinstance = inst->h_instance;
1142 createInfo.hwnd = inst->h_wnd;
1143 VkResult err = vkCreateWin32SurfaceKHR(inst->instance, &createInfo, NULL, &inst->surface);
1144 if (err) ERR_EXIT(err);
1147 static void AppDestroyWin32Window(struct AppInstance *inst) { DestroyWindow(inst->h_wnd); }
1148 #endif // VK_USE_PLATFORM_WIN32_KHR
1149 //-----------------------------------------------------------
1151 #if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \
1152 defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_WAYLAND_KHR) || defined(VK_USE_PLATFORM_ANDROID_KHR)
1153 static void AppDestroySurface(struct AppInstance *inst) { // same for all platforms
1154 vkDestroySurfaceKHR(inst->instance, inst->surface, NULL);
1158 //----------------------------XCB----------------------------
1160 #ifdef VK_USE_PLATFORM_XCB_KHR
1161 static void AppCreateXcbWindow(struct AppInstance *inst) {
1162 //--Init Connection--
1163 const xcb_setup_t *setup;
1164 xcb_screen_iterator_t iter;
1167 // API guarantees non-null xcb_connection
1168 inst->xcb_connection = xcb_connect(NULL, &scr);
1169 int conn_error = xcb_connection_has_error(inst->xcb_connection);
1171 fprintf(stderr, "XCB failed to connect to the X server due to error:%d.\n", conn_error);
1173 inst->xcb_connection = NULL;
1176 setup = xcb_get_setup(inst->xcb_connection);
1177 iter = xcb_setup_roots_iterator(setup);
1179 xcb_screen_next(&iter);
1182 inst->xcb_screen = iter.data;
1183 //-------------------
1185 inst->xcb_window = xcb_generate_id(inst->xcb_connection);
1186 xcb_create_window(inst->xcb_connection, XCB_COPY_FROM_PARENT, inst->xcb_window, inst->xcb_screen->root, 0, 0, inst->width,
1187 inst->height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, inst->xcb_screen->root_visual, 0, NULL);
1189 xcb_intern_atom_cookie_t cookie = xcb_intern_atom(inst->xcb_connection, 1, 12, "WM_PROTOCOLS");
1190 xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(inst->xcb_connection, cookie, 0);
1194 static void AppCreateXcbSurface(struct AppInstance *inst) {
1195 if (!inst->xcb_connection) {
1199 VkXcbSurfaceCreateInfoKHR xcb_createInfo;
1200 xcb_createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
1201 xcb_createInfo.pNext = NULL;
1202 xcb_createInfo.flags = 0;
1203 xcb_createInfo.connection = inst->xcb_connection;
1204 xcb_createInfo.window = inst->xcb_window;
1205 VkResult err = vkCreateXcbSurfaceKHR(inst->instance, &xcb_createInfo, NULL, &inst->surface);
1206 if (err) ERR_EXIT(err);
1209 static void AppDestroyXcbWindow(struct AppInstance *inst) {
1210 if (!inst->xcb_connection) {
1211 return; // Nothing to destroy
1214 xcb_destroy_window(inst->xcb_connection, inst->xcb_window);
1215 xcb_disconnect(inst->xcb_connection);
1217 #endif // VK_USE_PLATFORM_XCB_KHR
1218 //-----------------------------------------------------------
1220 //----------------------------XLib---------------------------
1221 #ifdef VK_USE_PLATFORM_XLIB_KHR
1222 static void AppCreateXlibWindow(struct AppInstance *inst) {
1223 long visualMask = VisualScreenMask;
1224 int numberOfVisuals;
1226 inst->xlib_display = XOpenDisplay(NULL);
1227 if (inst->xlib_display == NULL) {
1228 fprintf(stderr, "XLib failed to connect to the X server.\nExiting ...\n");
1232 XVisualInfo vInfoTemplate = {};
1233 vInfoTemplate.screen = DefaultScreen(inst->xlib_display);
1234 XVisualInfo *visualInfo = XGetVisualInfo(inst->xlib_display, visualMask, &vInfoTemplate, &numberOfVisuals);
1235 inst->xlib_window = XCreateWindow(inst->xlib_display, RootWindow(inst->xlib_display, vInfoTemplate.screen), 0, 0, inst->width,
1236 inst->height, 0, visualInfo->depth, InputOutput, visualInfo->visual, 0, NULL);
1238 XSync(inst->xlib_display, false);
1242 static void AppCreateXlibSurface(struct AppInstance *inst) {
1243 VkXlibSurfaceCreateInfoKHR createInfo;
1244 createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
1245 createInfo.pNext = NULL;
1246 createInfo.flags = 0;
1247 createInfo.dpy = inst->xlib_display;
1248 createInfo.window = inst->xlib_window;
1249 VkResult err = vkCreateXlibSurfaceKHR(inst->instance, &createInfo, NULL, &inst->surface);
1250 if (err) ERR_EXIT(err);
1253 static void AppDestroyXlibWindow(struct AppInstance *inst) {
1254 XDestroyWindow(inst->xlib_display, inst->xlib_window);
1255 XCloseDisplay(inst->xlib_display);
1257 #endif // VK_USE_PLATFORM_XLIB_KHR
1258 //-----------------------------------------------------------
1260 #ifdef VK_USE_PLATFORM_MACOS_MVK
1262 static void AppCreateMacOSWindow(struct AppInstance *inst) {
1263 inst->window = CreateMetalView(inst->width, inst->height);
1264 if (inst->window == NULL) {
1265 fprintf(stderr, "Could not create a native Metal view.\nExiting...\n");
1270 static void AppCreateMacOSSurface(struct AppInstance *inst) {
1271 VkMacOSSurfaceCreateInfoMVK surface;
1272 surface.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
1273 surface.pNext = NULL;
1275 surface.pView = inst->window;
1277 VkResult err = vkCreateMacOSSurfaceMVK(inst->instance, &surface, NULL, &inst->surface);
1278 if (err) ERR_EXIT(err);
1281 static void AppDestroyMacOSWindow(struct AppInstance *inst) { DestroyMetalView(inst->window); }
1282 #endif // VK_USE_PLATFORM_MACOS_MVK
1283 //-----------------------------------------------------------
1285 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
1287 static void wayland_registry_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface,
1289 struct AppInstance *inst = (struct AppInstance *)data;
1290 if (strcmp(interface, "wl_compositor") == 0) {
1291 struct wl_compositor *compositor = (struct wl_compositor *)wl_registry_bind(registry, id, &wl_compositor_interface, 1);
1292 inst->wayland_surface = wl_compositor_create_surface(compositor);
1295 static void wayland_registry_global_remove(void *data, struct wl_registry *registry, uint32_t id) {}
1296 static const struct wl_registry_listener wayland_registry_listener = {wayland_registry_global, wayland_registry_global_remove};
1298 static void AppCreateWaylandWindow(struct AppInstance *inst) {
1299 inst->wayland_display = wl_display_connect(NULL);
1300 struct wl_registry *registry = wl_display_get_registry(inst->wayland_display);
1301 wl_registry_add_listener(wl_display_get_registry(inst->wayland_display), &wayland_registry_listener, inst);
1302 wl_display_roundtrip(inst->wayland_display);
1303 wl_registry_destroy(registry);
1306 static void AppCreateWaylandSurface(struct AppInstance *inst) {
1307 VkWaylandSurfaceCreateInfoKHR createInfo;
1308 createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
1309 createInfo.pNext = NULL;
1310 createInfo.flags = 0;
1311 createInfo.display = inst->wayland_display;
1312 createInfo.surface = inst->wayland_surface;
1313 VkResult err = vkCreateWaylandSurfaceKHR(inst->instance, &createInfo, NULL, &inst->surface);
1314 if (err) ERR_EXIT(err);
1317 static void AppDestroyWaylandWindow(struct AppInstance *inst) { wl_display_disconnect(inst->wayland_display); }
1318 #endif // VK_USE_PLATFORM_WAYLAND_KHR
1320 #if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \
1321 defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_WAYLAND_KHR)
1322 static int AppDumpSurfaceFormats(struct AppInstance *inst, struct AppGpu *gpu, FILE *out) {
1323 // Get the list of VkFormat's that are supported
1325 uint32_t format_count = 0;
1326 VkSurfaceFormatKHR *surf_formats = NULL;
1327 VkSurfaceFormat2KHR *surf_formats2 = NULL;
1329 const VkPhysicalDeviceSurfaceInfo2KHR surface_info2 = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR,
1330 .surface = inst->surface};
1332 if (CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
1333 gpu->inst->inst_extensions_count)) {
1334 err = inst->vkGetPhysicalDeviceSurfaceFormats2KHR(gpu->obj, &surface_info2, &format_count, NULL);
1335 if (err) ERR_EXIT(err);
1336 surf_formats2 = (VkSurfaceFormat2KHR *)malloc(format_count * sizeof(VkSurfaceFormat2KHR));
1337 if (!surf_formats2) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
1338 for (uint32_t i = 0; i < format_count; ++i) {
1339 surf_formats2[i].sType = VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR;
1340 surf_formats2[i].pNext = NULL;
1342 err = inst->vkGetPhysicalDeviceSurfaceFormats2KHR(gpu->obj, &surface_info2, &format_count, surf_formats2);
1343 if (err) ERR_EXIT(err);
1345 err = inst->vkGetPhysicalDeviceSurfaceFormatsKHR(gpu->obj, inst->surface, &format_count, NULL);
1346 if (err) ERR_EXIT(err);
1347 surf_formats = (VkSurfaceFormatKHR *)malloc(format_count * sizeof(VkSurfaceFormatKHR));
1348 if (!surf_formats) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
1349 err = inst->vkGetPhysicalDeviceSurfaceFormatsKHR(gpu->obj, inst->surface, &format_count, surf_formats);
1350 if (err) ERR_EXIT(err);
1354 fprintf(out, "\t\t\t\t\t<details><summary>Formats: count = <div class='val'>%d</div></summary>", format_count);
1355 if (format_count > 0) {
1358 fprintf(out, "</details>\n");
1360 } else if (human_readable_output) {
1361 printf("Formats:\t\tcount = %d\n", format_count);
1363 for (uint32_t i = 0; i < format_count; ++i) {
1365 if (CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
1366 gpu->inst->inst_extensions_count)) {
1367 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>%s</div></summary></details>\n",
1368 VkFormatString(surf_formats2[i].surfaceFormat.format));
1370 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>%s</div></summary></details>\n",
1371 VkFormatString(surf_formats[i].format));
1373 } else if (human_readable_output) {
1374 if (CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
1375 gpu->inst->inst_extensions_count)) {
1376 printf("\t%s\n", VkFormatString(surf_formats2[i].surfaceFormat.format));
1378 printf("\t%s\n", VkFormatString(surf_formats[i].format));
1382 if (format_count > 0 && html_output) {
1383 fprintf(out, "\t\t\t\t\t</details>\n");
1388 if (CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
1389 gpu->inst->inst_extensions_count)) {
1390 free(surf_formats2);
1395 return format_count;
1398 static int AppDumpSurfacePresentModes(struct AppInstance *inst, struct AppGpu *gpu, FILE *out) {
1399 // Get the list of VkPresentMode's that are supported:
1401 uint32_t present_mode_count = 0;
1402 err = inst->vkGetPhysicalDeviceSurfacePresentModesKHR(gpu->obj, inst->surface, &present_mode_count, NULL);
1403 if (err) ERR_EXIT(err);
1405 VkPresentModeKHR *surf_present_modes = (VkPresentModeKHR *)malloc(present_mode_count * sizeof(VkPresentInfoKHR));
1406 if (!surf_present_modes) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
1407 err = inst->vkGetPhysicalDeviceSurfacePresentModesKHR(gpu->obj, inst->surface, &present_mode_count, surf_present_modes);
1408 if (err) ERR_EXIT(err);
1411 fprintf(out, "\t\t\t\t\t<details><summary>Present Modes: count = <div class='val'>%d</div></summary>", present_mode_count);
1412 if (present_mode_count > 0) {
1415 fprintf(out, "</details>");
1417 } else if (human_readable_output) {
1418 printf("Present Modes:\t\tcount = %d\n", present_mode_count);
1420 for (uint32_t i = 0; i < present_mode_count; ++i) {
1422 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>%s</div></summary></details>\n",
1423 VkPresentModeString(surf_present_modes[i]));
1424 } else if (human_readable_output) {
1425 printf("\t%s\n", VkPresentModeString(surf_present_modes[i]));
1428 if (present_mode_count > 0 && html_output) {
1429 fprintf(out, "\t\t\t\t\t</details>\n");
1434 free(surf_present_modes);
1436 return present_mode_count;
1439 static void AppDumpSurfaceCapabilities(struct AppInstance *inst, struct AppGpu *gpu, FILE *out) {
1440 if (CheckExtensionEnabled(VK_KHR_SURFACE_EXTENSION_NAME, gpu->inst->inst_extensions, gpu->inst->inst_extensions_count)) {
1442 err = inst->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu->obj, inst->surface, &inst->surface_capabilities);
1443 if (err) ERR_EXIT(err);
1446 fprintf(out, "\t\t\t\t\t<details><summary>VkSurfaceCapabilitiesKHR</summary>\n");
1447 fprintf(out, "\t\t\t\t\t\t<details><summary>minImageCount = <div class='val'>%u</div></summary></details>\n",
1448 inst->surface_capabilities.minImageCount);
1449 fprintf(out, "\t\t\t\t\t\t<details><summary>maxImageCount = <div class='val'>%u</div></summary></details>\n",
1450 inst->surface_capabilities.maxImageCount);
1451 fprintf(out, "\t\t\t\t\t\t<details><summary>currentExtent</summary>\n");
1452 fprintf(out, "\t\t\t\t\t\t\t<details><summary>width = <div class='val'>%u</div></summary></details>\n",
1453 inst->surface_capabilities.currentExtent.width);
1454 fprintf(out, "\t\t\t\t\t\t\t<details><summary>height = <div class='val'>%u</div></summary></details>\n",
1455 inst->surface_capabilities.currentExtent.height);
1456 fprintf(out, "\t\t\t\t\t\t</details>\n");
1457 fprintf(out, "\t\t\t\t\t\t<details><summary>minImageExtent</summary>\n");
1458 fprintf(out, "\t\t\t\t\t\t\t<details><summary>width = <div class='val'>%u</div></summary></details>\n",
1459 inst->surface_capabilities.minImageExtent.width);
1460 fprintf(out, "\t\t\t\t\t\t\t<details><summary>height = <div class='val'>%u</div></summary></details>\n",
1461 inst->surface_capabilities.minImageExtent.height);
1462 fprintf(out, "\t\t\t\t\t\t</details>\n");
1463 fprintf(out, "\t\t\t\t\t\t<details><summary>maxImageExtent</summary>\n");
1464 fprintf(out, "\t\t\t\t\t\t\t<details><summary>width = <div class='val'>%u</div></summary></details>\n",
1465 inst->surface_capabilities.maxImageExtent.width);
1466 fprintf(out, "\t\t\t\t\t\t\t<details><summary>height = <div class='val'>%u</div></summary></details>\n",
1467 inst->surface_capabilities.maxImageExtent.height);
1468 fprintf(out, "\t\t\t\t\t\t</details>\n");
1469 fprintf(out, "\t\t\t\t\t\t<details><summary>maxImageArrayLayers = <div class='val'>%u</div></summary></details>\n",
1470 inst->surface_capabilities.maxImageArrayLayers);
1471 fprintf(out, "\t\t\t\t\t\t<details><summary>supportedTransform</summary>\n");
1472 if (inst->surface_capabilities.supportedTransforms == 0) {
1473 fprintf(out, "\t\t\t\t\t\t\t<details><summary>None</summary></details>\n");
1475 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
1477 "\t\t\t\t\t\t\t<details><summary><div "
1478 "class='type'>VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR</div></summary></details>\n");
1480 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR) {
1482 "\t\t\t\t\t\t\t\t<details><summary><div "
1483 "class='type'>VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR</div></summary></details>\n");
1485 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR) {
1487 "\t\t\t\t\t\t\t\t<details><summary><div "
1488 "class='type'>VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR</div></summary></details>\n");
1490 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) {
1492 "\t\t\t\t\t\t\t\t<details><summary><div "
1493 "class='type'>VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR</div></summary></details>\n");
1495 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR) {
1497 "\t\t\t\t\t\t\t\t<details><summary><div "
1498 "class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR</div></summary></details>\n");
1500 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR) {
1502 "\t\t\t\t\t\t\t\t<details><summary><div "
1503 "class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR</div></summary></details>\n");
1505 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR) {
1507 "\t\t\t\t\t\t\t\t<details><summary><div "
1508 "class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR</div></summary></details>\n");
1510 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR) {
1512 "\t\t\t\t\t\t\t\t<details><summary><div "
1513 "class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR</div></summary></details>\n");
1515 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR) {
1517 "\t\t\t\t\t\t\t\t<details><summary><div "
1518 "class='type'>VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR</div></summary></details>\n");
1520 fprintf(out, "\t\t\t\t\t\t</details>\n");
1521 fprintf(out, "\t\t\t\t\t\t<details><summary>currentTransform</summary>\n");
1522 if (inst->surface_capabilities.currentTransform == 0) {
1523 fprintf(out, "\t\t\t\t\t\t\t<details><summary>None</summary></details>\n");
1525 if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
1527 "\t\t\t\t\t\t\t<details><summary><div "
1528 "class='type'>VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR</div></summary></details>\n");
1529 } else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR) {
1531 "\t\t\t\t\t\t\t<details><summary><div "
1532 "class='type'>VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR</div></summary></details>\n");
1533 } else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR) {
1535 "\t\t\t\t\t\t\t<details><summary><div "
1536 "class='type'>VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR</div></summary></details>\n");
1537 } else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) {
1539 "\t\t\t\t\t\t\t<details><summary><div "
1540 "class='type'>VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR</div></summary></details>\n");
1541 } else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR) {
1543 "\t\t\t\t\t\t\t<details><summary><div "
1544 "class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR</div></summary></details>\n");
1545 } else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR) {
1547 "\t\t\t\t\t\t<details><summary><div "
1548 "class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR</div></summary></details>\n");
1549 } else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR) {
1551 "\t\t\t\t\t\t\t<details><summary><div "
1552 "class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR</div></summary></details>\n");
1553 } else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR) {
1555 "\t\t\t\t\t\t\t<details><summary><div "
1556 "class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR</div></summary></details>\n");
1557 } else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR) {
1559 "\t\t\t\t\t\t\t<details><summary><div "
1560 "class='type'>VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR</div></summary></details>\n");
1562 fprintf(out, "\t\t\t\t\t\t</details>\n");
1563 fprintf(out, "\t\t\t\t\t\t<details><summary>supportedCompositeAlpha</summary>\n");
1564 if (inst->surface_capabilities.supportedCompositeAlpha == 0) {
1565 fprintf(out, "\t\t\t\t\t\t\t<details><summary>None</summary></details>\n");
1567 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) {
1569 "\t\t\t\t\t\t\t<details><summary><div "
1570 "class='type'>VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR</div></summary></details>\n");
1572 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR) {
1574 "\t\t\t\t\t\t\t<details><summary><div "
1575 "class='type'>VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR</div></summary></details>\n");
1577 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR) {
1579 "\t\t\t\t\t\t\t<details><summary><div "
1580 "class='type'>VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR</div></summary></details>\n");
1582 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) {
1584 "\t\t\t\t\t\t\t<details><summary><div "
1585 "class='type'>VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR</div></summary></details>\n");
1587 fprintf(out, "\t\t\t\t\t\t</details>\n");
1588 fprintf(out, "\t\t\t\t\t\t<details><summary>supportedUsageFlags</summary>\n");
1589 if (inst->surface_capabilities.supportedUsageFlags == 0) {
1590 fprintf(out, "\t\t\t\t\t\t\t<details><summary>None</summary></details>\n");
1592 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
1594 "\t\t\t\t\t\t\t<details><summary><div "
1595 "class='type'>VK_IMAGE_USAGE_TRANSFER_SRC_BIT</div></summary></details>\n");
1597 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
1599 "\t\t\t\t\t\t\t<details><summary><div "
1600 "class='type'>VK_IMAGE_USAGE_TRANSFER_DST_BIT</div></summary></details>\n");
1602 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) {
1604 "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_IMAGE_USAGE_SAMPLED_BIT</div></summary></details>\n");
1606 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT) {
1608 "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_IMAGE_USAGE_STORAGE_BIT</div></summary></details>\n");
1610 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
1612 "\t\t\t\t\t\t\t<details><summary><div "
1613 "class='type'>VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT</div></summary></details>\n");
1615 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
1617 "\t\t\t\t\t\t\t<details><summary><div "
1618 "class='type'>VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT</div></summary></details>\n");
1620 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) {
1622 "\t\t\t\t\t\t\t<details><summary><div "
1623 "class='type'>VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT</div></summary></details>\n");
1625 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
1627 "\t\t\t\t\t\t\t<details><summary><div "
1628 "class='type'>VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT</div></summary></details>\n");
1630 fprintf(out, "\t\t\t\t\t\t</details>\n");
1631 } else if (human_readable_output) {
1632 printf("VkSurfaceCapabilitiesKHR:\n");
1633 printf("\tminImageCount = %u\n", inst->surface_capabilities.minImageCount);
1634 printf("\tmaxImageCount = %u\n", inst->surface_capabilities.maxImageCount);
1635 printf("\tcurrentExtent:\n");
1636 printf("\t\twidth = %u\n", inst->surface_capabilities.currentExtent.width);
1637 printf("\t\theight = %u\n", inst->surface_capabilities.currentExtent.height);
1638 printf("\tminImageExtent:\n");
1639 printf("\t\twidth = %u\n", inst->surface_capabilities.minImageExtent.width);
1640 printf("\t\theight = %u\n", inst->surface_capabilities.minImageExtent.height);
1641 printf("\tmaxImageExtent:\n");
1642 printf("\t\twidth = %u\n", inst->surface_capabilities.maxImageExtent.width);
1643 printf("\t\theight = %u\n", inst->surface_capabilities.maxImageExtent.height);
1644 printf("\tmaxImageArrayLayers = %u\n", inst->surface_capabilities.maxImageArrayLayers);
1645 printf("\tsupportedTransform:\n");
1646 if (inst->surface_capabilities.supportedTransforms == 0) {
1647 printf("\t\tNone\n");
1649 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
1650 printf("\t\tVK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR\n");
1652 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR) {
1653 printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR\n");
1655 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR) {
1656 printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR\n");
1658 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) {
1659 printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR\n");
1661 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR) {
1662 printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR\n");
1664 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR) {
1665 printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR\n");
1667 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR) {
1668 printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR\n");
1670 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR) {
1671 printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR\n");
1673 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR) {
1674 printf("\t\tVK_SURFACE_TRANSFORM_INHERIT_BIT_KHR\n");
1676 printf("\tcurrentTransform:\n");
1677 if (inst->surface_capabilities.currentTransform == 0) {
1678 printf("\t\tNone\n");
1680 if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
1681 printf("\t\tVK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR\n");
1682 } else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR) {
1683 printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR\n");
1684 } else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR) {
1685 printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR\n");
1686 } else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) {
1687 printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR\n");
1688 } else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR) {
1689 printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR\n");
1690 } else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR) {
1691 printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR\n");
1692 } else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR) {
1693 printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR\n");
1694 } else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR) {
1695 printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR\n");
1696 } else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR) {
1697 printf("\t\tVK_SURFACE_TRANSFORM_INHERIT_BIT_KHR\n");
1699 printf("\tsupportedCompositeAlpha:\n");
1700 if (inst->surface_capabilities.supportedCompositeAlpha == 0) {
1701 printf("\t\tNone\n");
1703 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) {
1704 printf("\t\tVK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR\n");
1706 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR) {
1707 printf("\t\tVK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR\n");
1709 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR) {
1710 printf("\t\tVK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR\n");
1712 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) {
1713 printf("\t\tVK_COMPOSITE_ALPHA_INHERIT_BIT_KHR\n");
1715 printf("\tsupportedUsageFlags:\n");
1716 if (inst->surface_capabilities.supportedUsageFlags == 0) {
1717 printf("\t\tNone\n");
1719 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
1720 printf("\t\tVK_IMAGE_USAGE_TRANSFER_SRC_BIT\n");
1722 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
1723 printf("\t\tVK_IMAGE_USAGE_TRANSFER_DST_BIT\n");
1725 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) {
1726 printf("\t\tVK_IMAGE_USAGE_SAMPLED_BIT\n");
1728 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT) {
1729 printf("\t\tVK_IMAGE_USAGE_STORAGE_BIT\n");
1731 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
1732 printf("\t\tVK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT\n");
1734 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
1735 printf("\t\tVK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT\n");
1737 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) {
1738 printf("\t\tVK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT\n");
1740 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
1741 printf("\t\tVK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT\n");
1745 // Get additional surface capability information from vkGetPhysicalDeviceSurfaceCapabilities2EXT
1746 if (CheckExtensionEnabled(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME, gpu->inst->inst_extensions,
1747 gpu->inst->inst_extensions_count)) {
1748 memset(&inst->surface_capabilities2_ext, 0, sizeof(VkSurfaceCapabilities2EXT));
1749 inst->surface_capabilities2_ext.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT;
1750 inst->surface_capabilities2_ext.pNext = NULL;
1752 err = inst->vkGetPhysicalDeviceSurfaceCapabilities2EXT(gpu->obj, inst->surface, &inst->surface_capabilities2_ext);
1753 if (err) ERR_EXIT(err);
1756 fprintf(out, "\t\t\t\t\t\t<details><summary>VkSurfaceCapabilities2EXT</summary>\n");
1757 fprintf(out, "\t\t\t\t\t\t\t<details><summary>supportedSurfaceCounters</summary>\n");
1758 if (inst->surface_capabilities2_ext.supportedSurfaceCounters == 0) {
1759 fprintf(out, "\t\t\t\t\t\t\t\t<details><summary>None</summary></details>\n");
1761 if (inst->surface_capabilities2_ext.supportedSurfaceCounters & VK_SURFACE_COUNTER_VBLANK_EXT) {
1763 "\t\t\t\t\t\t\t\t<details><summary><div "
1764 "class='type'>VK_SURFACE_COUNTER_VBLANK_EXT</div></summary></details>\n");
1766 fprintf(out, "\t\t\t\t\t\t\t</details>\n");
1767 fprintf(out, "\t\t\t\t\t\t</details>\n");
1768 } else if (human_readable_output) {
1769 printf("VkSurfaceCapabilities2EXT:\n");
1770 printf("\tsupportedSurfaceCounters:\n");
1771 if (inst->surface_capabilities2_ext.supportedSurfaceCounters == 0) {
1772 printf("\t\tNone\n");
1774 if (inst->surface_capabilities2_ext.supportedSurfaceCounters & VK_SURFACE_COUNTER_VBLANK_EXT) {
1775 printf("\t\tVK_SURFACE_COUNTER_VBLANK_EXT\n");
1780 // Get additional surface capability information from vkGetPhysicalDeviceSurfaceCapabilities2KHR
1781 if (CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
1782 gpu->inst->inst_extensions_count)) {
1783 if (CheckExtensionEnabled(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, gpu->inst->inst_extensions,
1784 gpu->inst->inst_extensions_count)) {
1785 inst->shared_surface_capabilities.sType = VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR;
1786 inst->shared_surface_capabilities.pNext = NULL;
1787 inst->surface_capabilities2.pNext = &inst->shared_surface_capabilities;
1789 inst->surface_capabilities2.pNext = NULL;
1792 inst->surface_capabilities2.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR;
1794 VkPhysicalDeviceSurfaceInfo2KHR surface_info;
1795 surface_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR;
1796 surface_info.pNext = NULL;
1797 surface_info.surface = inst->surface;
1799 err = inst->vkGetPhysicalDeviceSurfaceCapabilities2KHR(gpu->obj, &surface_info, &inst->surface_capabilities2);
1800 if (err) ERR_EXIT(err);
1802 void *place = inst->surface_capabilities2.pNext;
1804 struct VkStructureHeader *work = (struct VkStructureHeader *)place;
1805 if (work->sType == VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR) {
1806 VkSharedPresentSurfaceCapabilitiesKHR *shared_surface_capabilities =
1807 (VkSharedPresentSurfaceCapabilitiesKHR *)place;
1809 fprintf(out, "\t\t\t\t\t\t<details><summary>VkSharedPresentSurfaceCapabilitiesKHR</summary>\n");
1810 fprintf(out, "\t\t\t\t\t\t\t<details><summary>sharedPresentSupportedUsageFlags</summary>\n");
1811 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags == 0) {
1812 fprintf(out, "\t\t\t\t\t\t\t\t<details><summary>None</summary></details>\n");
1814 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
1816 "\t\t\t\t\t\t\t\t<details><summary><div "
1817 "class='type'>VK_IMAGE_USAGE_TRANSFER_SRC_BIT</div></summary></details>\n");
1819 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
1821 "\t\t\t\t\t\t\t\t<details><summary><div "
1822 "class='type'>VK_IMAGE_USAGE_TRANSFER_DST_BIT</div></summary></details>\n");
1824 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) {
1826 "\t\t\t\t\t\t\t\t<details><summary><div "
1827 "class='type'>VK_IMAGE_USAGE_SAMPLED_BIT</div></summary></details>\n");
1829 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT) {
1831 "\t\t\t\t\t\t\t\t<details><summary><div "
1832 "class='type'>VK_IMAGE_USAGE_STORAGE_BIT</div></summary></details>\n");
1834 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
1836 "\t\t\t\t\t\t\t\t<details><summary><div "
1837 "class='type'>VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT</div></summary></details>\n");
1839 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags &
1840 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
1842 "\t\t\t\t\t\t\t\t<details><summary><div "
1843 "class='type'>VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT</div></summary></details>\n");
1845 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags &
1846 VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) {
1848 "\t\t\t\t\t\t\t\t<details><summary><div "
1849 "class='type'>VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT</div></summary></details>\n");
1851 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
1853 "\t\t\t\t\t\t\t\t<details><summary><div "
1854 "class='type'>VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT</div></summary></details>\n");
1856 fprintf(out, "\t\t\t\t\t\t\t</details>\n");
1857 fprintf(out, "\t\t\t\t\t\t</details>\n");
1858 } else if (human_readable_output) {
1859 printf("VkSharedPresentSurfaceCapabilitiesKHR:\n");
1860 printf("\tsharedPresentSupportedUsageFlags:\n");
1861 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags == 0) {
1862 printf("\t\tNone\n");
1864 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
1865 printf("\t\tVK_IMAGE_USAGE_TRANSFER_SRC_BIT\n");
1867 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
1868 printf("\t\tVK_IMAGE_USAGE_TRANSFER_DST_BIT\n");
1870 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) {
1871 printf("\t\tVK_IMAGE_USAGE_SAMPLED_BIT\n");
1873 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT) {
1874 printf("\t\tVK_IMAGE_USAGE_STORAGE_BIT\n");
1876 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
1877 printf("\t\tVK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT\n");
1879 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags &
1880 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
1881 printf("\t\tVK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT\n");
1883 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags &
1884 VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) {
1885 printf("\t\tVK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT\n");
1887 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
1888 printf("\t\tVK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT\n");
1892 place = work->pNext;
1896 fprintf(out, "\t\t\t\t\t</details>\n");
1901 struct SurfaceExtensionInfo {
1903 void (*create_window)(struct AppInstance *);
1904 void (*create_surface)(struct AppInstance *);
1905 void (*destroy_window)(struct AppInstance *);
1908 static void AppDumpSurfaceExtension(struct AppInstance *inst, struct AppGpu *gpus, uint32_t gpu_count,
1909 struct SurfaceExtensionInfo *surface_extension, int *format_count, int *present_mode_count,
1911 if (!CheckExtensionEnabled(surface_extension->name, inst->inst_extensions, inst->inst_extensions_count)) {
1915 surface_extension->create_window(inst);
1916 for (uint32_t i = 0; i < gpu_count; ++i) {
1917 surface_extension->create_surface(inst);
1919 fprintf(out, "\t\t\t\t<details><summary>GPU id : <div class='val'>%u</div> (%s)</summary>\n", i,
1920 gpus[i].props.deviceName);
1921 fprintf(out, "\t\t\t\t\t<details><summary>Surface type : <div class='type'>%s</div></summary></details>\n",
1922 surface_extension->name);
1923 } else if (human_readable_output) {
1924 printf("GPU id : %u (%s)\n", i, gpus[i].props.deviceName);
1925 printf("Surface type : %s\n", surface_extension->name);
1927 *format_count += AppDumpSurfaceFormats(inst, &gpus[i], out);
1928 *present_mode_count += AppDumpSurfacePresentModes(inst, &gpus[i], out);
1929 AppDumpSurfaceCapabilities(inst, &gpus[i], out);
1932 fprintf(out, "\t\t\t\t</details>\n");
1933 } else if (human_readable_output) {
1937 surface_extension->destroy_window(inst);
1942 static void AppDevDumpFormatProps(const struct AppGpu *gpu, VkFormat fmt, bool *first_in_list, FILE *out) {
1943 VkFormatProperties props;
1944 vkGetPhysicalDeviceFormatProperties(gpu->obj, fmt, &props);
1950 features[0].name = "linearTiling FormatFeatureFlags";
1951 features[0].flags = props.linearTilingFeatures;
1952 features[1].name = "optimalTiling FormatFeatureFlags";
1953 features[1].flags = props.optimalTilingFeatures;
1954 features[2].name = "bufferFeatures FormatFeatureFlags";
1955 features[2].flags = props.bufferFeatures;
1958 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>FORMAT_%s</div></summary>\n", VkFormatString(fmt));
1959 } else if (human_readable_output) {
1960 printf("\nFORMAT_%s:", VkFormatString(fmt));
1962 for (uint32_t i = 0; i < ARRAY_SIZE(features); ++i) {
1964 fprintf(out, "\t\t\t\t\t\t\t<details open><summary>%s</summary>\n", features[i].name);
1965 if (features[i].flags == 0) {
1966 fprintf(out, "\t\t\t\t\t\t\t\t<details><summary>None</summary></details>\n");
1968 fprintf(out, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
1969 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div "
1970 "class='type'>VK_FORMAT_FEATURE_SAMPLED_IMAGE_"
1971 "BIT</div></summary></details>\n"
1973 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div "
1974 "class='type'>VK_FORMAT_FEATURE_STORAGE_IMAGE_"
1975 "BIT</div></summary></details>\n"
1977 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT)
1978 ? "\t\t\t\t\t\t\t\t<details><summary><div "
1979 "class='type'>VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT</div></summary></details>\n"
1981 ((features[i].flags & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)
1982 ? "\t\t\t\t\t\t\t\t<details><summary><div "
1983 "class='type'>VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT</div></summary></details>\n"
1985 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)
1986 ? "\t\t\t\t\t\t\t\t<details><summary><div "
1987 "class='type'>VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT</div></summary></details>\n"
1989 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT)
1990 ? "\t\t\t\t\t\t\t\t<details><summary><div "
1991 "class='type'>VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT</div></summary></details>\n"
1993 ((features[i].flags & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div "
1994 "class='type'>VK_FORMAT_FEATURE_VERTEX_BUFFER_"
1995 "BIT</div></summary></details>\n"
1997 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div "
1998 "class='type'>VK_FORMAT_FEATURE_COLOR_"
1999 "ATTACHMENT_BIT</div></summary></details>\n"
2001 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT)
2002 ? "\t\t\t\t\t\t\t\t<details><summary><div "
2003 "class='type'>VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT</div></summary></details>\n"
2005 ((features[i].flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
2006 ? "\t\t\t\t\t\t\t\t<details><summary><div "
2007 "class='type'>VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT</div></summary></details>\n"
2009 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_SRC_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div "
2010 "class='type'>VK_FORMAT_FEATURE_BLIT_SRC_BIT</"
2011 "div></summary></details>\n"
2013 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_DST_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div "
2014 "class='type'>VK_FORMAT_FEATURE_BLIT_DST_BIT</"
2015 "div></summary></details>\n"
2017 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)
2018 ? "\t\t\t\t\t\t\t\t<details><summary><div "
2019 "class='type'>VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT</div></summary></details>\n"
2021 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG)
2022 ? "\t\t\t\t\t\t\t\t<details><summary><div "
2023 "class='type'>VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG</div></summary></details>\n"
2025 ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR) ? "\t\t\t\t\t\t\t\t<details><summary><div "
2026 "class='type'>VK_FORMAT_FEATURE_TRANSFER_"
2027 "SRC_BIT_KHR</div></summary></details>\n"
2029 ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR) ? "\t\t\t\t\t\t\t\t<details><summary><div "
2030 "class='type'>VK_FORMAT_FEATURE_TRANSFER_"
2031 "DST_BIT_KHR</div></summary></details>\n"
2034 fprintf(out, "\t\t\t\t\t\t\t</details>\n");
2035 } else if (human_readable_output) {
2036 printf("\n\t%s:", features[i].name);
2037 if (features[i].flags == 0) {
2038 printf("\n\t\tNone");
2041 "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
2042 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT"
2044 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_BIT"
2046 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT)
2047 ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT"
2049 ((features[i].flags & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)
2050 ? "\n\t\tVK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT"
2052 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)
2053 ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT"
2055 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT)
2056 ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT"
2058 ((features[i].flags & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_VERTEX_BUFFER_BIT"
2060 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT"
2062 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT)
2063 ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT"
2065 ((features[i].flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
2066 ? "\n\t\tVK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT"
2068 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_SRC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_SRC_BIT" : ""), // 0x0400
2069 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_DST_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_DST_BIT" : ""), // 0x0800
2070 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)
2071 ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT"
2073 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG)
2074 ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG"
2076 ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR) ? "\n\t\tVK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR"
2078 ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR) ? "\n\t\tVK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR"
2084 fprintf(out, "\t\t\t\t\t\t</details>\n");
2085 } else if (human_readable_output) {
2088 if (json_output && (props.linearTilingFeatures || props.optimalTilingFeatures || props.bufferFeatures)) {
2089 if (!(*first_in_list)) {
2092 *first_in_list = false;
2096 printf("\t\t\t\"formatID\": %d,\n", fmt);
2097 printf("\t\t\t\"linearTilingFeatures\": %u,\n", props.linearTilingFeatures);
2098 printf("\t\t\t\"optimalTilingFeatures\": %u,\n", props.optimalTilingFeatures);
2099 printf("\t\t\t\"bufferFeatures\": %u\n", props.bufferFeatures);
2104 /* This structure encodes all the format ranges to be queried.
2105 * It ensures that a format is not queried if the instance
2106 * doesn't support it (either through the instance version or
2107 * through extensions).
2109 static struct FormatRange {
2110 // the Vulkan standard version that supports this format range, or 0 if non-standard
2111 uint32_t minimum_instance_version;
2113 // The name of the extension that supports this format range, or NULL if the range
2114 // is only part of the standard
2115 char *extension_name;
2117 // The first and last supported formats within this range.
2118 VkFormat first_format;
2119 VkFormat last_format;
2120 } supported_format_ranges[] = {
2122 // Standard formats in Vulkan 1.0
2123 VK_MAKE_VERSION(1, 0, 0),
2125 VK_FORMAT_BEGIN_RANGE,
2126 VK_FORMAT_END_RANGE,
2129 // YCBCR extension, standard in Vulkan 1.1
2130 VK_MAKE_VERSION(1, 1, 0),
2131 VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME,
2132 VK_FORMAT_G8B8G8R8_422_UNORM,
2133 VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,
2136 // PVRTC extension, not standardized
2138 VK_IMG_FORMAT_PVRTC_EXTENSION_NAME,
2139 VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG,
2140 VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG,
2144 // Helper function to determine whether a format range is currently supported.
2145 bool FormatRangeSupported(const struct FormatRange *format_range, const struct AppGpu *gpu) {
2146 // True if standard and supported by both this instance and this GPU
2147 if (format_range->minimum_instance_version > 0 && gpu->inst->instance_version >= format_range->minimum_instance_version &&
2148 gpu->props.apiVersion >= format_range->minimum_instance_version) {
2152 // True if this extension is present
2153 if (format_range->extension_name != NULL) {
2154 return CheckExtensionEnabled(format_range->extension_name, gpu->inst->inst_extensions, gpu->inst->inst_extensions_count);
2157 // Otherwise, not supported.
2161 bool FormatPropsEq(const VkFormatProperties *props1, const VkFormatProperties *props2) {
2162 if (props1->bufferFeatures == props2->bufferFeatures && props1->linearTilingFeatures == props2->linearTilingFeatures &&
2163 props1->optimalTilingFeatures == props2->optimalTilingFeatures) {
2170 struct PropFormats {
2171 VkFormatProperties props;
2173 uint32_t format_count;
2174 uint32_t format_reserve;
2178 void FormatPropsShortenedDump(const struct AppGpu *gpu) {
2179 const VkFormatProperties unsupported_prop = {0};
2180 uint32_t unique_props_count = 1;
2181 uint32_t unique_props_reserve = 50;
2182 struct PropFormats *prop_map = malloc(sizeof(struct PropFormats) * unique_props_reserve);
2183 if (!prop_map) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
2184 prop_map[0].props = unsupported_prop;
2185 prop_map[0].format_count = 0;
2186 prop_map[0].format_reserve = 20;
2187 prop_map[0].formats = malloc(sizeof(VkFormat) * prop_map[0].format_reserve);
2188 if (!prop_map[0].formats) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
2190 for (uint32_t ri = 0; ri < ARRAY_SIZE(supported_format_ranges); ++ri) {
2191 struct FormatRange format_range = supported_format_ranges[ri];
2192 if (FormatRangeSupported(&format_range, gpu)) {
2193 for (VkFormat fmt = format_range.first_format; fmt <= format_range.last_format; ++fmt) {
2194 VkFormatProperties props;
2195 vkGetPhysicalDeviceFormatProperties(gpu->obj, fmt, &props);
2197 uint32_t formats_prop_i = 0;
2198 for (; formats_prop_i < unique_props_count; ++formats_prop_i) {
2199 if (FormatPropsEq(&prop_map[formats_prop_i].props, &props)) break;
2202 if (formats_prop_i < unique_props_count) {
2203 struct PropFormats *propFormats = &prop_map[formats_prop_i];
2204 ++propFormats->format_count;
2206 if (propFormats->format_count > propFormats->format_reserve) {
2207 propFormats->format_reserve *= 2;
2208 propFormats->formats = realloc(propFormats->formats, sizeof(VkFormat) * propFormats->format_reserve);
2209 if (!propFormats->formats) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
2212 propFormats->formats[propFormats->format_count - 1] = fmt;
2214 assert(formats_prop_i == unique_props_count);
2215 ++unique_props_count;
2217 if (unique_props_count > unique_props_reserve) {
2218 unique_props_reserve *= 2;
2219 prop_map = realloc(prop_map, sizeof(struct PropFormats) * unique_props_reserve);
2220 if (!prop_map) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
2223 struct PropFormats *propFormats = &prop_map[formats_prop_i];
2224 propFormats->props = props;
2225 propFormats->format_count = 1;
2226 propFormats->format_reserve = 20;
2227 propFormats->formats = malloc(sizeof(VkFormat) * propFormats->format_reserve);
2228 if (!propFormats->formats) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
2229 propFormats->formats[0] = fmt;
2235 for (uint32_t pi = 1; pi < unique_props_count; ++pi) {
2236 struct PropFormats *propFormats = &prop_map[pi];
2238 for (uint32_t fi = 0; fi < propFormats->format_count; ++fi) {
2239 const VkFormat fmt = propFormats->formats[fi];
2241 printf("\nFORMAT_%s", VkFormatString(fmt));
2243 if (fi < propFormats->format_count - 1)
2254 features[0].name = "linearTiling FormatFeatureFlags";
2255 features[0].flags = propFormats->props.linearTilingFeatures;
2256 features[1].name = "optimalTiling FormatFeatureFlags";
2257 features[1].flags = propFormats->props.optimalTilingFeatures;
2258 features[2].name = "bufferFeatures FormatFeatureFlags";
2259 features[2].flags = propFormats->props.bufferFeatures;
2261 for (uint32_t i = 0; i < ARRAY_SIZE(features); ++i) {
2262 printf("\n\t%s:", features[i].name);
2263 if (features[i].flags == 0) {
2264 printf("\n\t\tNone");
2267 "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
2268 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT"
2270 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_BIT"
2272 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT)
2273 ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT"
2275 ((features[i].flags & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)
2276 ? "\n\t\tVK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT"
2278 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)
2279 ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT"
2281 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT)
2282 ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT"
2284 ((features[i].flags & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_VERTEX_BUFFER_BIT"
2286 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT"
2288 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT)
2289 ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT"
2291 ((features[i].flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
2292 ? "\n\t\tVK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT"
2294 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_SRC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_SRC_BIT" : ""), // 0x0400
2295 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_DST_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_DST_BIT" : ""), // 0x0800
2296 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)
2297 ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT"
2299 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG)
2300 ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG"
2302 ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR) ? "\n\t\tVK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR"
2304 ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR) ? "\n\t\tVK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR"
2312 printf("\nUnsupported formats:");
2313 if (prop_map[0].format_count == 0) printf("\nNone");
2314 for (uint32_t fi = 0; fi < prop_map[0].format_count; ++fi) {
2315 const VkFormat fmt = prop_map[0].formats[fi];
2317 printf("\nFORMAT_%s", VkFormatString(fmt));
2321 for (uint32_t pi = 0; pi < unique_props_count; ++pi) free(prop_map[pi].formats);
2325 static void AppDevDump(const struct AppGpu *gpu, FILE *out) {
2327 fprintf(out, "\t\t\t\t\t<details><summary>Format Properties</summary>\n");
2328 } else if (human_readable_output) {
2329 printf("Format Properties:\n");
2330 printf("==================\n");
2334 printf("\t\"ArrayOfVkFormatProperties\": [");
2337 if (human_readable_output) {
2338 FormatPropsShortenedDump(gpu);
2340 bool first_in_list = true; // Used for commas in json output
2341 for (uint32_t i = 0; i < ARRAY_SIZE(supported_format_ranges); ++i) {
2342 struct FormatRange format_range = supported_format_ranges[i];
2343 if (FormatRangeSupported(&format_range, gpu)) {
2344 for (VkFormat fmt = format_range.first_format; fmt <= format_range.last_format; ++fmt) {
2345 AppDevDumpFormatProps(gpu, fmt, &first_in_list, out);
2352 fprintf(out, "\t\t\t\t\t</details>\n");
2360 #define PRINTF_SIZE_T_SPECIFIER "%Iu"
2362 #define PRINTF_SIZE_T_SPECIFIER "%zu"
2365 static void AppGpuDumpFeatures(const struct AppGpu *gpu, FILE *out) {
2366 VkPhysicalDeviceFeatures features;
2368 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
2369 gpu->inst->inst_extensions_count)) {
2370 const VkPhysicalDeviceFeatures *features2_const = &gpu->features2.features;
2371 features = *features2_const;
2373 const VkPhysicalDeviceFeatures *features_const = &gpu->features;
2374 features = *features_const;
2378 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceFeatures</summary>\n");
2380 "\t\t\t\t\t\t<details><summary>robustBufferAccess = <div "
2381 "class='val'>%u</div></summary></details>\n",
2382 features.robustBufferAccess);
2384 "\t\t\t\t\t\t<details><summary>fullDrawIndexUint32 = <div "
2385 "class='val'>%u</div></summary></details>\n",
2386 features.fullDrawIndexUint32);
2388 "\t\t\t\t\t\t<details><summary>imageCubeArray = <div "
2389 "class='val'>%u</div></summary></details>\n",
2390 features.imageCubeArray);
2392 "\t\t\t\t\t\t<details><summary>independentBlend = <div "
2393 "class='val'>%u</div></summary></details>\n",
2394 features.independentBlend);
2396 "\t\t\t\t\t\t<details><summary>geometryShader = <div "
2397 "class='val'>%u</div></summary></details>\n",
2398 features.geometryShader);
2400 "\t\t\t\t\t\t<details><summary>tessellationShader = <div "
2401 "class='val'>%u</div></summary></details>\n",
2402 features.tessellationShader);
2404 "\t\t\t\t\t\t<details><summary>sampleRateShading = <div "
2405 "class='val'>%u</div></summary></details>\n",
2406 features.sampleRateShading);
2408 "\t\t\t\t\t\t<details><summary>dualSrcBlend = <div "
2409 "class='val'>%u</div></summary></details>\n",
2410 features.dualSrcBlend);
2412 "\t\t\t\t\t\t<details><summary>logicOp = <div "
2413 "class='val'>%u</div></summary></details>\n",
2416 "\t\t\t\t\t\t<details><summary>multiDrawIndirect = <div "
2417 "class='val'>%u</div></summary></details>\n",
2418 features.multiDrawIndirect);
2420 "\t\t\t\t\t\t<details><summary>drawIndirectFirstInstance = <div "
2421 "class='val'>%u</div></summary></details>\n",
2422 features.drawIndirectFirstInstance);
2424 "\t\t\t\t\t\t<details><summary>depthClamp = <div "
2425 "class='val'>%u</div></summary></details>\n",
2426 features.depthClamp);
2428 "\t\t\t\t\t\t<details><summary>depthBiasClamp = <div "
2429 "class='val'>%u</div></summary></details>\n",
2430 features.depthBiasClamp);
2432 "\t\t\t\t\t\t<details><summary>fillModeNonSolid = <div "
2433 "class='val'>%u</div></summary></details>\n",
2434 features.fillModeNonSolid);
2436 "\t\t\t\t\t\t<details><summary>depthBounds = <div "
2437 "class='val'>%u</div></summary></details>\n",
2438 features.depthBounds);
2440 "\t\t\t\t\t\t<details><summary>wideLines = <div "
2441 "class='val'>%u</div></summary></details>\n",
2442 features.wideLines);
2444 "\t\t\t\t\t\t<details><summary>largePoints = <div "
2445 "class='val'>%u</div></summary></details>\n",
2446 features.largePoints);
2448 "\t\t\t\t\t\t<details><summary>alphaToOne = <div "
2449 "class='val'>%u</div></summary></details>\n",
2450 features.alphaToOne);
2452 "\t\t\t\t\t\t<details><summary>multiViewport = <div "
2453 "class='val'>%u</div></summary></details>\n",
2454 features.multiViewport);
2456 "\t\t\t\t\t\t<details><summary>samplerAnisotropy = <div "
2457 "class='val'>%u</div></summary></details>\n",
2458 features.samplerAnisotropy);
2460 "\t\t\t\t\t\t<details><summary>textureCompressionETC2 = <div "
2461 "class='val'>%u</div></summary></details>\n",
2462 features.textureCompressionETC2);
2464 "\t\t\t\t\t\t<details><summary>textureCompressionASTC_LDR = <div "
2465 "class='val'>%u</div></summary></details>\n",
2466 features.textureCompressionASTC_LDR);
2468 "\t\t\t\t\t\t<details><summary>textureCompressionBC = <div "
2469 "class='val'>%u</div></summary></details>\n",
2470 features.textureCompressionBC);
2472 "\t\t\t\t\t\t<details><summary>occlusionQueryPrecise = <div "
2473 "class='val'>%u</div></summary></details>\n",
2474 features.occlusionQueryPrecise);
2476 "\t\t\t\t\t\t<details><summary>pipelineStatisticsQuery = <div "
2477 "class='val'>%u</div></summary></details>\n",
2478 features.pipelineStatisticsQuery);
2480 "\t\t\t\t\t\t<details><summary>vertexPipelineStoresAndAtomics = <div "
2481 "class='val'>%u</div></summary></details>\n",
2482 features.vertexPipelineStoresAndAtomics);
2484 "\t\t\t\t\t\t<details><summary>fragmentStoresAndAtomics = <div "
2485 "class='val'>%u</div></summary></details>\n",
2486 features.fragmentStoresAndAtomics);
2488 "\t\t\t\t\t\t<details><summary>shaderTessellationAndGeometryPointSize = <div "
2489 "class='val'>%u</div></summary></details>\n",
2490 features.shaderTessellationAndGeometryPointSize);
2492 "\t\t\t\t\t\t<details><summary>shaderImageGatherExtended = <div "
2493 "class='val'>%u</div></summary></details>\n",
2494 features.shaderImageGatherExtended);
2496 "\t\t\t\t\t\t<details><summary>shaderStorageImageExtendedFormats = <div "
2497 "class='val'>%u</div></summary></details>\n",
2498 features.shaderStorageImageExtendedFormats);
2500 "\t\t\t\t\t\t<details><summary>shaderStorageImageMultisample = <div "
2501 "class='val'>%u</div></summary></details>\n",
2502 features.shaderStorageImageMultisample);
2504 "\t\t\t\t\t\t<details><summary>shaderStorageImageReadWithoutFormat = <div "
2505 "class='val'>%u</div></summary></details>\n",
2506 features.shaderStorageImageReadWithoutFormat);
2508 "\t\t\t\t\t\t<details><summary>shaderStorageImageWriteWithoutFormat = <div "
2509 "class='val'>%u</div></summary></details>\n",
2510 features.shaderStorageImageWriteWithoutFormat);
2512 "\t\t\t\t\t\t<details><summary>shaderUniformBufferArrayDynamicIndexing = <div "
2513 "class='val'>%u</div></summary></details>\n",
2514 features.shaderUniformBufferArrayDynamicIndexing);
2516 "\t\t\t\t\t\t<details><summary>shaderSampledImageArrayDynamicIndexing = <div "
2517 "class='val'>%u</div></summary></details>\n",
2518 features.shaderSampledImageArrayDynamicIndexing);
2520 "\t\t\t\t\t\t<details><summary>shaderStorageBufferArrayDynamicIndexing = <div "
2521 "class='val'>%u</div></summary></details>\n",
2522 features.shaderStorageBufferArrayDynamicIndexing);
2524 "\t\t\t\t\t\t<details><summary>shaderStorageImageArrayDynamicIndexing = <div "
2525 "class='val'>%u</div></summary></details>\n",
2526 features.shaderStorageImageArrayDynamicIndexing);
2528 "\t\t\t\t\t\t<details><summary>shaderClipDistance = <div "
2529 "class='val'>%u</div></summary></details>\n",
2530 features.shaderClipDistance);
2532 "\t\t\t\t\t\t<details><summary>shaderCullDistance = <div "
2533 "class='val'>%u</div></summary></details>\n",
2534 features.shaderCullDistance);
2536 "\t\t\t\t\t\t<details><summary>shaderFloat64 = <div "
2537 "class='val'>%u</div></summary></details>\n",
2538 features.shaderFloat64);
2540 "\t\t\t\t\t\t<details><summary>shaderInt64 = <div "
2541 "class='val'>%u</div></summary></details>\n",
2542 features.shaderInt64);
2544 "\t\t\t\t\t\t<details><summary>shaderInt16 = <div "
2545 "class='val'>%u</div></summary></details>\n",
2546 features.shaderInt16);
2548 "\t\t\t\t\t\t<details><summary>shaderResourceResidency = <div "
2549 "class='val'>%u</div></summary></details>\n",
2550 features.shaderResourceResidency);
2552 "\t\t\t\t\t\t<details><summary>shaderResourceMinLod = <div "
2553 "class='val'>%u</div></summary></details>\n",
2554 features.shaderResourceMinLod);
2556 "\t\t\t\t\t\t<details><summary>sparseBinding = <div "
2557 "class='val'>%u</div></summary></details>\n",
2558 features.sparseBinding);
2560 "\t\t\t\t\t\t<details><summary>sparseResidencyBuffer = <div "
2561 "class='val'>%u</div></summary></details>\n",
2562 features.sparseResidencyBuffer);
2564 "\t\t\t\t\t\t<details><summary>sparseResidencyImage2D = <div "
2565 "class='val'>%u</div></summary></details>\n",
2566 features.sparseResidencyImage2D);
2568 "\t\t\t\t\t\t<details><summary>sparseResidencyImage3D = <div "
2569 "class='val'>%u</div></summary></details>\n",
2570 features.sparseResidencyImage3D);
2572 "\t\t\t\t\t\t<details><summary>sparseResidency2Samples = <div "
2573 "class='val'>%u</div></summary></details>\n",
2574 features.sparseResidency2Samples);
2576 "\t\t\t\t\t\t<details><summary>sparseResidency4Samples = <div "
2577 "class='val'>%u</div></summary></details>\n",
2578 features.sparseResidency4Samples);
2580 "\t\t\t\t\t\t<details><summary>sparseResidency8Samples = <div "
2581 "class='val'>%u</div></summary></details>\n",
2582 features.sparseResidency8Samples);
2584 "\t\t\t\t\t\t<details><summary>sparseResidency16Samples = <div "
2585 "class='val'>%u</div></summary></details>\n",
2586 features.sparseResidency16Samples);
2588 "\t\t\t\t\t\t<details><summary>sparseResidencyAliased = <div "
2589 "class='val'>%u</div></summary></details>\n",
2590 features.sparseResidencyAliased);
2592 "\t\t\t\t\t\t<details><summary>variableMultisampleRate = <div "
2593 "class='val'>%u</div></summary></details>\n",
2594 features.variableMultisampleRate);
2596 "\t\t\t\t\t\t<details><summary>inheritedQueries = <div "
2597 "class='val'>%u</div></summary></details>\n",
2598 features.inheritedQueries);
2599 fprintf(out, "\t\t\t\t\t</details>\n");
2600 } else if (human_readable_output) {
2601 printf("VkPhysicalDeviceFeatures:\n");
2602 printf("=========================\n");
2603 printf("\trobustBufferAccess = %u\n", features.robustBufferAccess);
2604 printf("\tfullDrawIndexUint32 = %u\n", features.fullDrawIndexUint32);
2605 printf("\timageCubeArray = %u\n", features.imageCubeArray);
2606 printf("\tindependentBlend = %u\n", features.independentBlend);
2607 printf("\tgeometryShader = %u\n", features.geometryShader);
2608 printf("\ttessellationShader = %u\n", features.tessellationShader);
2609 printf("\tsampleRateShading = %u\n", features.sampleRateShading);
2610 printf("\tdualSrcBlend = %u\n", features.dualSrcBlend);
2611 printf("\tlogicOp = %u\n", features.logicOp);
2612 printf("\tmultiDrawIndirect = %u\n", features.multiDrawIndirect);
2613 printf("\tdrawIndirectFirstInstance = %u\n", features.drawIndirectFirstInstance);
2614 printf("\tdepthClamp = %u\n", features.depthClamp);
2615 printf("\tdepthBiasClamp = %u\n", features.depthBiasClamp);
2616 printf("\tfillModeNonSolid = %u\n", features.fillModeNonSolid);
2617 printf("\tdepthBounds = %u\n", features.depthBounds);
2618 printf("\twideLines = %u\n", features.wideLines);
2619 printf("\tlargePoints = %u\n", features.largePoints);
2620 printf("\talphaToOne = %u\n", features.alphaToOne);
2621 printf("\tmultiViewport = %u\n", features.multiViewport);
2622 printf("\tsamplerAnisotropy = %u\n", features.samplerAnisotropy);
2623 printf("\ttextureCompressionETC2 = %u\n", features.textureCompressionETC2);
2624 printf("\ttextureCompressionASTC_LDR = %u\n", features.textureCompressionASTC_LDR);
2625 printf("\ttextureCompressionBC = %u\n", features.textureCompressionBC);
2626 printf("\tocclusionQueryPrecise = %u\n", features.occlusionQueryPrecise);
2627 printf("\tpipelineStatisticsQuery = %u\n", features.pipelineStatisticsQuery);
2628 printf("\tvertexPipelineStoresAndAtomics = %u\n", features.vertexPipelineStoresAndAtomics);
2629 printf("\tfragmentStoresAndAtomics = %u\n", features.fragmentStoresAndAtomics);
2630 printf("\tshaderTessellationAndGeometryPointSize = %u\n", features.shaderTessellationAndGeometryPointSize);
2631 printf("\tshaderImageGatherExtended = %u\n", features.shaderImageGatherExtended);
2632 printf("\tshaderStorageImageExtendedFormats = %u\n", features.shaderStorageImageExtendedFormats);
2633 printf("\tshaderStorageImageMultisample = %u\n", features.shaderStorageImageMultisample);
2634 printf("\tshaderStorageImageReadWithoutFormat = %u\n", features.shaderStorageImageReadWithoutFormat);
2635 printf("\tshaderStorageImageWriteWithoutFormat = %u\n", features.shaderStorageImageWriteWithoutFormat);
2636 printf("\tshaderUniformBufferArrayDynamicIndexing = %u\n", features.shaderUniformBufferArrayDynamicIndexing);
2637 printf("\tshaderSampledImageArrayDynamicIndexing = %u\n", features.shaderSampledImageArrayDynamicIndexing);
2638 printf("\tshaderStorageBufferArrayDynamicIndexing = %u\n", features.shaderStorageBufferArrayDynamicIndexing);
2639 printf("\tshaderStorageImageArrayDynamicIndexing = %u\n", features.shaderStorageImageArrayDynamicIndexing);
2640 printf("\tshaderClipDistance = %u\n", features.shaderClipDistance);
2641 printf("\tshaderCullDistance = %u\n", features.shaderCullDistance);
2642 printf("\tshaderFloat64 = %u\n", features.shaderFloat64);
2643 printf("\tshaderInt64 = %u\n", features.shaderInt64);
2644 printf("\tshaderInt16 = %u\n", features.shaderInt16);
2645 printf("\tshaderResourceResidency = %u\n", features.shaderResourceResidency);
2646 printf("\tshaderResourceMinLod = %u\n", features.shaderResourceMinLod);
2647 printf("\tsparseBinding = %u\n", features.sparseBinding);
2648 printf("\tsparseResidencyBuffer = %u\n", features.sparseResidencyBuffer);
2649 printf("\tsparseResidencyImage2D = %u\n", features.sparseResidencyImage2D);
2650 printf("\tsparseResidencyImage3D = %u\n", features.sparseResidencyImage3D);
2651 printf("\tsparseResidency2Samples = %u\n", features.sparseResidency2Samples);
2652 printf("\tsparseResidency4Samples = %u\n", features.sparseResidency4Samples);
2653 printf("\tsparseResidency8Samples = %u\n", features.sparseResidency8Samples);
2654 printf("\tsparseResidency16Samples = %u\n", features.sparseResidency16Samples);
2655 printf("\tsparseResidencyAliased = %u\n", features.sparseResidencyAliased);
2656 printf("\tvariableMultisampleRate = %u\n", features.variableMultisampleRate);
2657 printf("\tinheritedQueries = %u\n", features.inheritedQueries);
2661 printf("\t\"VkPhysicalDeviceFeatures\": {\n");
2662 printf("\t\t\"robustBufferAccess\": %u,\n", features.robustBufferAccess);
2663 printf("\t\t\"fullDrawIndexUint32\": %u,\n", features.fullDrawIndexUint32);
2664 printf("\t\t\"imageCubeArray\": %u,\n", features.imageCubeArray);
2665 printf("\t\t\"independentBlend\": %u,\n", features.independentBlend);
2666 printf("\t\t\"geometryShader\": %u,\n", features.geometryShader);
2667 printf("\t\t\"tessellationShader\": %u,\n", features.tessellationShader);
2668 printf("\t\t\"sampleRateShading\": %u,\n", features.sampleRateShading);
2669 printf("\t\t\"dualSrcBlend\": %u,\n", features.dualSrcBlend);
2670 printf("\t\t\"logicOp\": %u,\n", features.logicOp);
2671 printf("\t\t\"multiDrawIndirect\": %u,\n", features.multiDrawIndirect);
2672 printf("\t\t\"drawIndirectFirstInstance\": %u,\n", features.drawIndirectFirstInstance);
2673 printf("\t\t\"depthClamp\": %u,\n", features.depthClamp);
2674 printf("\t\t\"depthBiasClamp\": %u,\n", features.depthBiasClamp);
2675 printf("\t\t\"fillModeNonSolid\": %u,\n", features.fillModeNonSolid);
2676 printf("\t\t\"depthBounds\": %u,\n", features.depthBounds);
2677 printf("\t\t\"wideLines\": %u,\n", features.wideLines);
2678 printf("\t\t\"largePoints\": %u,\n", features.largePoints);
2679 printf("\t\t\"alphaToOne\": %u,\n", features.alphaToOne);
2680 printf("\t\t\"multiViewport\": %u,\n", features.multiViewport);
2681 printf("\t\t\"samplerAnisotropy\": %u,\n", features.samplerAnisotropy);
2682 printf("\t\t\"textureCompressionETC2\": %u,\n", features.textureCompressionETC2);
2683 printf("\t\t\"textureCompressionASTC_LDR\": %u,\n", features.textureCompressionASTC_LDR);
2684 printf("\t\t\"textureCompressionBC\": %u,\n", features.textureCompressionBC);
2685 printf("\t\t\"occlusionQueryPrecise\": %u,\n", features.occlusionQueryPrecise);
2686 printf("\t\t\"pipelineStatisticsQuery\": %u,\n", features.pipelineStatisticsQuery);
2687 printf("\t\t\"vertexPipelineStoresAndAtomics\": %u,\n", features.vertexPipelineStoresAndAtomics);
2688 printf("\t\t\"fragmentStoresAndAtomics\": %u,\n", features.fragmentStoresAndAtomics);
2689 printf("\t\t\"shaderTessellationAndGeometryPointSize\": %u,\n", features.shaderTessellationAndGeometryPointSize);
2690 printf("\t\t\"shaderImageGatherExtended\": %u,\n", features.shaderImageGatherExtended);
2691 printf("\t\t\"shaderStorageImageExtendedFormats\": %u,\n", features.shaderStorageImageExtendedFormats);
2692 printf("\t\t\"shaderStorageImageMultisample\": %u,\n", features.shaderStorageImageMultisample);
2693 printf("\t\t\"shaderStorageImageReadWithoutFormat\": %u,\n", features.shaderStorageImageReadWithoutFormat);
2694 printf("\t\t\"shaderStorageImageWriteWithoutFormat\": %u,\n", features.shaderStorageImageWriteWithoutFormat);
2695 printf("\t\t\"shaderUniformBufferArrayDynamicIndexing\": %u,\n", features.shaderUniformBufferArrayDynamicIndexing);
2696 printf("\t\t\"shaderSampledImageArrayDynamicIndexing\": %u,\n", features.shaderSampledImageArrayDynamicIndexing);
2697 printf("\t\t\"shaderStorageBufferArrayDynamicIndexing\": %u,\n", features.shaderStorageBufferArrayDynamicIndexing);
2698 printf("\t\t\"shaderStorageImageArrayDynamicIndexing\": %u,\n", features.shaderStorageImageArrayDynamicIndexing);
2699 printf("\t\t\"shaderClipDistance\": %u,\n", features.shaderClipDistance);
2700 printf("\t\t\"shaderCullDistance\": %u,\n", features.shaderCullDistance);
2701 printf("\t\t\"shaderFloat64\": %u,\n", features.shaderFloat64);
2702 printf("\t\t\"shaderInt64\": %u,\n", features.shaderInt64);
2703 printf("\t\t\"shaderInt16\": %u,\n", features.shaderInt16);
2704 printf("\t\t\"shaderResourceResidency\": %u,\n", features.shaderResourceResidency);
2705 printf("\t\t\"shaderResourceMinLod\": %u,\n", features.shaderResourceMinLod);
2706 printf("\t\t\"sparseBinding\": %u,\n", features.sparseBinding);
2707 printf("\t\t\"sparseResidencyBuffer\": %u,\n", features.sparseResidencyBuffer);
2708 printf("\t\t\"sparseResidencyImage2D\": %u,\n", features.sparseResidencyImage2D);
2709 printf("\t\t\"sparseResidencyImage3D\": %u,\n", features.sparseResidencyImage3D);
2710 printf("\t\t\"sparseResidency2Samples\": %u,\n", features.sparseResidency2Samples);
2711 printf("\t\t\"sparseResidency4Samples\": %u,\n", features.sparseResidency4Samples);
2712 printf("\t\t\"sparseResidency8Samples\": %u,\n", features.sparseResidency8Samples);
2713 printf("\t\t\"sparseResidency16Samples\": %u,\n", features.sparseResidency16Samples);
2714 printf("\t\t\"sparseResidencyAliased\": %u,\n", features.sparseResidencyAliased);
2715 printf("\t\t\"variableMultisampleRate\": %u,\n", features.variableMultisampleRate);
2716 printf("\t\t\"inheritedQueries\": %u\n", features.inheritedQueries);
2720 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
2721 gpu->inst->inst_extensions_count)) {
2722 void *place = gpu->features2.pNext;
2724 struct VkStructureHeader *structure = (struct VkStructureHeader *)place;
2725 if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR &&
2726 CheckPhysicalDeviceExtensionIncluded(VK_KHR_8BIT_STORAGE_EXTENSION_NAME, gpu->device_extensions,
2727 gpu->device_extension_count)) {
2728 VkPhysicalDevice8BitStorageFeaturesKHR *b8_store_features = (VkPhysicalDevice8BitStorageFeaturesKHR *)structure;
2730 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDevice8BitStorageFeatures</summary>\n");
2732 "\t\t\t\t\t\t<details><summary>storageBuffer8BitAccess = <div "
2733 "class='val'>%u</div></summary></details>\n",
2734 b8_store_features->storageBuffer8BitAccess);
2736 "\t\t\t\t\t\t<details><summary>uniformAndStorageBuffer8BitAccess = <div "
2737 "class='val'>%u</div></summary></details>\n",
2738 b8_store_features->uniformAndStorageBuffer8BitAccess);
2740 "\t\t\t\t\t\t<details><summary>storagePushConstant8 = <div "
2741 "class='val'>%u</div></summary></details>\n",
2742 b8_store_features->storagePushConstant8);
2743 fprintf(out, "\t\t\t\t\t</details>\n");
2744 } else if (human_readable_output) {
2745 printf("\nVkPhysicalDevice8BitStorageFeatures:\n");
2746 printf("=====================================\n");
2747 printf("\tstorageBuffer8BitAccess = %u\n", b8_store_features->storageBuffer8BitAccess);
2748 printf("\tuniformAndStorageBuffer8BitAccess = %u\n", b8_store_features->uniformAndStorageBuffer8BitAccess);
2749 printf("\tstoragePushConstant8 = %u\n", b8_store_features->storagePushConstant8);
2751 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR &&
2752 CheckPhysicalDeviceExtensionIncluded(VK_KHR_16BIT_STORAGE_EXTENSION_NAME, gpu->device_extensions,
2753 gpu->device_extension_count)) {
2754 VkPhysicalDevice16BitStorageFeaturesKHR *b16_store_features = (VkPhysicalDevice16BitStorageFeaturesKHR *)structure;
2756 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDevice16BitStorageFeatures</summary>\n");
2758 "\t\t\t\t\t\t<details><summary>storageBuffer16BitAccess = <div "
2759 "class='val'>%u</div></summary></details>\n",
2760 b16_store_features->storageBuffer16BitAccess);
2762 "\t\t\t\t\t\t<details><summary>uniformAndStorageBuffer16BitAccess = <div "
2763 "class='val'>%u</div></summary></details>\n",
2764 b16_store_features->uniformAndStorageBuffer16BitAccess);
2766 "\t\t\t\t\t\t<details><summary>storagePushConstant16 = <div "
2767 "class='val'>%u</div></summary></details>\n",
2768 b16_store_features->storagePushConstant16);
2770 "\t\t\t\t\t\t<details><summary>storageInputOutput16 = <div "
2771 "class='val'>%u</div></summary></details>\n",
2772 b16_store_features->storageInputOutput16);
2773 fprintf(out, "\t\t\t\t\t</details>\n");
2774 } else if (human_readable_output) {
2775 printf("\nVkPhysicalDevice16BitStorageFeatures:\n");
2776 printf("=====================================\n");
2777 printf("\tstorageBuffer16BitAccess = %u\n", b16_store_features->storageBuffer16BitAccess);
2778 printf("\tuniformAndStorageBuffer16BitAccess = %u\n", b16_store_features->uniformAndStorageBuffer16BitAccess);
2779 printf("\tstoragePushConstant16 = %u\n", b16_store_features->storagePushConstant16);
2780 printf("\tstorageInputOutput16 = %u\n", b16_store_features->storageInputOutput16);
2782 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR &&
2783 CheckPhysicalDeviceExtensionIncluded(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, gpu->device_extensions,
2784 gpu->device_extension_count)) {
2785 VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR *sampler_ycbcr_features =
2786 (VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR *)structure;
2788 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceSamplerYcbcrConversionFeatures</summary>\n");
2791 "\t\t\t\t\t\t<details><summary>samplerYcbcrConversion = <div class='val'>%u</div></summary></details>\n",
2792 sampler_ycbcr_features->samplerYcbcrConversion);
2793 fprintf(out, "\t\t\t\t\t</details>\n");
2794 } else if (human_readable_output) {
2795 printf("\nVkPhysicalDeviceSamplerYcbcrConversionFeatures:\n");
2796 printf("===============================================\n");
2797 printf("\tsamplerYcbcrConversion = %u\n", sampler_ycbcr_features->samplerYcbcrConversion);
2799 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR &&
2800 CheckPhysicalDeviceExtensionIncluded(VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME, gpu->device_extensions,
2801 gpu->device_extension_count)) {
2802 VkPhysicalDeviceVariablePointerFeaturesKHR *var_pointer_features =
2803 (VkPhysicalDeviceVariablePointerFeaturesKHR *)structure;
2805 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceVariablePointerFeatures</summary>\n");
2807 "\t\t\t\t\t\t<details><summary>variablePointersStorageBuffer = <div "
2808 "class='val'>%u</div></summary></details>\n",
2809 var_pointer_features->variablePointersStorageBuffer);
2811 "\t\t\t\t\t\t<details><summary>variablePointers = <div "
2812 "class='val'>%u</div></summary></details>\n",
2813 var_pointer_features->variablePointers);
2814 fprintf(out, "\t\t\t\t\t</details>\n");
2815 } else if (human_readable_output) {
2816 printf("\nVkPhysicalDeviceVariablePointerFeatures:\n");
2817 printf("========================================\n");
2818 printf("\tvariablePointersStorageBuffer = %u\n", var_pointer_features->variablePointersStorageBuffer);
2819 printf("\tvariablePointers = %u\n", var_pointer_features->variablePointers);
2821 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT &&
2822 CheckPhysicalDeviceExtensionIncluded(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, gpu->device_extensions,
2823 gpu->device_extension_count)) {
2824 VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT *blend_op_adv_features =
2825 (VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT *)structure;
2827 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceBlendOperationAdvancedFeatures</summary>\n");
2829 "\t\t\t\t\t\t<details><summary>advancedBlendCoherentOperations = <div "
2830 "class='val'>%u</div></summary></details>\n",
2831 blend_op_adv_features->advancedBlendCoherentOperations);
2832 fprintf(out, "\t\t\t\t\t</details>\n");
2833 } else if (human_readable_output) {
2834 printf("\nVkPhysicalDeviceBlendOperationAdvancedFeatures:\n");
2835 printf("===============================================\n");
2836 printf("\tadvancedBlendCoherentOperations = %u\n", blend_op_adv_features->advancedBlendCoherentOperations);
2838 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR &&
2839 CheckPhysicalDeviceExtensionIncluded(VK_KHR_MULTIVIEW_EXTENSION_NAME, gpu->device_extensions,
2840 gpu->device_extension_count)) {
2841 VkPhysicalDeviceMultiviewFeaturesKHR *multiview_features = (VkPhysicalDeviceMultiviewFeaturesKHR *)structure;
2843 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceMultiviewFeatures</summary>\n");
2845 "\t\t\t\t\t\t<details><summary>multiview = <div "
2846 "class='val'>%u</div></summary></details>\n",
2847 multiview_features->multiview);
2849 "\t\t\t\t\t\t<details><summary>multiviewGeometryShader = <div "
2850 "class='val'>%u</div></summary></details>\n",
2851 multiview_features->multiviewGeometryShader);
2853 "\t\t\t\t\t\t<details><summary>multiviewTessellationShader = <div "
2854 "class='val'>%u</div></summary></details>\n",
2855 multiview_features->multiviewTessellationShader);
2856 fprintf(out, "\t\t\t\t\t</details>\n");
2857 } else if (human_readable_output) {
2858 printf("\nVkPhysicalDeviceMultiviewFeatures:\n");
2859 printf("==================================\n");
2860 printf("\tmultiview = %u\n", multiview_features->multiview);
2861 printf("\tmultiviewGeometryShader = %u\n", multiview_features->multiviewGeometryShader);
2862 printf("\tmultiviewTessellationShader = %u\n", multiview_features->multiviewTessellationShader);
2864 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR &&
2865 CheckPhysicalDeviceExtensionIncluded(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, gpu->device_extensions,
2866 gpu->device_extension_count)) {
2867 VkPhysicalDeviceFloat16Int8FeaturesKHR *float_int_features = (VkPhysicalDeviceFloat16Int8FeaturesKHR *)structure;
2869 fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceFloat16Int8Features</summary>\n");
2871 "\t\t\t\t\t\t<details><summary>shaderFloat16 = <div class='val'>%" PRIuLEAST32
2872 "</div></summary></details>\n",
2873 float_int_features->shaderFloat16);
2875 "\t\t\t\t\t\t<details><summary>shaderInt8 = <div class='val'>%" PRIuLEAST32
2876 "</div></summary></details>\n",
2877 float_int_features->shaderInt8);
2878 fprintf(out, "\t\t\t\t\t</details>\n");
2879 } else if (human_readable_output) {
2880 printf("\nVkPhysicalDeviceFloat16Int8Features:\n");
2881 printf("====================================\n");
2882 printf("\tshaderFloat16 = %" PRIuLEAST32 "\n", float_int_features->shaderFloat16);
2883 printf("\tshaderInt8 = %" PRIuLEAST32 "\n", float_int_features->shaderInt8);
2885 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR &&
2886 CheckPhysicalDeviceExtensionIncluded(VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME, gpu->device_extensions,
2887 gpu->device_extension_count)) {
2888 VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *shader_atomic_int64_features =
2889 (VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *)structure;
2891 fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceShaderAtomicInt64Features</summary>\n");
2893 "\t\t\t\t\t\t<details><summary>shaderBufferInt64Atomics = <div class='val'>%" PRIuLEAST32
2894 "</div></summary></details>\n",
2895 shader_atomic_int64_features->shaderBufferInt64Atomics);
2897 "\t\t\t\t\t\t<details><summary>shaderSharedInt64Atomics = <div class='val'>%" PRIuLEAST32
2898 "</div></summary></details>\n",
2899 shader_atomic_int64_features->shaderSharedInt64Atomics);
2900 fprintf(out, "\t\t\t\t\t</details>\n");
2901 } else if (human_readable_output) {
2902 printf("\nVkPhysicalDeviceShaderAtomicInt64Features:\n");
2903 printf("==========================================\n");
2904 printf("\tshaderBufferInt64Atomics = %" PRIuLEAST32 "\n",
2905 shader_atomic_int64_features->shaderBufferInt64Atomics);
2906 printf("\tshaderSharedInt64Atomics = %" PRIuLEAST32 "\n",
2907 shader_atomic_int64_features->shaderSharedInt64Atomics);
2909 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT &&
2910 CheckPhysicalDeviceExtensionIncluded(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, gpu->device_extensions,
2911 gpu->device_extension_count)) {
2912 VkPhysicalDeviceTransformFeedbackFeaturesEXT *transform_feedback_features =
2913 (VkPhysicalDeviceTransformFeedbackFeaturesEXT *)structure;
2915 fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceTransformFeedbackFeatures</summary>\n");
2917 "\t\t\t\t\t\t<details><summary>transformFeedback = <div class='val'>%" PRIuLEAST32
2918 "</div></summary></details>\n",
2919 transform_feedback_features->transformFeedback);
2921 "\t\t\t\t\t\t<details><summary>geometryStreams = <div class='val'>%" PRIuLEAST32
2922 "</div></summary></details>\n",
2923 transform_feedback_features->geometryStreams);
2924 fprintf(out, "\t\t\t\t\t</details>\n");
2925 } else if (human_readable_output) {
2926 printf("\nVkPhysicalDeviceTransformFeedbackFeatures:\n");
2927 printf("==========================================\n");
2928 printf("\ttransformFeedback = %" PRIuLEAST32 "\n", transform_feedback_features->transformFeedback);
2929 printf("\tgeometryStreams = %" PRIuLEAST32 "\n", transform_feedback_features->geometryStreams);
2931 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT &&
2932 CheckPhysicalDeviceExtensionIncluded(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME, gpu->device_extensions,
2933 gpu->device_extension_count)) {
2934 VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *scalar_block_layout_features =
2935 (VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *)structure;
2937 fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceScalarBlockLayoutFeatures</summary>\n");
2939 "\t\t\t\t\t\t<details><summary>scalarBlockLayout = <div class='val'>%" PRIuLEAST32
2940 "</div></summary></details>\n",
2941 scalar_block_layout_features->scalarBlockLayout);
2942 fprintf(out, "\t\t\t\t\t</details>\n");
2943 } else if (human_readable_output) {
2944 printf("\nVkPhysicalDeviceScalarBlockLayoutFeatures:\n");
2945 printf("==========================================\n");
2946 printf("\tscalarBlockLayout = %" PRIuLEAST32 "\n", scalar_block_layout_features->scalarBlockLayout);
2948 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT &&
2949 CheckPhysicalDeviceExtensionIncluded(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME, gpu->device_extensions,
2950 gpu->device_extension_count)) {
2951 VkPhysicalDeviceFragmentDensityMapFeaturesEXT *fragment_density_map_features =
2952 (VkPhysicalDeviceFragmentDensityMapFeaturesEXT *)structure;
2954 fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceFragmentDensityMapFeatures</summary>\n");
2956 "\t\t\t\t\t\t<details><summary>fragmentDensityMap = <div class='val'>%" PRIuLEAST32
2957 "</div></summary></details>\n",
2958 fragment_density_map_features->fragmentDensityMap);
2960 "\t\t\t\t\t\t<details><summary>fragmentDensityMapDynamic = <div class='val'>%" PRIuLEAST32
2961 "</div></summary></details>\n",
2962 fragment_density_map_features->fragmentDensityMapDynamic);
2964 "\t\t\t\t\t\t<details><summary>fragmentDensityMapNonSubsampledImages = <div class='val'>%" PRIuLEAST32
2965 "</div></summary></details>\n",
2966 fragment_density_map_features->fragmentDensityMapNonSubsampledImages);
2967 fprintf(out, "\t\t\t\t\t</details>\n");
2968 } else if (human_readable_output) {
2969 printf("\nVkPhysicalDeviceFragmentDensityMapFeatures:\n");
2970 printf("==========================================\n");
2971 printf("\tfragmentDensityMap = %" PRIuLEAST32 "\n",
2972 fragment_density_map_features->fragmentDensityMap);
2973 printf("\tfragmentDensityMapDynamic = %" PRIuLEAST32 "\n",
2974 fragment_density_map_features->fragmentDensityMapDynamic);
2975 printf("\tfragmentDensityMapNonSubsampledImages = %" PRIuLEAST32 "\n",
2976 fragment_density_map_features->fragmentDensityMapNonSubsampledImages);
2979 place = structure->pNext;
2984 static void AppDumpSparseProps(const VkPhysicalDeviceSparseProperties *sparse_props, FILE *out) {
2986 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceSparseProperties</summary>\n");
2988 "\t\t\t\t\t\t<details><summary>residencyStandard2DBlockShape = <div "
2989 "class='val'>%u</div></summary></details>\n",
2990 sparse_props->residencyStandard2DBlockShape);
2992 "\t\t\t\t\t\t<details><summary>residencyStandard2DMultisampleBlockShape = <div "
2993 "class='val'>%u</div></summary></details>\n",
2994 sparse_props->residencyStandard2DMultisampleBlockShape);
2996 "\t\t\t\t\t\t<details><summary>residencyStandard3DBlockShape = <div "
2997 "class='val'>%u</div></summary></details>\n",
2998 sparse_props->residencyStandard3DBlockShape);
3000 "\t\t\t\t\t\t<details><summary>residencyAlignedMipSize = <div "
3001 "class='val'>%u</div></summary></details>\n",
3002 sparse_props->residencyAlignedMipSize);
3004 "\t\t\t\t\t\t<details><summary>residencyNonResidentStrict = <div "
3005 "class='val'>%u</div></summary></details>\n",
3006 sparse_props->residencyNonResidentStrict);
3007 fprintf(out, "\t\t\t\t\t</details>\n");
3008 } else if (human_readable_output) {
3009 printf("\tVkPhysicalDeviceSparseProperties:\n");
3010 printf("\t---------------------------------\n");
3011 printf("\t\tresidencyStandard2DBlockShape = %u\n", sparse_props->residencyStandard2DBlockShape);
3012 printf("\t\tresidencyStandard2DMultisampleBlockShape = %u\n", sparse_props->residencyStandard2DMultisampleBlockShape);
3013 printf("\t\tresidencyStandard3DBlockShape = %u\n", sparse_props->residencyStandard3DBlockShape);
3014 printf("\t\tresidencyAlignedMipSize = %u\n", sparse_props->residencyAlignedMipSize);
3015 printf("\t\tresidencyNonResidentStrict = %u\n", sparse_props->residencyNonResidentStrict);
3019 printf("\t\t\"sparseProperties\": {\n");
3020 printf("\t\t\t\"residencyStandard2DBlockShape\": %u,\n", sparse_props->residencyStandard2DBlockShape);
3021 printf("\t\t\t\"residencyStandard2DMultisampleBlockShape\": %u,\n", sparse_props->residencyStandard2DMultisampleBlockShape);
3022 printf("\t\t\t\"residencyStandard3DBlockShape\": %u,\n", sparse_props->residencyStandard3DBlockShape);
3023 printf("\t\t\t\"residencyAlignedMipSize\": %u,\n", sparse_props->residencyAlignedMipSize);
3024 printf("\t\t\t\"residencyNonResidentStrict\": %u\n", sparse_props->residencyNonResidentStrict);
3029 static void AppDumpLimits(const VkPhysicalDeviceLimits *limits, FILE *out) {
3031 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceLimits</summary>\n");
3033 "\t\t\t\t\t\t<details><summary>maxImageDimension1D = <div "
3034 "class='val'>%u</div></summary></details>\n",
3035 limits->maxImageDimension1D);
3037 "\t\t\t\t\t\t<details><summary>maxImageDimension2D = <div "
3038 "class='val'>%u</div></summary></details>\n",
3039 limits->maxImageDimension2D);
3041 "\t\t\t\t\t\t<details><summary>maxImageDimension3D = <div "
3042 "class='val'>%u</div></summary></details>\n",
3043 limits->maxImageDimension3D);
3045 "\t\t\t\t\t\t<details><summary>maxImageDimensionCube = <div "
3046 "class='val'>%u</div></summary></details>\n",
3047 limits->maxImageDimensionCube);
3049 "\t\t\t\t\t\t<details><summary>maxImageArrayLayers = <div "
3050 "class='val'>%u</div></summary></details>\n",
3051 limits->maxImageArrayLayers);
3053 "\t\t\t\t\t\t<details><summary>maxTexelBufferElements = <div class='val'>0x%" PRIxLEAST32
3054 "</div></summary></details>\n",
3055 limits->maxTexelBufferElements);
3057 "\t\t\t\t\t\t<details><summary>maxUniformBufferRange = <div class='val'>0x%" PRIxLEAST32
3058 "</div></summary></details>\n",
3059 limits->maxUniformBufferRange);
3061 "\t\t\t\t\t\t<details><summary>maxStorageBufferRange = <div class='val'>0x%" PRIxLEAST32
3062 "</div></summary></details>\n",
3063 limits->maxStorageBufferRange);
3065 "\t\t\t\t\t\t<details><summary>maxPushConstantsSize = <div "
3066 "class='val'>%u</div></summary></details>\n",
3067 limits->maxPushConstantsSize);
3069 "\t\t\t\t\t\t<details><summary>maxMemoryAllocationCount = <div "
3070 "class='val'>%u</div></summary></details>\n",
3071 limits->maxMemoryAllocationCount);
3073 "\t\t\t\t\t\t<details><summary>maxSamplerAllocationCount = <div "
3074 "class='val'>%u</div></summary></details>\n",
3075 limits->maxSamplerAllocationCount);
3077 "\t\t\t\t\t\t<details><summary>bufferImageGranularity = <div class='val'>0x%" PRIxLEAST64
3078 "</div></summary></details>\n",
3079 limits->bufferImageGranularity);
3081 "\t\t\t\t\t\t<details><summary>sparseAddressSpaceSize = <div class='val'>0x%" PRIxLEAST64
3082 "</div></summary></details>\n",
3083 limits->sparseAddressSpaceSize);
3085 "\t\t\t\t\t\t<details><summary>maxBoundDescriptorSets = <div "
3086 "class='val'>%u</div></summary></details>\n",
3087 limits->maxBoundDescriptorSets);
3089 "\t\t\t\t\t\t<details><summary>maxPerStageDescriptorSamplers = <div "
3090 "class='val'>%u</div></summary></details>\n",
3091 limits->maxPerStageDescriptorSamplers);
3093 "\t\t\t\t\t\t<details><summary>maxPerStageDescriptorUniformBuffers = <div "
3094 "class='val'>%u</div></summary></details>\n",
3095 limits->maxPerStageDescriptorUniformBuffers);
3097 "\t\t\t\t\t\t<details><summary>maxPerStageDescriptorStorageBuffers = <div "
3098 "class='val'>%u</div></summary></details>\n",
3099 limits->maxPerStageDescriptorStorageBuffers);
3101 "\t\t\t\t\t\t<details><summary>maxPerStageDescriptorSampledImages = <div "
3102 "class='val'>%u</div></summary></details>\n",
3103 limits->maxPerStageDescriptorSampledImages);
3105 "\t\t\t\t\t\t<details><summary>maxPerStageDescriptorStorageImages = <div "
3106 "class='val'>%u</div></summary></details>\n",
3107 limits->maxPerStageDescriptorStorageImages);
3109 "\t\t\t\t\t\t<details><summary>maxPerStageDescriptorInputAttachments = <div "
3110 "class='val'>%u</div></summary></details>\n",
3111 limits->maxPerStageDescriptorInputAttachments);
3113 "\t\t\t\t\t\t<details><summary>maxPerStageResources = <div "
3114 "class='val'>%u</div></summary></details>\n",
3115 limits->maxPerStageResources);
3117 "\t\t\t\t\t\t<details><summary>maxDescriptorSetSamplers = <div "
3118 "class='val'>%u</div></summary></details>\n",
3119 limits->maxDescriptorSetSamplers);
3121 "\t\t\t\t\t\t<details><summary>maxDescriptorSetUniformBuffers = <div "
3122 "class='val'>%u</div></summary></details>\n",
3123 limits->maxDescriptorSetUniformBuffers);
3125 "\t\t\t\t\t\t<details><summary>maxDescriptorSetUniformBuffersDynamic = <div "
3126 "class='val'>%u</div></summary></details>\n",
3127 limits->maxDescriptorSetUniformBuffersDynamic);
3129 "\t\t\t\t\t\t<details><summary>maxDescriptorSetStorageBuffers = <div "
3130 "class='val'>%u</div></summary></details>\n",
3131 limits->maxDescriptorSetStorageBuffers);
3133 "\t\t\t\t\t\t<details><summary>maxDescriptorSetStorageBuffersDynamic = <div "
3134 "class='val'>%u</div></summary></details>\n",
3135 limits->maxDescriptorSetStorageBuffersDynamic);
3137 "\t\t\t\t\t\t<details><summary>maxDescriptorSetSampledImages = <div "
3138 "class='val'>%u</div></summary></details>\n",
3139 limits->maxDescriptorSetSampledImages);
3141 "\t\t\t\t\t\t<details><summary>maxDescriptorSetStorageImages = <div "
3142 "class='val'>%u</div></summary></details>\n",
3143 limits->maxDescriptorSetStorageImages);
3145 "\t\t\t\t\t\t<details><summary>maxDescriptorSetInputAttachments = <div "
3146 "class='val'>%u</div></summary></details>\n",
3147 limits->maxDescriptorSetInputAttachments);
3149 "\t\t\t\t\t\t<details><summary>maxVertexInputAttributes = <div "
3150 "class='val'>%u</div></summary></details>\n",
3151 limits->maxVertexInputAttributes);
3153 "\t\t\t\t\t\t<details><summary>maxVertexInputBindings = <div "
3154 "class='val'>%u</div></summary></details>\n",
3155 limits->maxVertexInputBindings);
3157 "\t\t\t\t\t\t<details><summary>maxVertexInputAttributeOffset = <div class='val'>0x%" PRIxLEAST32
3158 "</div></summary></details>\n",
3159 limits->maxVertexInputAttributeOffset);
3161 "\t\t\t\t\t\t<details><summary>maxVertexInputBindingStride = <div class='val'>0x%" PRIxLEAST32
3162 "</div></summary></details>\n",
3163 limits->maxVertexInputBindingStride);
3165 "\t\t\t\t\t\t<details><summary>maxVertexOutputComponents = <div "
3166 "class='val'>%u</div></summary></details>\n",
3167 limits->maxVertexOutputComponents);
3169 "\t\t\t\t\t\t<details><summary>maxTessellationGenerationLevel = <div "
3170 "class='val'>%u</div></summary></details>\n",
3171 limits->maxTessellationGenerationLevel);
3173 "\t\t\t\t\t\t<details><summary>maxTessellationPatchSize = <div "
3174 "class='val'>%u</div></summary></details>\n",
3175 limits->maxTessellationPatchSize);
3177 "\t\t\t\t\t\t<details><summary>maxTessellationControlPerVertexInputComponents = <div "
3178 "class='val'>%u</div></summary></details>\n",
3179 limits->maxTessellationControlPerVertexInputComponents);
3181 "\t\t\t\t\t\t<details><summary>maxTessellationControlPerVertexOutputComponents = <div "
3182 "class='val'>%u</div></summary></details>\n",
3183 limits->maxTessellationControlPerVertexOutputComponents);
3185 "\t\t\t\t\t\t<details><summary>maxTessellationControlPerPatchOutputComponents = <div "
3186 "class='val'>%u</div></summary></details>\n",
3187 limits->maxTessellationControlPerPatchOutputComponents);
3189 "\t\t\t\t\t\t<details><summary>maxTessellationControlTotalOutputComponents = <div "
3190 "class='val'>%u</div></summary></details>\n",
3191 limits->maxTessellationControlTotalOutputComponents);
3193 "\t\t\t\t\t\t<details><summary>maxTessellationEvaluationInputComponents = <div "
3194 "class='val'>%u</div></summary></details>\n",
3195 limits->maxTessellationEvaluationInputComponents);
3197 "\t\t\t\t\t\t<details><summary>maxTessellationEvaluationOutputComponents = <div "
3198 "class='val'>%u</div></summary></details>\n",
3199 limits->maxTessellationEvaluationOutputComponents);
3201 "\t\t\t\t\t\t<details><summary>maxGeometryShaderInvocations = <div "
3202 "class='val'>%u</div></summary></details>\n",
3203 limits->maxGeometryShaderInvocations);
3205 "\t\t\t\t\t\t<details><summary>maxGeometryInputComponents = <div "
3206 "class='val'>%u</div></summary></details>\n",
3207 limits->maxGeometryInputComponents);
3209 "\t\t\t\t\t\t<details><summary>maxGeometryOutputComponents = <div "
3210 "class='val'>%u</div></summary></details>\n",
3211 limits->maxGeometryOutputComponents);
3213 "\t\t\t\t\t\t<details><summary>maxGeometryOutputVertices = <div "
3214 "class='val'>%u</div></summary></details>\n",
3215 limits->maxGeometryOutputVertices);
3217 "\t\t\t\t\t\t<details><summary>maxGeometryTotalOutputComponents = <div "
3218 "class='val'>%u</div></summary></details>\n",
3219 limits->maxGeometryTotalOutputComponents);
3221 "\t\t\t\t\t\t<details><summary>maxFragmentInputComponents = <div "
3222 "class='val'>%u</div></summary></details>\n",
3223 limits->maxFragmentInputComponents);
3225 "\t\t\t\t\t\t<details><summary>maxFragmentOutputAttachments = <div "
3226 "class='val'>%u</div></summary></details>\n",
3227 limits->maxFragmentOutputAttachments);
3229 "\t\t\t\t\t\t<details><summary>maxFragmentDualSrcAttachments = <div "
3230 "class='val'>%u</div></summary></details>\n",
3231 limits->maxFragmentDualSrcAttachments);
3233 "\t\t\t\t\t\t<details><summary>maxFragmentCombinedOutputResources = <div "
3234 "class='val'>%u</div></summary></details>\n",
3235 limits->maxFragmentCombinedOutputResources);
3237 "\t\t\t\t\t\t<details><summary>maxComputeSharedMemorySize = <div class='val'>0x%" PRIxLEAST32
3238 "</div></summary></details>\n",
3239 limits->maxComputeSharedMemorySize);
3241 "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupCount[0] = <div "
3242 "class='val'>%u</div></summary></details>\n",
3243 limits->maxComputeWorkGroupCount[0]);
3245 "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupCount[1] = <div "
3246 "class='val'>%u</div></summary></details>\n",
3247 limits->maxComputeWorkGroupCount[1]);
3249 "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupCount[2] = <div "
3250 "class='val'>%u</div></summary></details>\n",
3251 limits->maxComputeWorkGroupCount[2]);
3253 "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupInvocations = <div "
3254 "class='val'>%u</div></summary></details>\n",
3255 limits->maxComputeWorkGroupInvocations);
3257 "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupSize[0] = <div "
3258 "class='val'>%u</div></summary></details>\n",
3259 limits->maxComputeWorkGroupSize[0]);
3261 "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupSize[1] = <div "
3262 "class='val'>%u</div></summary></details>\n",
3263 limits->maxComputeWorkGroupSize[1]);
3265 "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupSize[2] = <div "
3266 "class='val'>%u</div></summary></details>\n",
3267 limits->maxComputeWorkGroupSize[2]);
3269 "\t\t\t\t\t\t<details><summary>subPixelPrecisionBits = <div "
3270 "class='val'>%u</div></summary></details>\n",
3271 limits->subPixelPrecisionBits);
3273 "\t\t\t\t\t\t<details><summary>subTexelPrecisionBits = <div "
3274 "class='val'>%u</div></summary></details>\n",
3275 limits->subTexelPrecisionBits);
3277 "\t\t\t\t\t\t<details><summary>mipmapPrecisionBits = <div "
3278 "class='val'>%u</div></summary></details>\n",
3279 limits->mipmapPrecisionBits);
3281 "\t\t\t\t\t\t<details><summary>maxDrawIndexedIndexValue = <div "
3282 "class='val'>%u</div></summary></details>\n",
3283 limits->maxDrawIndexedIndexValue);
3285 "\t\t\t\t\t\t<details><summary>maxDrawIndirectCount = <div "
3286 "class='val'>%u</div></summary></details>\n",
3287 limits->maxDrawIndirectCount);
3289 "\t\t\t\t\t\t<details><summary>maxSamplerLodBias = <div "
3290 "class='val'>%f</div></summary></details>\n",
3291 limits->maxSamplerLodBias);
3293 "\t\t\t\t\t\t<details><summary>maxSamplerAnisotropy = <div "
3294 "class='val'>%f</div></summary></details>\n",
3295 limits->maxSamplerAnisotropy);
3297 "\t\t\t\t\t\t<details><summary>maxViewports = <div "
3298 "class='val'>%u</div></summary></details>\n",
3299 limits->maxViewports);
3301 "\t\t\t\t\t\t<details><summary>maxViewportDimensions[0] = <div "
3302 "class='val'>%u</div></summary></details>\n",
3303 limits->maxViewportDimensions[0]);
3305 "\t\t\t\t\t\t<details><summary>maxViewportDimensions[1] = <div "
3306 "class='val'>%u</div></summary></details>\n",
3307 limits->maxViewportDimensions[1]);
3309 "\t\t\t\t\t\t<details><summary>viewportBoundsRange[0] = <div "
3310 "class='val'>%13f</div></summary></details>\n",
3311 limits->viewportBoundsRange[0]);
3313 "\t\t\t\t\t\t<details><summary>viewportBoundsRange[1] = <div "
3314 "class='val'>%13f</div></summary></details>\n",
3315 limits->viewportBoundsRange[1]);
3317 "\t\t\t\t\t\t<details><summary>viewportSubPixelBits = <div "
3318 "class='val'>%u</div></summary></details>\n",
3319 limits->viewportSubPixelBits);
3321 "\t\t\t\t\t\t<details><summary>minMemoryMapAlignment = <div class='val'>" PRINTF_SIZE_T_SPECIFIER
3322 "</div></summary></details>\n",
3323 limits->minMemoryMapAlignment);
3325 "\t\t\t\t\t\t<details><summary>minTexelBufferOffsetAlignment = <div class='val'>0x%" PRIxLEAST64
3326 "</div></summary></details>\n",
3327 limits->minTexelBufferOffsetAlignment);
3329 "\t\t\t\t\t\t<details><summary>minUniformBufferOffsetAlignment = <div class='val'>0x%" PRIxLEAST64
3330 "</div></summary></details>\n",
3331 limits->minUniformBufferOffsetAlignment);
3333 "\t\t\t\t\t\t<details><summary>minStorageBufferOffsetAlignment = <div class='val'>0x%" PRIxLEAST64
3334 "</div></summary></details>\n",
3335 limits->minStorageBufferOffsetAlignment);
3337 "\t\t\t\t\t\t<details><summary>minTexelOffset = <div "
3338 "class='val'>%3d</div></summary></details>\n",
3339 limits->minTexelOffset);
3341 "\t\t\t\t\t\t<details><summary>maxTexelOffset = <div "
3342 "class='val'>%3d</div></summary></details>\n",
3343 limits->maxTexelOffset);
3345 "\t\t\t\t\t\t<details><summary>minTexelGatherOffset = <div "
3346 "class='val'>%3d</div></summary></details>\n",
3347 limits->minTexelGatherOffset);
3349 "\t\t\t\t\t\t<details><summary>maxTexelGatherOffset = <div "
3350 "class='val'>%3d</div></summary></details>\n",
3351 limits->maxTexelGatherOffset);
3353 "\t\t\t\t\t\t<details><summary>minInterpolationOffset = <div "
3354 "class='val'>%9f</div></summary></details>\n",
3355 limits->minInterpolationOffset);
3357 "\t\t\t\t\t\t<details><summary>maxInterpolationOffset = <div "
3358 "class='val'>%9f</div></summary></details>\n",
3359 limits->maxInterpolationOffset);
3361 "\t\t\t\t\t\t<details><summary>subPixelInterpolationOffsetBits = <div "
3362 "class='val'>%u</div></summary></details>\n",
3363 limits->subPixelInterpolationOffsetBits);
3365 "\t\t\t\t\t\t<details><summary>maxFramebufferWidth = <div "
3366 "class='val'>%u</div></summary></details>\n",
3367 limits->maxFramebufferWidth);
3369 "\t\t\t\t\t\t<details><summary>maxFramebufferHeight = <div "
3370 "class='val'>%u</div></summary></details>\n",
3371 limits->maxFramebufferHeight);
3373 "\t\t\t\t\t\t<details><summary>maxFramebufferLayers = <div "
3374 "class='val'>%u</div></summary></details>\n",
3375 limits->maxFramebufferLayers);
3377 "\t\t\t\t\t\t<details><summary>framebufferColorSampleCounts = <div "
3378 "class='val'>%u</div></summary></details>\n",
3379 limits->framebufferColorSampleCounts);
3381 "\t\t\t\t\t\t<details><summary>framebufferDepthSampleCounts = <div "
3382 "class='val'>%u</div></summary></details>\n",
3383 limits->framebufferDepthSampleCounts);
3385 "\t\t\t\t\t\t<details><summary>framebufferStencilSampleCounts = <div "
3386 "class='val'>%u</div></summary></details>\n",
3387 limits->framebufferStencilSampleCounts);
3389 "\t\t\t\t\t\t<details><summary>framebufferNoAttachmentsSampleCounts = <div "
3390 "class='val'>%u</div></summary></details>\n",
3391 limits->framebufferNoAttachmentsSampleCounts);
3393 "\t\t\t\t\t\t<details><summary>maxColorAttachments = <div "
3394 "class='val'>%u</div></summary></details>\n",
3395 limits->maxColorAttachments);
3397 "\t\t\t\t\t\t<details><summary>sampledImageColorSampleCounts = <div "
3398 "class='val'>%u</div></summary></details>\n",
3399 limits->sampledImageColorSampleCounts);
3401 "\t\t\t\t\t\t<details><summary>sampledImageDepthSampleCounts = <div "
3402 "class='val'>%u</div></summary></details>\n",
3403 limits->sampledImageDepthSampleCounts);
3405 "\t\t\t\t\t\t<details><summary>sampledImageStencilSampleCounts = <div "
3406 "class='val'>%u</div></summary></details>\n",
3407 limits->sampledImageStencilSampleCounts);
3409 "\t\t\t\t\t\t<details><summary>sampledImageIntegerSampleCounts = <div "
3410 "class='val'>%u</div></summary></details>\n",
3411 limits->sampledImageIntegerSampleCounts);
3413 "\t\t\t\t\t\t<details><summary>storageImageSampleCounts = <div "
3414 "class='val'>%u</div></summary></details>\n",
3415 limits->storageImageSampleCounts);
3417 "\t\t\t\t\t\t<details><summary>maxSampleMaskWords = <div "
3418 "class='val'>%u</div></summary></details>\n",
3419 limits->maxSampleMaskWords);
3421 "\t\t\t\t\t\t<details><summary>timestampComputeAndGraphics = <div "
3422 "class='val'>%u</div></summary></details>\n",
3423 limits->timestampComputeAndGraphics);
3425 "\t\t\t\t\t\t<details><summary>timestampPeriod = <div "
3426 "class='val'>%f</div></summary></details>\n",
3427 limits->timestampPeriod);
3429 "\t\t\t\t\t\t<details><summary>maxClipDistances = <div "
3430 "class='val'>%u</div></summary></details>\n",
3431 limits->maxClipDistances);
3433 "\t\t\t\t\t\t<details><summary>maxCullDistances = <div "
3434 "class='val'>%u</div></summary></details>\n",
3435 limits->maxCullDistances);
3437 "\t\t\t\t\t\t<details><summary>maxCombinedClipAndCullDistances = <div "
3438 "class='val'>%u</div></summary></details>\n",
3439 limits->maxCombinedClipAndCullDistances);
3441 "\t\t\t\t\t\t<details><summary>discreteQueuePriorities = <div "
3442 "class='val'>%u</div></summary></details>\n",
3443 limits->discreteQueuePriorities);
3445 "\t\t\t\t\t\t<details><summary>pointSizeRange[0] = <div "
3446 "class='val'>%f</div></summary></details>\n",
3447 limits->pointSizeRange[0]);
3449 "\t\t\t\t\t\t<details><summary>pointSizeRange[1] = <div "
3450 "class='val'>%f</div></summary></details>\n",
3451 limits->pointSizeRange[1]);
3453 "\t\t\t\t\t\t<details><summary>lineWidthRange[0] = <div "
3454 "class='val'>%f</div></summary></details>\n",
3455 limits->lineWidthRange[0]);
3457 "\t\t\t\t\t\t<details><summary>lineWidthRange[1] = <div "
3458 "class='val'>%f</div></summary></details>\n",
3459 limits->lineWidthRange[1]);
3461 "\t\t\t\t\t\t<details><summary>pointSizeGranularity = <div "
3462 "class='val'>%f</div></summary></details>\n",
3463 limits->pointSizeGranularity);
3465 "\t\t\t\t\t\t<details><summary>lineWidthGranularity = <div "
3466 "class='val'>%f</div></summary></details>\n",
3467 limits->lineWidthGranularity);
3469 "\t\t\t\t\t\t<details><summary>strictLines = <div "
3470 "class='val'>%u</div></summary></details>\n",
3471 limits->strictLines);
3473 "\t\t\t\t\t\t<details><summary>standardSampleLocations = <div "
3474 "class='val'>%u</div></summary></details>\n",
3475 limits->standardSampleLocations);
3477 "\t\t\t\t\t\t<details><summary>optimalBufferCopyOffsetAlignment = <div class='val'>0x%" PRIxLEAST64
3478 "</div></summary></details>\n",
3479 limits->optimalBufferCopyOffsetAlignment);
3481 "\t\t\t\t\t\t<details><summary>optimalBufferCopyRowPitchAlignment = <div class='val'>0x%" PRIxLEAST64
3482 "</div></summary></details>\n",
3483 limits->optimalBufferCopyRowPitchAlignment);
3485 "\t\t\t\t\t\t<details><summary>nonCoherentAtomSize = <div class='val'>0x%" PRIxLEAST64
3486 "</div></summary></details>\n",
3487 limits->nonCoherentAtomSize);
3488 fprintf(out, "\t\t\t\t\t</details>\n");
3489 } else if (human_readable_output) {
3490 printf("\tVkPhysicalDeviceLimits:\n");
3491 printf("\t-----------------------\n");
3492 printf("\t\tmaxImageDimension1D = %u\n", limits->maxImageDimension1D);
3493 printf("\t\tmaxImageDimension2D = %u\n", limits->maxImageDimension2D);
3494 printf("\t\tmaxImageDimension3D = %u\n", limits->maxImageDimension3D);
3495 printf("\t\tmaxImageDimensionCube = %u\n", limits->maxImageDimensionCube);
3496 printf("\t\tmaxImageArrayLayers = %u\n", limits->maxImageArrayLayers);
3497 printf("\t\tmaxTexelBufferElements = 0x%" PRIxLEAST32 "\n", limits->maxTexelBufferElements);
3498 printf("\t\tmaxUniformBufferRange = 0x%" PRIxLEAST32 "\n", limits->maxUniformBufferRange);
3499 printf("\t\tmaxStorageBufferRange = 0x%" PRIxLEAST32 "\n", limits->maxStorageBufferRange);
3500 printf("\t\tmaxPushConstantsSize = %u\n", limits->maxPushConstantsSize);
3501 printf("\t\tmaxMemoryAllocationCount = %u\n", limits->maxMemoryAllocationCount);
3502 printf("\t\tmaxSamplerAllocationCount = %u\n", limits->maxSamplerAllocationCount);
3503 printf("\t\tbufferImageGranularity = 0x%" PRIxLEAST64 "\n", limits->bufferImageGranularity);
3504 printf("\t\tsparseAddressSpaceSize = 0x%" PRIxLEAST64 "\n", limits->sparseAddressSpaceSize);
3505 printf("\t\tmaxBoundDescriptorSets = %u\n", limits->maxBoundDescriptorSets);
3506 printf("\t\tmaxPerStageDescriptorSamplers = %u\n", limits->maxPerStageDescriptorSamplers);
3507 printf("\t\tmaxPerStageDescriptorUniformBuffers = %u\n", limits->maxPerStageDescriptorUniformBuffers);
3508 printf("\t\tmaxPerStageDescriptorStorageBuffers = %u\n", limits->maxPerStageDescriptorStorageBuffers);
3509 printf("\t\tmaxPerStageDescriptorSampledImages = %u\n", limits->maxPerStageDescriptorSampledImages);
3510 printf("\t\tmaxPerStageDescriptorStorageImages = %u\n", limits->maxPerStageDescriptorStorageImages);
3511 printf("\t\tmaxPerStageDescriptorInputAttachments = %u\n", limits->maxPerStageDescriptorInputAttachments);
3512 printf("\t\tmaxPerStageResources = %u\n", limits->maxPerStageResources);
3513 printf("\t\tmaxDescriptorSetSamplers = %u\n", limits->maxDescriptorSetSamplers);
3514 printf("\t\tmaxDescriptorSetUniformBuffers = %u\n", limits->maxDescriptorSetUniformBuffers);
3515 printf("\t\tmaxDescriptorSetUniformBuffersDynamic = %u\n", limits->maxDescriptorSetUniformBuffersDynamic);
3516 printf("\t\tmaxDescriptorSetStorageBuffers = %u\n", limits->maxDescriptorSetStorageBuffers);
3517 printf("\t\tmaxDescriptorSetStorageBuffersDynamic = %u\n", limits->maxDescriptorSetStorageBuffersDynamic);
3518 printf("\t\tmaxDescriptorSetSampledImages = %u\n", limits->maxDescriptorSetSampledImages);
3519 printf("\t\tmaxDescriptorSetStorageImages = %u\n", limits->maxDescriptorSetStorageImages);
3520 printf("\t\tmaxDescriptorSetInputAttachments = %u\n", limits->maxDescriptorSetInputAttachments);
3521 printf("\t\tmaxVertexInputAttributes = %u\n", limits->maxVertexInputAttributes);
3522 printf("\t\tmaxVertexInputBindings = %u\n", limits->maxVertexInputBindings);
3523 printf("\t\tmaxVertexInputAttributeOffset = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputAttributeOffset);
3524 printf("\t\tmaxVertexInputBindingStride = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputBindingStride);
3525 printf("\t\tmaxVertexOutputComponents = %u\n", limits->maxVertexOutputComponents);
3526 printf("\t\tmaxTessellationGenerationLevel = %u\n", limits->maxTessellationGenerationLevel);
3527 printf("\t\tmaxTessellationPatchSize = %u\n", limits->maxTessellationPatchSize);
3528 printf("\t\tmaxTessellationControlPerVertexInputComponents = %u\n",
3529 limits->maxTessellationControlPerVertexInputComponents);
3530 printf("\t\tmaxTessellationControlPerVertexOutputComponents = %u\n",
3531 limits->maxTessellationControlPerVertexOutputComponents);
3532 printf("\t\tmaxTessellationControlPerPatchOutputComponents = %u\n",
3533 limits->maxTessellationControlPerPatchOutputComponents);
3534 printf("\t\tmaxTessellationControlTotalOutputComponents = %u\n", limits->maxTessellationControlTotalOutputComponents);
3535 printf("\t\tmaxTessellationEvaluationInputComponents = %u\n", limits->maxTessellationEvaluationInputComponents);
3536 printf("\t\tmaxTessellationEvaluationOutputComponents = %u\n", limits->maxTessellationEvaluationOutputComponents);
3537 printf("\t\tmaxGeometryShaderInvocations = %u\n", limits->maxGeometryShaderInvocations);
3538 printf("\t\tmaxGeometryInputComponents = %u\n", limits->maxGeometryInputComponents);
3539 printf("\t\tmaxGeometryOutputComponents = %u\n", limits->maxGeometryOutputComponents);
3540 printf("\t\tmaxGeometryOutputVertices = %u\n", limits->maxGeometryOutputVertices);
3541 printf("\t\tmaxGeometryTotalOutputComponents = %u\n", limits->maxGeometryTotalOutputComponents);
3542 printf("\t\tmaxFragmentInputComponents = %u\n", limits->maxFragmentInputComponents);
3543 printf("\t\tmaxFragmentOutputAttachments = %u\n", limits->maxFragmentOutputAttachments);
3544 printf("\t\tmaxFragmentDualSrcAttachments = %u\n", limits->maxFragmentDualSrcAttachments);
3545 printf("\t\tmaxFragmentCombinedOutputResources = %u\n", limits->maxFragmentCombinedOutputResources);
3546 printf("\t\tmaxComputeSharedMemorySize = 0x%" PRIxLEAST32 "\n", limits->maxComputeSharedMemorySize);
3547 printf("\t\tmaxComputeWorkGroupCount[0] = %u\n", limits->maxComputeWorkGroupCount[0]);
3548 printf("\t\tmaxComputeWorkGroupCount[1] = %u\n", limits->maxComputeWorkGroupCount[1]);
3549 printf("\t\tmaxComputeWorkGroupCount[2] = %u\n", limits->maxComputeWorkGroupCount[2]);
3550 printf("\t\tmaxComputeWorkGroupInvocations = %u\n", limits->maxComputeWorkGroupInvocations);
3551 printf("\t\tmaxComputeWorkGroupSize[0] = %u\n", limits->maxComputeWorkGroupSize[0]);
3552 printf("\t\tmaxComputeWorkGroupSize[1] = %u\n", limits->maxComputeWorkGroupSize[1]);
3553 printf("\t\tmaxComputeWorkGroupSize[2] = %u\n", limits->maxComputeWorkGroupSize[2]);
3554 printf("\t\tsubPixelPrecisionBits = %u\n", limits->subPixelPrecisionBits);
3555 printf("\t\tsubTexelPrecisionBits = %u\n", limits->subTexelPrecisionBits);
3556 printf("\t\tmipmapPrecisionBits = %u\n", limits->mipmapPrecisionBits);
3557 printf("\t\tmaxDrawIndexedIndexValue = %u\n", limits->maxDrawIndexedIndexValue);
3558 printf("\t\tmaxDrawIndirectCount = %u\n", limits->maxDrawIndirectCount);
3559 printf("\t\tmaxSamplerLodBias = %f\n", limits->maxSamplerLodBias);
3560 printf("\t\tmaxSamplerAnisotropy = %f\n", limits->maxSamplerAnisotropy);
3561 printf("\t\tmaxViewports = %u\n", limits->maxViewports);
3562 printf("\t\tmaxViewportDimensions[0] = %u\n", limits->maxViewportDimensions[0]);
3563 printf("\t\tmaxViewportDimensions[1] = %u\n", limits->maxViewportDimensions[1]);
3564 printf("\t\tviewportBoundsRange[0] = %13f\n", limits->viewportBoundsRange[0]);
3565 printf("\t\tviewportBoundsRange[1] = %13f\n", limits->viewportBoundsRange[1]);
3566 printf("\t\tviewportSubPixelBits = %u\n", limits->viewportSubPixelBits);
3567 printf("\t\tminMemoryMapAlignment = " PRINTF_SIZE_T_SPECIFIER "\n", limits->minMemoryMapAlignment);
3568 printf("\t\tminTexelBufferOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->minTexelBufferOffsetAlignment);
3569 printf("\t\tminUniformBufferOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->minUniformBufferOffsetAlignment);
3570 printf("\t\tminStorageBufferOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->minStorageBufferOffsetAlignment);
3571 printf("\t\tminTexelOffset = %3d\n", limits->minTexelOffset);
3572 printf("\t\tmaxTexelOffset = %3d\n", limits->maxTexelOffset);
3573 printf("\t\tminTexelGatherOffset = %3d\n", limits->minTexelGatherOffset);
3574 printf("\t\tmaxTexelGatherOffset = %3d\n", limits->maxTexelGatherOffset);
3575 printf("\t\tminInterpolationOffset = %9f\n", limits->minInterpolationOffset);
3576 printf("\t\tmaxInterpolationOffset = %9f\n", limits->maxInterpolationOffset);
3577 printf("\t\tsubPixelInterpolationOffsetBits = %u\n", limits->subPixelInterpolationOffsetBits);
3578 printf("\t\tmaxFramebufferWidth = %u\n", limits->maxFramebufferWidth);
3579 printf("\t\tmaxFramebufferHeight = %u\n", limits->maxFramebufferHeight);
3580 printf("\t\tmaxFramebufferLayers = %u\n", limits->maxFramebufferLayers);
3581 printf("\t\tframebufferColorSampleCounts = %u\n", limits->framebufferColorSampleCounts);
3582 printf("\t\tframebufferDepthSampleCounts = %u\n", limits->framebufferDepthSampleCounts);
3583 printf("\t\tframebufferStencilSampleCounts = %u\n", limits->framebufferStencilSampleCounts);
3584 printf("\t\tframebufferNoAttachmentsSampleCounts = %u\n", limits->framebufferNoAttachmentsSampleCounts);
3585 printf("\t\tmaxColorAttachments = %u\n", limits->maxColorAttachments);
3586 printf("\t\tsampledImageColorSampleCounts = %u\n", limits->sampledImageColorSampleCounts);
3587 printf("\t\tsampledImageDepthSampleCounts = %u\n", limits->sampledImageDepthSampleCounts);
3588 printf("\t\tsampledImageStencilSampleCounts = %u\n", limits->sampledImageStencilSampleCounts);
3589 printf("\t\tsampledImageIntegerSampleCounts = %u\n", limits->sampledImageIntegerSampleCounts);
3590 printf("\t\tstorageImageSampleCounts = %u\n", limits->storageImageSampleCounts);
3591 printf("\t\tmaxSampleMaskWords = %u\n", limits->maxSampleMaskWords);
3592 printf("\t\ttimestampComputeAndGraphics = %u\n", limits->timestampComputeAndGraphics);
3593 printf("\t\ttimestampPeriod = %f\n", limits->timestampPeriod);
3594 printf("\t\tmaxClipDistances = %u\n", limits->maxClipDistances);
3595 printf("\t\tmaxCullDistances = %u\n", limits->maxCullDistances);
3596 printf("\t\tmaxCombinedClipAndCullDistances = %u\n", limits->maxCombinedClipAndCullDistances);
3597 printf("\t\tdiscreteQueuePriorities = %u\n", limits->discreteQueuePriorities);
3598 printf("\t\tpointSizeRange[0] = %f\n", limits->pointSizeRange[0]);
3599 printf("\t\tpointSizeRange[1] = %f\n", limits->pointSizeRange[1]);
3600 printf("\t\tlineWidthRange[0] = %f\n", limits->lineWidthRange[0]);
3601 printf("\t\tlineWidthRange[1] = %f\n", limits->lineWidthRange[1]);
3602 printf("\t\tpointSizeGranularity = %f\n", limits->pointSizeGranularity);
3603 printf("\t\tlineWidthGranularity = %f\n", limits->lineWidthGranularity);
3604 printf("\t\tstrictLines = %u\n", limits->strictLines);
3605 printf("\t\tstandardSampleLocations = %u\n", limits->standardSampleLocations);
3606 printf("\t\toptimalBufferCopyOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->optimalBufferCopyOffsetAlignment);
3607 printf("\t\toptimalBufferCopyRowPitchAlignment = 0x%" PRIxLEAST64 "\n", limits->optimalBufferCopyRowPitchAlignment);
3608 printf("\t\tnonCoherentAtomSize = 0x%" PRIxLEAST64 "\n", limits->nonCoherentAtomSize);
3612 printf("\t\t\"limits\": {\n");
3613 printf("\t\t\t\"maxImageDimension1D\": %u,\n", limits->maxImageDimension1D);
3614 printf("\t\t\t\"maxImageDimension2D\": %u,\n", limits->maxImageDimension2D);
3615 printf("\t\t\t\"maxImageDimension3D\": %u,\n", limits->maxImageDimension3D);
3616 printf("\t\t\t\"maxImageDimensionCube\": %u,\n", limits->maxImageDimensionCube);
3617 printf("\t\t\t\"maxImageArrayLayers\": %u,\n", limits->maxImageArrayLayers);
3618 printf("\t\t\t\"maxTexelBufferElements\": %u,\n", limits->maxTexelBufferElements);
3619 printf("\t\t\t\"maxUniformBufferRange\": %u,\n", limits->maxUniformBufferRange);
3620 printf("\t\t\t\"maxStorageBufferRange\": %u,\n", limits->maxStorageBufferRange);
3621 printf("\t\t\t\"maxPushConstantsSize\": %u,\n", limits->maxPushConstantsSize);
3622 printf("\t\t\t\"maxMemoryAllocationCount\": %u,\n", limits->maxMemoryAllocationCount);
3623 printf("\t\t\t\"maxSamplerAllocationCount\": %u,\n", limits->maxSamplerAllocationCount);
3624 printf("\t\t\t\"bufferImageGranularity\": %llu,\n", (unsigned long long)limits->bufferImageGranularity);
3625 printf("\t\t\t\"sparseAddressSpaceSize\": %llu,\n", (unsigned long long)limits->sparseAddressSpaceSize);
3626 printf("\t\t\t\"maxBoundDescriptorSets\": %u,\n", limits->maxBoundDescriptorSets);
3627 printf("\t\t\t\"maxPerStageDescriptorSamplers\": %u,\n", limits->maxPerStageDescriptorSamplers);
3628 printf("\t\t\t\"maxPerStageDescriptorUniformBuffers\": %u,\n", limits->maxPerStageDescriptorUniformBuffers);
3629 printf("\t\t\t\"maxPerStageDescriptorStorageBuffers\": %u,\n", limits->maxPerStageDescriptorStorageBuffers);
3630 printf("\t\t\t\"maxPerStageDescriptorSampledImages\": %u,\n", limits->maxPerStageDescriptorSampledImages);
3631 printf("\t\t\t\"maxPerStageDescriptorStorageImages\": %u,\n", limits->maxPerStageDescriptorStorageImages);
3632 printf("\t\t\t\"maxPerStageDescriptorInputAttachments\": %u,\n", limits->maxPerStageDescriptorInputAttachments);
3633 printf("\t\t\t\"maxPerStageResources\": %u,\n", limits->maxPerStageResources);
3634 printf("\t\t\t\"maxDescriptorSetSamplers\": %u,\n", limits->maxDescriptorSetSamplers);
3635 printf("\t\t\t\"maxDescriptorSetUniformBuffers\": %u,\n", limits->maxDescriptorSetUniformBuffers);
3636 printf("\t\t\t\"maxDescriptorSetUniformBuffersDynamic\": %u,\n", limits->maxDescriptorSetUniformBuffersDynamic);
3637 printf("\t\t\t\"maxDescriptorSetStorageBuffers\": %u,\n", limits->maxDescriptorSetStorageBuffers);
3638 printf("\t\t\t\"maxDescriptorSetStorageBuffersDynamic\": %u,\n", limits->maxDescriptorSetStorageBuffersDynamic);
3639 printf("\t\t\t\"maxDescriptorSetSampledImages\": %u,\n", limits->maxDescriptorSetSampledImages);
3640 printf("\t\t\t\"maxDescriptorSetStorageImages\": %u,\n", limits->maxDescriptorSetStorageImages);
3641 printf("\t\t\t\"maxDescriptorSetInputAttachments\": %u,\n", limits->maxDescriptorSetInputAttachments);
3642 printf("\t\t\t\"maxVertexInputAttributes\": %u,\n", limits->maxVertexInputAttributes);
3643 printf("\t\t\t\"maxVertexInputBindings\": %u,\n", limits->maxVertexInputBindings);
3644 printf("\t\t\t\"maxVertexInputAttributeOffset\": %u,\n", limits->maxVertexInputAttributeOffset);
3645 printf("\t\t\t\"maxVertexInputBindingStride\": %u,\n", limits->maxVertexInputBindingStride);
3646 printf("\t\t\t\"maxVertexOutputComponents\": %u,\n", limits->maxVertexOutputComponents);
3647 printf("\t\t\t\"maxTessellationGenerationLevel\": %u,\n", limits->maxTessellationGenerationLevel);
3648 printf("\t\t\t\"maxTessellationPatchSize\": %u,\n", limits->maxTessellationPatchSize);
3649 printf("\t\t\t\"maxTessellationControlPerVertexInputComponents\": %u,\n",
3650 limits->maxTessellationControlPerVertexInputComponents);
3651 printf("\t\t\t\"maxTessellationControlPerVertexOutputComponents\": %u,\n",
3652 limits->maxTessellationControlPerVertexOutputComponents);
3653 printf("\t\t\t\"maxTessellationControlPerPatchOutputComponents\": %u,\n",
3654 limits->maxTessellationControlPerPatchOutputComponents);
3655 printf("\t\t\t\"maxTessellationControlTotalOutputComponents\": %u,\n", limits->maxTessellationControlTotalOutputComponents);
3656 printf("\t\t\t\"maxTessellationEvaluationInputComponents\": %u,\n", limits->maxTessellationEvaluationInputComponents);
3657 printf("\t\t\t\"maxTessellationEvaluationOutputComponents\": %u,\n", limits->maxTessellationEvaluationOutputComponents);
3658 printf("\t\t\t\"maxGeometryShaderInvocations\": %u,\n", limits->maxGeometryShaderInvocations);
3659 printf("\t\t\t\"maxGeometryInputComponents\": %u,\n", limits->maxGeometryInputComponents);
3660 printf("\t\t\t\"maxGeometryOutputComponents\": %u,\n", limits->maxGeometryOutputComponents);
3661 printf("\t\t\t\"maxGeometryOutputVertices\": %u,\n", limits->maxGeometryOutputVertices);
3662 printf("\t\t\t\"maxGeometryTotalOutputComponents\": %u,\n", limits->maxGeometryTotalOutputComponents);
3663 printf("\t\t\t\"maxFragmentInputComponents\": %u,\n", limits->maxFragmentInputComponents);
3664 printf("\t\t\t\"maxFragmentOutputAttachments\": %u,\n", limits->maxFragmentOutputAttachments);
3665 printf("\t\t\t\"maxFragmentDualSrcAttachments\": %u,\n", limits->maxFragmentDualSrcAttachments);
3666 printf("\t\t\t\"maxFragmentCombinedOutputResources\": %u,\n", limits->maxFragmentCombinedOutputResources);
3667 printf("\t\t\t\"maxComputeSharedMemorySize\": %u,\n", limits->maxComputeSharedMemorySize);
3668 printf("\t\t\t\"maxComputeWorkGroupCount\": [\n");
3669 printf("\t\t\t\t%u,\n", limits->maxComputeWorkGroupCount[0]);
3670 printf("\t\t\t\t%u,\n", limits->maxComputeWorkGroupCount[1]);
3671 printf("\t\t\t\t%u\n", limits->maxComputeWorkGroupCount[2]);
3672 printf("\t\t\t],\n");
3673 printf("\t\t\t\"maxComputeWorkGroupInvocations\": %u,\n", limits->maxComputeWorkGroupInvocations);
3674 printf("\t\t\t\"maxComputeWorkGroupSize\": [\n");
3675 printf("\t\t\t\t%u,\n", limits->maxComputeWorkGroupSize[0]);
3676 printf("\t\t\t\t%u,\n", limits->maxComputeWorkGroupSize[1]);
3677 printf("\t\t\t\t%u\n", limits->maxComputeWorkGroupSize[2]);
3678 printf("\t\t\t],\n");
3679 printf("\t\t\t\"subPixelPrecisionBits\": %u,\n", limits->subPixelPrecisionBits);
3680 printf("\t\t\t\"subTexelPrecisionBits\": %u,\n", limits->subTexelPrecisionBits);
3681 printf("\t\t\t\"mipmapPrecisionBits\": %u,\n", limits->mipmapPrecisionBits);
3682 printf("\t\t\t\"maxDrawIndexedIndexValue\": %u,\n", limits->maxDrawIndexedIndexValue);
3683 printf("\t\t\t\"maxDrawIndirectCount\": %u,\n", limits->maxDrawIndirectCount);
3684 printf("\t\t\t\"maxSamplerLodBias\": %g,\n", limits->maxSamplerLodBias);
3685 printf("\t\t\t\"maxSamplerAnisotropy\": %g,\n", limits->maxSamplerAnisotropy);
3686 printf("\t\t\t\"maxViewports\": %u,\n", limits->maxViewports);
3687 printf("\t\t\t\"maxViewportDimensions\": [\n");
3688 printf("\t\t\t\t%u,\n", limits->maxViewportDimensions[0]);
3689 printf("\t\t\t\t%u\n", limits->maxViewportDimensions[1]);
3690 printf("\t\t\t],\n");
3691 printf("\t\t\t\"viewportBoundsRange\": [\n");
3692 printf("\t\t\t\t%g,\n", limits->viewportBoundsRange[0]);
3693 printf("\t\t\t\t%g\n", limits->viewportBoundsRange[1]);
3694 printf("\t\t\t],\n");
3695 printf("\t\t\t\"viewportSubPixelBits\": %u,\n", limits->viewportSubPixelBits);
3696 printf("\t\t\t\"minMemoryMapAlignment\": " PRINTF_SIZE_T_SPECIFIER ",\n", limits->minMemoryMapAlignment);
3697 printf("\t\t\t\"minTexelBufferOffsetAlignment\": %llu,\n", (unsigned long long)limits->minTexelBufferOffsetAlignment);
3698 printf("\t\t\t\"minUniformBufferOffsetAlignment\": %llu,\n", (unsigned long long)limits->minUniformBufferOffsetAlignment);
3699 printf("\t\t\t\"minStorageBufferOffsetAlignment\": %llu,\n", (unsigned long long)limits->minStorageBufferOffsetAlignment);
3700 printf("\t\t\t\"minTexelOffset\": %d,\n", limits->minTexelOffset);
3701 printf("\t\t\t\"maxTexelOffset\": %u,\n", limits->maxTexelOffset);
3702 printf("\t\t\t\"minTexelGatherOffset\": %d,\n", limits->minTexelGatherOffset);
3703 printf("\t\t\t\"maxTexelGatherOffset\": %u,\n", limits->maxTexelGatherOffset);
3704 printf("\t\t\t\"minInterpolationOffset\": %g,\n", limits->minInterpolationOffset);
3705 printf("\t\t\t\"maxInterpolationOffset\": %g,\n", limits->maxInterpolationOffset);
3706 printf("\t\t\t\"subPixelInterpolationOffsetBits\": %u,\n", limits->subPixelInterpolationOffsetBits);
3707 printf("\t\t\t\"maxFramebufferWidth\": %u,\n", limits->maxFramebufferWidth);
3708 printf("\t\t\t\"maxFramebufferHeight\": %u,\n", limits->maxFramebufferHeight);
3709 printf("\t\t\t\"maxFramebufferLayers\": %u,\n", limits->maxFramebufferLayers);
3710 printf("\t\t\t\"framebufferColorSampleCounts\": %u,\n", limits->framebufferColorSampleCounts);
3711 printf("\t\t\t\"framebufferDepthSampleCounts\": %u,\n", limits->framebufferDepthSampleCounts);
3712 printf("\t\t\t\"framebufferStencilSampleCounts\": %u,\n", limits->framebufferStencilSampleCounts);
3713 printf("\t\t\t\"framebufferNoAttachmentsSampleCounts\": %u,\n", limits->framebufferNoAttachmentsSampleCounts);
3714 printf("\t\t\t\"maxColorAttachments\": %u,\n", limits->maxColorAttachments);
3715 printf("\t\t\t\"sampledImageColorSampleCounts\": %u,\n", limits->sampledImageColorSampleCounts);
3716 printf("\t\t\t\"sampledImageIntegerSampleCounts\": %u,\n", limits->sampledImageIntegerSampleCounts);
3717 printf("\t\t\t\"sampledImageDepthSampleCounts\": %u,\n", limits->sampledImageDepthSampleCounts);
3718 printf("\t\t\t\"sampledImageStencilSampleCounts\": %u,\n", limits->sampledImageStencilSampleCounts);
3719 printf("\t\t\t\"storageImageSampleCounts\": %u,\n", limits->storageImageSampleCounts);
3720 printf("\t\t\t\"maxSampleMaskWords\": %u,\n", limits->maxSampleMaskWords);
3721 printf("\t\t\t\"timestampComputeAndGraphics\": %u,\n", limits->timestampComputeAndGraphics);
3722 printf("\t\t\t\"timestampPeriod\": %g,\n", limits->timestampPeriod);
3723 printf("\t\t\t\"maxClipDistances\": %u,\n", limits->maxClipDistances);
3724 printf("\t\t\t\"maxCullDistances\": %u,\n", limits->maxCullDistances);
3725 printf("\t\t\t\"maxCombinedClipAndCullDistances\": %u,\n", limits->maxCombinedClipAndCullDistances);
3726 printf("\t\t\t\"discreteQueuePriorities\": %u,\n", limits->discreteQueuePriorities);
3727 printf("\t\t\t\"pointSizeRange\": [\n");
3728 printf("\t\t\t\t%g,\n", limits->pointSizeRange[0]);
3729 printf("\t\t\t\t%g\n", limits->pointSizeRange[1]);
3730 printf("\t\t\t],\n");
3731 printf("\t\t\t\"lineWidthRange\": [\n");
3732 printf("\t\t\t\t%g,\n", limits->lineWidthRange[0]);
3733 printf("\t\t\t\t%g\n", limits->lineWidthRange[1]);
3734 printf("\t\t\t],\n");
3735 printf("\t\t\t\"pointSizeGranularity\": %g,\n", limits->pointSizeGranularity);
3736 printf("\t\t\t\"lineWidthGranularity\": %g,\n", limits->lineWidthGranularity);
3737 printf("\t\t\t\"strictLines\": %u,\n", limits->strictLines);
3738 printf("\t\t\t\"standardSampleLocations\": %u,\n", limits->standardSampleLocations);
3739 printf("\t\t\t\"optimalBufferCopyOffsetAlignment\": %llu,\n", (unsigned long long)limits->optimalBufferCopyOffsetAlignment);
3740 printf("\t\t\t\"optimalBufferCopyRowPitchAlignment\": %llu,\n",
3741 (unsigned long long)limits->optimalBufferCopyRowPitchAlignment);
3742 printf("\t\t\t\"nonCoherentAtomSize\": %llu\n", (unsigned long long)limits->nonCoherentAtomSize);
3747 static void AppGpuDumpProps(const struct AppGpu *gpu, FILE *out) {
3748 VkPhysicalDeviceProperties props;
3750 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
3751 gpu->inst->inst_extensions_count)) {
3752 const VkPhysicalDeviceProperties *props2_const = &gpu->props2.properties;
3753 props = *props2_const;
3755 const VkPhysicalDeviceProperties *props_const = &gpu->props;
3756 props = *props_const;
3758 const uint32_t apiVersion = props.apiVersion;
3759 const uint32_t major = VK_VERSION_MAJOR(apiVersion);
3760 const uint32_t minor = VK_VERSION_MINOR(apiVersion);
3761 const uint32_t patch = VK_VERSION_PATCH(apiVersion);
3764 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceProperties</summary>\n");
3766 "\t\t\t\t\t\t<details><summary>apiVersion = <div class='val'>0x%" PRIxLEAST32
3767 "</div> (<div class='val'>%d.%d.%d</div>)</summary></details>\n",
3768 apiVersion, major, minor, patch);
3770 "\t\t\t\t\t\t<details><summary>driverVersion = <div class='val'>%u</div> (<div class='val'>0x%" PRIxLEAST32
3771 "</div>)</summary></details>\n",
3772 props.driverVersion, props.driverVersion);
3773 fprintf(out, "\t\t\t\t\t\t<details><summary>vendorID = <div class='val'>0x%04x</div></summary></details>\n",
3775 fprintf(out, "\t\t\t\t\t\t<details><summary>deviceID = <div class='val'>0x%04x</div></summary></details>\n",
3777 fprintf(out, "\t\t\t\t\t\t<details><summary>deviceType = %s</summary></details>\n",
3778 VkPhysicalDeviceTypeString(props.deviceType));
3779 fprintf(out, "\t\t\t\t\t\t<details><summary>deviceName = %s</summary></details>\n", props.deviceName);
3780 fprintf(out, "\t\t\t\t\t</details>\n");
3781 } else if (human_readable_output) {
3782 printf("VkPhysicalDeviceProperties:\n");
3783 printf("===========================\n");
3784 printf("\tapiVersion = 0x%" PRIxLEAST32 " (%d.%d.%d)\n", apiVersion, major, minor, patch);
3785 printf("\tdriverVersion = %u (0x%" PRIxLEAST32 ")\n", props.driverVersion, props.driverVersion);
3786 printf("\tvendorID = 0x%04x\n", props.vendorID);
3787 printf("\tdeviceID = 0x%04x\n", props.deviceID);
3788 printf("\tdeviceType = %s\n", VkPhysicalDeviceTypeString(props.deviceType));
3789 printf("\tdeviceName = %s\n", props.deviceName);
3793 printf("\t\"VkPhysicalDeviceProperties\": {\n");
3794 printf("\t\t\"apiVersion\": %u,\n", apiVersion);
3795 printf("\t\t\"driverVersion\": %u,\n", props.driverVersion);
3796 printf("\t\t\"vendorID\": %u,\n", props.vendorID);
3797 printf("\t\t\"deviceID\": %u,\n", props.deviceID);
3798 printf("\t\t\"deviceType\": %u,\n", props.deviceType);
3799 printf("\t\t\"deviceName\": \"%s\",\n", props.deviceName);
3800 printf("\t\t\"pipelineCacheUUID\": [");
3801 for (uint32_t i = 0; i < VK_UUID_SIZE; ++i) {
3806 printf("\t\t\t%u", props.pipelineCacheUUID[i]);
3812 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
3813 gpu->inst->inst_extensions_count)) {
3814 AppDumpLimits(&gpu->props2.properties.limits, out);
3816 AppDumpLimits(&gpu->props.limits, out);
3819 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
3820 gpu->inst->inst_extensions_count)) {
3821 AppDumpSparseProps(&gpu->props2.properties.sparseProperties, out);
3823 AppDumpSparseProps(&gpu->props.sparseProperties, out);
3830 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
3831 gpu->inst->inst_extensions_count)) {
3832 void *place = gpu->props2.pNext;
3834 struct VkStructureHeader *structure = (struct VkStructureHeader *)place;
3835 if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT &&
3836 CheckPhysicalDeviceExtensionIncluded(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, gpu->device_extensions,
3837 gpu->device_extension_count)) {
3838 VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT *blend_op_adv_props =
3839 (VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT *)structure;
3841 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceBlendOperationAdvancedProperties</summary>\n");
3843 "\t\t\t\t\t\t<details><summary>advancedBlendMaxColorAttachments = <div "
3844 "class='val'>%u</div></summary></details>\n",
3845 blend_op_adv_props->advancedBlendMaxColorAttachments);
3847 "\t\t\t\t\t\t<details><summary>advancedBlendIndependentBlend = <div "
3848 "class='val'>%u</div></summary></details>\n",
3849 blend_op_adv_props->advancedBlendIndependentBlend);
3851 "\t\t\t\t\t\t<details><summary>advancedBlendNonPremultipliedSrcColor = <div "
3852 "class='val'>%u</div></summary></details>\n",
3853 blend_op_adv_props->advancedBlendNonPremultipliedSrcColor);
3855 "\t\t\t\t\t\t<details><summary>advancedBlendNonPremultipliedDstColor = <div "
3856 "class='val'>%u</div></summary></details>\n",
3857 blend_op_adv_props->advancedBlendNonPremultipliedDstColor);
3859 "\t\t\t\t\t\t<details><summary>advancedBlendCorrelatedOverlap = <div "
3860 "class='val'>%u</div></summary></details>\n",
3861 blend_op_adv_props->advancedBlendCorrelatedOverlap);
3863 "\t\t\t\t\t\t<details><summary>advancedBlendAllOperations = <div "
3864 "class='val'>%u</div></summary></details>\n",
3865 blend_op_adv_props->advancedBlendAllOperations);
3866 fprintf(out, "\t\t\t\t\t</details>\n");
3867 } else if (human_readable_output) {
3868 printf("\nVkPhysicalDeviceBlendOperationAdvancedProperties:\n");
3869 printf("=================================================\n");
3870 printf("\tadvancedBlendMaxColorAttachments = %u\n",
3871 blend_op_adv_props->advancedBlendMaxColorAttachments);
3872 printf("\tadvancedBlendIndependentBlend = %u\n",
3873 blend_op_adv_props->advancedBlendIndependentBlend);
3874 printf("\tadvancedBlendNonPremultipliedSrcColor = %u\n",
3875 blend_op_adv_props->advancedBlendNonPremultipliedSrcColor);
3876 printf("\tadvancedBlendNonPremultipliedDstColor = %u\n",
3877 blend_op_adv_props->advancedBlendNonPremultipliedDstColor);
3878 printf("\tadvancedBlendCorrelatedOverlap = %u\n",
3879 blend_op_adv_props->advancedBlendCorrelatedOverlap);
3880 printf("\tadvancedBlendAllOperations = %u\n",
3881 blend_op_adv_props->advancedBlendAllOperations);
3883 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR &&
3884 CheckPhysicalDeviceExtensionIncluded(VK_KHR_MAINTENANCE2_EXTENSION_NAME, gpu->device_extensions,
3885 gpu->device_extension_count)) {
3886 VkPhysicalDevicePointClippingPropertiesKHR *pt_clip_props = (VkPhysicalDevicePointClippingPropertiesKHR *)structure;
3888 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDevicePointClippingProperties</summary>\n");
3890 "\t\t\t\t\t\t<details><summary>pointClippingBehavior = <div "
3891 "class='val'>%u</div></summary></details>\n",
3892 pt_clip_props->pointClippingBehavior);
3893 fprintf(out, "\t\t\t\t\t</details>\n");
3894 } else if (human_readable_output) {
3895 printf("\nVkPhysicalDevicePointClippingProperties:\n");
3896 printf("========================================\n");
3897 printf("\tpointClippingBehavior = %u\n", pt_clip_props->pointClippingBehavior);
3899 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR &&
3900 CheckPhysicalDeviceExtensionIncluded(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, gpu->device_extensions,
3901 gpu->device_extension_count)) {
3902 VkPhysicalDevicePushDescriptorPropertiesKHR *push_desc_props =
3903 (VkPhysicalDevicePushDescriptorPropertiesKHR *)structure;
3905 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDevicePushDescriptorProperties</summary>\n");
3907 "\t\t\t\t\t\t<details><summary>maxPushDescriptors = <div "
3908 "class='val'>%u</div></summary></details>\n",
3909 push_desc_props->maxPushDescriptors);
3910 fprintf(out, "\t\t\t\t\t</details>\n");
3911 } else if (human_readable_output) {
3912 printf("\nVkPhysicalDevicePushDescriptorProperties:\n");
3913 printf("=========================================\n");
3914 printf("\tmaxPushDescriptors = %u\n", push_desc_props->maxPushDescriptors);
3916 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT &&
3917 CheckPhysicalDeviceExtensionIncluded(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME, gpu->device_extensions,
3918 gpu->device_extension_count)) {
3919 VkPhysicalDeviceDiscardRectanglePropertiesEXT *discard_rect_props =
3920 (VkPhysicalDeviceDiscardRectanglePropertiesEXT *)structure;
3922 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceDiscardRectangleProperties</summary>\n");
3924 "\t\t\t\t\t\t<details><summary>maxDiscardRectangles = <div "
3925 "class='val'>%u</div></summary></details>\n",
3926 discard_rect_props->maxDiscardRectangles);
3927 fprintf(out, "\t\t\t\t\t</details>\n");
3928 } else if (human_readable_output) {
3929 printf("\nVkPhysicalDeviceDiscardRectangleProperties:\n");
3930 printf("===========================================\n");
3931 printf("\tmaxDiscardRectangles = %u\n", discard_rect_props->maxDiscardRectangles);
3933 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR &&
3934 CheckPhysicalDeviceExtensionIncluded(VK_KHR_MULTIVIEW_EXTENSION_NAME, gpu->device_extensions,
3935 gpu->device_extension_count)) {
3936 VkPhysicalDeviceMultiviewPropertiesKHR *multiview_props = (VkPhysicalDeviceMultiviewPropertiesKHR *)structure;
3938 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceMultiviewProperties</summary>\n");
3941 "\t\t\t\t\t\t<details><summary>maxMultiviewViewCount = <div class='val'>%u</div></summary></details>\n",
3942 multiview_props->maxMultiviewViewCount);
3945 "\t\t\t\t\t\t<details><summary>maxMultiviewInstanceIndex = <div class='val'>%u</div></summary></details>\n",
3946 multiview_props->maxMultiviewInstanceIndex);
3947 fprintf(out, "\t\t\t\t\t</details>\n");
3948 } else if (human_readable_output) {
3949 printf("\nVkPhysicalDeviceMultiviewProperties:\n");
3950 printf("====================================\n");
3951 printf("\tmaxMultiviewViewCount = %u\n", multiview_props->maxMultiviewViewCount);
3952 printf("\tmaxMultiviewInstanceIndex = %u\n", multiview_props->maxMultiviewInstanceIndex);
3954 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR) {
3955 VkPhysicalDeviceMaintenance3PropertiesKHR *maintenance3_props =
3956 (VkPhysicalDeviceMaintenance3PropertiesKHR *)structure;
3958 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceMaintenance3Properties</summary>\n");
3960 "\t\t\t\t\t\t<details><summary>maxPerSetDescriptors = <div class='val'>%" PRIuLEAST32
3961 "</div></summary></details>\n",
3962 maintenance3_props->maxPerSetDescriptors);
3964 "\t\t\t\t\t\t<details><summary>maxMemoryAllocationSize = <div class='val'>%" PRIuLEAST64
3965 "</div></summary></details>\n",
3966 maintenance3_props->maxMemoryAllocationSize);
3967 fprintf(out, "\t\t\t\t\t</details>\n");
3968 } else if (human_readable_output) {
3969 printf("\nVkPhysicalDeviceMaintenance3Properties:\n");
3970 printf("=======================================\n");
3971 printf("\tmaxPerSetDescriptors = %" PRIuLEAST32 "\n", maintenance3_props->maxPerSetDescriptors);
3972 printf("\tmaxMemoryAllocationSize = %" PRIuLEAST64 "\n", maintenance3_props->maxMemoryAllocationSize);
3974 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR) {
3975 const VkPhysicalDeviceIDPropertiesKHR *id_props = (VkPhysicalDeviceIDPropertiesKHR *)structure;
3977 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceIDProperties</summary>\n");
3978 // Visual Studio 2013's printf does not support the "hh"
3979 // length modifier so cast the operands and use field width
3982 "\t\t\t\t\t\t<details><summary>deviceUUID = <div "
3983 "class='val'>%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x</div></summary></"
3985 (uint32_t)id_props->deviceUUID[0], (uint32_t)id_props->deviceUUID[1], (uint32_t)id_props->deviceUUID[2],
3986 (uint32_t)id_props->deviceUUID[3], (uint32_t)id_props->deviceUUID[4], (uint32_t)id_props->deviceUUID[5],
3987 (uint32_t)id_props->deviceUUID[6], (uint32_t)id_props->deviceUUID[7], (uint32_t)id_props->deviceUUID[8],
3988 (uint32_t)id_props->deviceUUID[9], (uint32_t)id_props->deviceUUID[10],
3989 (uint32_t)id_props->deviceUUID[11], (uint32_t)id_props->deviceUUID[12],
3990 (uint32_t)id_props->deviceUUID[13], (uint32_t)id_props->deviceUUID[14],
3991 (uint32_t)id_props->deviceUUID[15]);
3993 "\t\t\t\t\t\t<details><summary>driverUUID = <div "
3994 "class='val'>%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x</div></summary></"
3996 (uint32_t)id_props->driverUUID[0], (uint32_t)id_props->driverUUID[1], (uint32_t)id_props->driverUUID[2],
3997 (uint32_t)id_props->driverUUID[3], (uint32_t)id_props->driverUUID[4], (uint32_t)id_props->driverUUID[5],
3998 (uint32_t)id_props->driverUUID[6], (uint32_t)id_props->driverUUID[7], (uint32_t)id_props->driverUUID[8],
3999 (uint32_t)id_props->driverUUID[9], (uint32_t)id_props->driverUUID[10],
4000 (uint32_t)id_props->driverUUID[11], (uint32_t)id_props->driverUUID[12],
4001 (uint32_t)id_props->driverUUID[13], (uint32_t)id_props->driverUUID[14],
4002 (uint32_t)id_props->driverUUID[15]);
4003 fprintf(out, "\t\t\t\t\t\t<details><summary>deviceLUIDValid = <div class='val'>%s</div></summary></details>\n",
4004 id_props->deviceLUIDValid ? "true" : "false");
4005 if (id_props->deviceLUIDValid) {
4007 "\t\t\t\t\t\t<details><summary>deviceLUID = <div "
4008 "class='val'>%02x%02x%02x%02x-%02x%02x%02x%02x</div></summary></details>\n",
4009 (uint32_t)id_props->deviceLUID[0], (uint32_t)id_props->deviceLUID[1],
4010 (uint32_t)id_props->deviceLUID[2], (uint32_t)id_props->deviceLUID[3],
4011 (uint32_t)id_props->deviceLUID[4], (uint32_t)id_props->deviceLUID[5],
4012 (uint32_t)id_props->deviceLUID[6], (uint32_t)id_props->deviceLUID[7]);
4015 "\t\t\t\t\t\t<details><summary>deviceNodeMask = <div class='val'>0x%08x</div></summary></details>\n",
4016 id_props->deviceNodeMask);
4018 fprintf(out, "\t\t\t\t\t</details>\n");
4019 } else if (human_readable_output) {
4020 printf("\nVkPhysicalDeviceIDProperties:\n");
4021 printf("=========================================\n");
4022 printf("\tdeviceUUID = %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
4023 (uint32_t)id_props->deviceUUID[0], (uint32_t)id_props->deviceUUID[1], (uint32_t)id_props->deviceUUID[2],
4024 (uint32_t)id_props->deviceUUID[3], (uint32_t)id_props->deviceUUID[4], (uint32_t)id_props->deviceUUID[5],
4025 (uint32_t)id_props->deviceUUID[6], (uint32_t)id_props->deviceUUID[7], (uint32_t)id_props->deviceUUID[8],
4026 (uint32_t)id_props->deviceUUID[9], (uint32_t)id_props->deviceUUID[10],
4027 (uint32_t)id_props->deviceUUID[11], (uint32_t)id_props->deviceUUID[12],
4028 (uint32_t)id_props->deviceUUID[13], (uint32_t)id_props->deviceUUID[14],
4029 (uint32_t)id_props->deviceUUID[15]);
4030 printf("\tdriverUUID = %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
4031 (uint32_t)id_props->driverUUID[0], (uint32_t)id_props->driverUUID[1], (uint32_t)id_props->driverUUID[2],
4032 (uint32_t)id_props->driverUUID[3], (uint32_t)id_props->driverUUID[4], (uint32_t)id_props->driverUUID[5],
4033 (uint32_t)id_props->driverUUID[6], (uint32_t)id_props->driverUUID[7], (uint32_t)id_props->driverUUID[8],
4034 (uint32_t)id_props->driverUUID[9], (uint32_t)id_props->driverUUID[10],
4035 (uint32_t)id_props->driverUUID[11], (uint32_t)id_props->driverUUID[12],
4036 (uint32_t)id_props->driverUUID[13], (uint32_t)id_props->driverUUID[14],
4037 (uint32_t)id_props->driverUUID[15]);
4038 printf("\tdeviceLUIDValid = %s\n", id_props->deviceLUIDValid ? "true" : "false");
4039 if (id_props->deviceLUIDValid) {
4040 printf("\tdeviceLUID = %02x%02x%02x%02x-%02x%02x%02x%02x\n", (uint32_t)id_props->deviceLUID[0],
4041 (uint32_t)id_props->deviceLUID[1], (uint32_t)id_props->deviceLUID[2],
4042 (uint32_t)id_props->deviceLUID[3], (uint32_t)id_props->deviceLUID[4],
4043 (uint32_t)id_props->deviceLUID[5], (uint32_t)id_props->deviceLUID[6],
4044 (uint32_t)id_props->deviceLUID[7]);
4045 printf("\tdeviceNodeMask = 0x%08x\n", id_props->deviceNodeMask);
4048 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR &&
4049 CheckPhysicalDeviceExtensionIncluded(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, gpu->device_extensions,
4050 gpu->device_extension_count)) {
4051 VkPhysicalDeviceDriverPropertiesKHR *driver_props = (VkPhysicalDeviceDriverPropertiesKHR *)structure;
4053 fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceDriverProperties</summary>\n");
4055 "\t\t\t\t\t\t<details><summary>driverID = <div class='val'>%" PRIuLEAST32
4056 "</div></summary></details>\n",
4057 driver_props->driverID);
4058 fprintf(out, "\t\t\t\t\t\t<details><summary>driverName = %s</summary></details>\n", driver_props->driverName);
4059 fprintf(out, "\t\t\t\t\t\t<details><summary>driverInfo = %s</summary></details>\n", driver_props->driverInfo);
4060 fprintf(out, "\t\t\t\t\t\t<details><summary>conformanceVersion:</summary></details>\n");
4062 "\t\t\t\t\t\t\t<details><summary>major = <div class='val'>%" PRIuLEAST8
4063 "</div></summary></details>\n",
4064 driver_props->conformanceVersion.major);
4066 "\t\t\t\t\t\t\t<details><summary>minor = <div class='val'>%" PRIuLEAST8
4067 "</div></summary></details>\n",
4068 driver_props->conformanceVersion.minor);
4070 "\t\t\t\t\t\t\t<details><summary>subminor = <div class='val'>%" PRIuLEAST8
4071 "</div></summary></details>\n",
4072 driver_props->conformanceVersion.subminor);
4074 "\t\t\t\t\t\t\t<details><summary>patch = <div class='val'>%" PRIuLEAST8
4075 "</div></summary></details>\n",
4076 driver_props->conformanceVersion.patch);
4077 fprintf(out, "\t\t\t\t\t</details>\n");
4078 } else if (human_readable_output) {
4079 printf("\nVkPhysicalDeviceDriverProperties:\n");
4080 printf("=================================\n");
4081 printf("\tdriverID = %" PRIuLEAST32 "\n", driver_props->driverID);
4082 printf("\tdriverName = %s\n", driver_props->driverName);
4083 printf("\tdriverInfo = %s\n", driver_props->driverInfo);
4084 printf("\tconformanceVersion:\n");
4085 printf("\t\tmajor = %" PRIuLEAST8 "\n", driver_props->conformanceVersion.major);
4086 printf("\t\tminor = %" PRIuLEAST8 "\n", driver_props->conformanceVersion.minor);
4087 printf("\t\tsubminor = %" PRIuLEAST8 "\n", driver_props->conformanceVersion.subminor);
4088 printf("\t\tpatch = %" PRIuLEAST8 "\n", driver_props->conformanceVersion.patch);
4090 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR &&
4091 CheckPhysicalDeviceExtensionIncluded(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME, gpu->device_extensions,
4092 gpu->device_extension_count)) {
4093 VkPhysicalDeviceFloatControlsPropertiesKHR *float_control_props =
4094 (VkPhysicalDeviceFloatControlsPropertiesKHR *)structure;
4096 fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceFloatControlsProperties</summary>\n");
4098 "\t\t\t\t\t\t<details><summary>separateDenormSettings = <div class='val'>%" PRIuLEAST32
4099 "</div></summary></details>\n",
4100 float_control_props->separateDenormSettings);
4102 "\t\t\t\t\t\t<details><summary>separateRoundingModeSettings = <div class='val'>%" PRIuLEAST32
4103 "</div></summary></details>\n",
4104 float_control_props->separateRoundingModeSettings);
4106 "\t\t\t\t\t\t<details><summary>shaderSignedZeroInfNanPreserveFloat16 = <div class='val'>%" PRIuLEAST32
4107 "</div></summary></details>\n",
4108 float_control_props->shaderSignedZeroInfNanPreserveFloat16);
4110 "\t\t\t\t\t\t<details><summary>shaderSignedZeroInfNanPreserveFloat32 = <div class='val'>%" PRIuLEAST32
4111 "</div></summary></details>\n",
4112 float_control_props->shaderSignedZeroInfNanPreserveFloat32);
4114 "\t\t\t\t\t\t<details><summary>shaderSignedZeroInfNanPreserveFloat64 = <div class='val'>%" PRIuLEAST32
4115 "</div></summary></details>\n",
4116 float_control_props->shaderSignedZeroInfNanPreserveFloat64);
4118 "\t\t\t\t\t\t<details><summary>shaderDenormPreserveFloat16 = <div class='val'>%" PRIuLEAST32
4119 "</div></summary></details>\n",
4120 float_control_props->shaderDenormPreserveFloat16);
4122 "\t\t\t\t\t\t<details><summary>shaderDenormPreserveFloat32 = <div class='val'>%" PRIuLEAST32
4123 "</div></summary></details>\n",
4124 float_control_props->shaderDenormPreserveFloat32);
4126 "\t\t\t\t\t\t<details><summary>shaderDenormPreserveFloat64 = <div class='val'>%" PRIuLEAST32
4127 "</div></summary></details>\n",
4128 float_control_props->shaderDenormPreserveFloat64);
4130 "\t\t\t\t\t\t<details><summary>shaderDenormFlushToZeroFloat16 = <div class='val'>%" PRIuLEAST32
4131 "</div></summary></details>\n",
4132 float_control_props->shaderDenormFlushToZeroFloat16);
4134 "\t\t\t\t\t\t<details><summary>shaderDenormFlushToZeroFloat32 = <div class='val'>%" PRIuLEAST32
4135 "</div></summary></details>\n",
4136 float_control_props->shaderDenormFlushToZeroFloat32);
4138 "\t\t\t\t\t\t<details><summary>shaderDenormFlushToZeroFloat64 = <div class='val'>%" PRIuLEAST32
4139 "</div></summary></details>\n",
4140 float_control_props->shaderDenormFlushToZeroFloat64);
4142 "\t\t\t\t\t\t<details><summary>shaderRoundingModeRTEFloat16 = <div class='val'>%" PRIuLEAST32
4143 "</div></summary></details>\n",
4144 float_control_props->shaderRoundingModeRTEFloat16);
4146 "\t\t\t\t\t\t<details><summary>shaderRoundingModeRTEFloat32 = <div class='val'>%" PRIuLEAST32
4147 "</div></summary></details>\n",
4148 float_control_props->shaderRoundingModeRTEFloat32);
4150 "\t\t\t\t\t\t<details><summary>shaderRoundingModeRTEFloat64 = <div class='val'>%" PRIuLEAST32
4151 "</div></summary></details>\n",
4152 float_control_props->shaderRoundingModeRTEFloat64);
4154 "\t\t\t\t\t\t<details><summary>shaderRoundingModeRTZFloat16 = <div class='val'>%" PRIuLEAST32
4155 "</div></summary></details>\n",
4156 float_control_props->shaderRoundingModeRTZFloat16);
4158 "\t\t\t\t\t\t<details><summary>shaderRoundingModeRTZFloat32 = <div class='val'>%" PRIuLEAST32
4159 "</div></summary></details>\n",
4160 float_control_props->shaderRoundingModeRTZFloat32);
4162 "\t\t\t\t\t\t<details><summary>shaderRoundingModeRTZFloat64 = <div class='val'>%" PRIuLEAST32
4163 "</div></summary></details>\n",
4164 float_control_props->shaderRoundingModeRTZFloat64);
4165 fprintf(out, "\t\t\t\t\t</details>\n");
4166 } else if (human_readable_output) {
4167 printf("\nVkPhysicalDeviceFloatControlsProperties:\n");
4168 printf("========================================\n");
4169 printf("\tseparateDenormSettings = %" PRIuLEAST32 "\n", float_control_props->separateDenormSettings);
4170 printf("\tseparateRoundingModeSettings = %" PRIuLEAST32 "\n",
4171 float_control_props->separateRoundingModeSettings);
4172 printf("\tshaderSignedZeroInfNanPreserveFloat16 = %" PRIuLEAST32 "\n",
4173 float_control_props->shaderSignedZeroInfNanPreserveFloat16);
4174 printf("\tshaderSignedZeroInfNanPreserveFloat32 = %" PRIuLEAST32 "\n",
4175 float_control_props->shaderSignedZeroInfNanPreserveFloat32);
4176 printf("\tshaderSignedZeroInfNanPreserveFloat64 = %" PRIuLEAST32 "\n",
4177 float_control_props->shaderSignedZeroInfNanPreserveFloat64);
4178 printf("\tshaderDenormPreserveFloat16 = %" PRIuLEAST32 "\n",
4179 float_control_props->shaderDenormPreserveFloat16);
4180 printf("\tshaderDenormPreserveFloat32 = %" PRIuLEAST32 "\n",
4181 float_control_props->shaderDenormPreserveFloat32);
4182 printf("\tshaderDenormPreserveFloat64 = %" PRIuLEAST32 "\n",
4183 float_control_props->shaderDenormPreserveFloat64);
4184 printf("\tshaderDenormFlushToZeroFloat16 = %" PRIuLEAST32 "\n",
4185 float_control_props->shaderDenormFlushToZeroFloat16);
4186 printf("\tshaderDenormFlushToZeroFloat32 = %" PRIuLEAST32 "\n",
4187 float_control_props->shaderDenormFlushToZeroFloat32);
4188 printf("\tshaderDenormFlushToZeroFloat64 = %" PRIuLEAST32 "\n",
4189 float_control_props->shaderDenormFlushToZeroFloat64);
4190 printf("\tshaderRoundingModeRTEFloat16 = %" PRIuLEAST32 "\n",
4191 float_control_props->shaderRoundingModeRTEFloat16);
4192 printf("\tshaderRoundingModeRTEFloat32 = %" PRIuLEAST32 "\n",
4193 float_control_props->shaderRoundingModeRTEFloat32);
4194 printf("\tshaderRoundingModeRTEFloat64 = %" PRIuLEAST32 "\n",
4195 float_control_props->shaderRoundingModeRTEFloat64);
4196 printf("\tshaderRoundingModeRTZFloat16 = %" PRIuLEAST32 "\n",
4197 float_control_props->shaderRoundingModeRTZFloat16);
4198 printf("\tshaderRoundingModeRTZFloat32 = %" PRIuLEAST32 "\n",
4199 float_control_props->shaderRoundingModeRTZFloat32);
4200 printf("\tshaderRoundingModeRTZFloat64 = %" PRIuLEAST32 "\n",
4201 float_control_props->shaderRoundingModeRTZFloat64);
4203 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT &&
4204 CheckPhysicalDeviceExtensionIncluded(VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, gpu->device_extensions,
4205 gpu->device_extension_count)) {
4206 VkPhysicalDevicePCIBusInfoPropertiesEXT *pci_bus_properties = (VkPhysicalDevicePCIBusInfoPropertiesEXT *)structure;
4208 fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDevicePCIBusInfoProperties</summary>\n");
4210 "\t\t\t\t\t\t<details><summary>pciDomain = <div class='val'>%" PRIuLEAST32
4211 "</div></summary></details>\n",
4212 pci_bus_properties->pciDomain);
4214 "\t\t\t\t\t\t<details><summary>pciBus = <div class='val'>%" PRIuLEAST32
4215 "</div></summary></details>\n",
4216 pci_bus_properties->pciBus);
4218 "\t\t\t\t\t\t<details><summary>pciDevice = <div class='val'>%" PRIuLEAST32
4219 "</div></summary></details>\n",
4220 pci_bus_properties->pciDevice);
4222 "\t\t\t\t\t\t<details><summary>pciFunction = <div class='val'>%" PRIuLEAST32
4223 "</div></summary></details>\n",
4224 pci_bus_properties->pciFunction);
4225 } else if (human_readable_output) {
4226 printf("\nVkPhysicalDevicePCIBusInfoProperties\n");
4227 printf("====================================\n");
4228 printf("\tpciDomain = %" PRIuLEAST32 "\n", pci_bus_properties->pciDomain);
4229 printf("\tpciBus = %" PRIuLEAST32 "\n", pci_bus_properties->pciBus);
4230 printf("\tpciDevice = %" PRIuLEAST32 "\n", pci_bus_properties->pciDevice);
4231 printf("\tpciFunction = %" PRIuLEAST32 "\n", pci_bus_properties->pciFunction);
4233 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT &&
4234 CheckPhysicalDeviceExtensionIncluded(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, gpu->device_extensions,
4235 gpu->device_extension_count)) {
4236 VkPhysicalDeviceTransformFeedbackPropertiesEXT *transform_feedback_properties =
4237 (VkPhysicalDeviceTransformFeedbackPropertiesEXT *)structure;
4239 fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceTransformFeedbackProperties</summary>\n");
4242 "\t\t\t\t\t\t<details><summary>maxTransformFeedbackStreams = <div class='val'>%" PRIuLEAST32
4243 "</div></summary></details>\n",
4244 transform_feedback_properties->maxTransformFeedbackStreams);
4247 "\t\t\t\t\t\t<details><summary>maxTransformFeedbackBuffers = <div class='val'>%" PRIuLEAST32
4248 "</div></summary></details>\n",
4249 transform_feedback_properties->maxTransformFeedbackBuffers);
4252 "\t\t\t\t\t\t<details><summary>maxTransformFeedbackBufferSize = <div class='val'>%" PRIuLEAST64
4253 "</div></summary></details>\n",
4254 transform_feedback_properties->maxTransformFeedbackBufferSize);
4257 "\t\t\t\t\t\t<details><summary>maxTransformFeedbackStreamDataSize = <div class='val'>%" PRIuLEAST32
4258 "</div></summary></details>\n",
4259 transform_feedback_properties->maxTransformFeedbackStreamDataSize);
4262 "\t\t\t\t\t\t<details><summary>maxTransformFeedbackBufferDataSize = <div class='val'>%" PRIuLEAST32
4263 "</div></summary></details>\n",
4264 transform_feedback_properties->maxTransformFeedbackBufferDataSize);
4267 "\t\t\t\t\t\t<details><summary>maxTransformFeedbackBufferDataStride = <div class='val'>%" PRIuLEAST32
4268 "</div></summary></details>\n",
4269 transform_feedback_properties->maxTransformFeedbackBufferDataStride);
4272 "\t\t\t\t\t\t<details><summary>transformFeedbackQueries = <div class='val'>%" PRIuLEAST32
4273 "</div></summary></details>\n",
4274 transform_feedback_properties->transformFeedbackQueries);
4277 "\t\t\t\t\t\t<details><summary>transformFeedbackStreamsLinesTriangles = <div class='val'>%" PRIuLEAST32
4278 "</div></summary></details>\n",
4279 transform_feedback_properties->transformFeedbackStreamsLinesTriangles);
4282 "\t\t\t\t\t\t<details><summary>transformFeedbackRasterizationStreamSelect = <div class='val'>%" PRIuLEAST32
4283 "</div></summary></details>\n",
4284 transform_feedback_properties->transformFeedbackRasterizationStreamSelect);
4287 "\t\t\t\t\t\t<details><summary>transformFeedbackDraw = <div class='val'>%" PRIuLEAST32
4288 "</div></summary></details>\n",
4289 transform_feedback_properties->transformFeedbackDraw);
4290 } else if (human_readable_output) {
4291 printf("\nVkPhysicalDeviceTransformFeedbackProperties\n");
4292 printf("===========================================\n");
4293 printf("\tmaxTransformFeedbackStreams = %" PRIuLEAST32 "\n",
4294 transform_feedback_properties->maxTransformFeedbackStreams);
4295 printf("\tmaxTransformFeedbackBuffers = %" PRIuLEAST32 "\n",
4296 transform_feedback_properties->maxTransformFeedbackBuffers);
4297 printf("\tmaxTransformFeedbackBufferSize = %" PRIuLEAST64 "\n",
4298 transform_feedback_properties->maxTransformFeedbackBufferSize);
4299 printf("\tmaxTransformFeedbackStreamDataSize = %" PRIuLEAST32 "\n",
4300 transform_feedback_properties->maxTransformFeedbackStreamDataSize);
4301 printf("\tmaxTransformFeedbackBufferDataSize = %" PRIuLEAST32 "\n",
4302 transform_feedback_properties->maxTransformFeedbackBufferDataSize);
4303 printf("\tmaxTransformFeedbackBufferDataStride = %" PRIuLEAST32 "\n",
4304 transform_feedback_properties->maxTransformFeedbackBufferDataStride);
4305 printf("\ttransformFeedbackQueries = %" PRIuLEAST32 "\n",
4306 transform_feedback_properties->transformFeedbackQueries);
4307 printf("\ttransformFeedbackStreamsLinesTriangles = %" PRIuLEAST32 "\n",
4308 transform_feedback_properties->transformFeedbackStreamsLinesTriangles);
4309 printf("\ttransformFeedbackRasterizationStreamSelect = %" PRIuLEAST32 "\n",
4310 transform_feedback_properties->transformFeedbackRasterizationStreamSelect);
4311 printf("\ttransformFeedbackDraw = %" PRIuLEAST32 "\n",
4312 transform_feedback_properties->transformFeedbackDraw);
4314 } else if (structure->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT &&
4315 CheckPhysicalDeviceExtensionIncluded(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME, gpu->device_extensions,
4316 gpu->device_extension_count)) {
4317 VkPhysicalDeviceFragmentDensityMapPropertiesEXT *fragment_density_map_properties =
4318 (VkPhysicalDeviceFragmentDensityMapPropertiesEXT *)structure;
4320 fprintf(out, "\n\t\t\t\t\t<details><summary>VkPhysicalDeviceFragmentDensityMapProperties</summary>\n");
4321 fprintf(out, "\t\t\t\t\t\t<details><summary>minFragmentDensityTexelSize</summary>\n");
4323 "\t\t\t\t\t\t\t<details><summary>width = <div class='val'>%" PRIuLEAST32 "</div></summary></details>\n",
4324 fragment_density_map_properties->minFragmentDensityTexelSize.width);
4326 "\t\t\t\t\t\t\t<details><summary>height = <div class='val'>%" PRIuLEAST32
4327 "</div></summary></details>\n",
4328 fragment_density_map_properties->minFragmentDensityTexelSize.height);
4329 fprintf(out, "\t\t\t\t\t\t<details><summary>maxFragmentDensityTexelSize</summary>\n");
4331 "\t\t\t\t\t\t\t<details><summary>width = <div class='val'>%" PRIuLEAST32 "</div></summary></details>\n",
4332 fragment_density_map_properties->maxFragmentDensityTexelSize.width);
4334 "\t\t\t\t\t\t\t<details><summary>height = <div class='val'>%" PRIuLEAST32
4335 "</div></summary></details>\n",
4336 fragment_density_map_properties->maxFragmentDensityTexelSize.height);
4338 "\t\t\t\t\t\t<details><summary>fragmentDensityInvocations = <div class='val'>%" PRIuLEAST32
4339 "</div></summary></details>\n",
4340 fragment_density_map_properties->fragmentDensityInvocations);
4341 } else if (human_readable_output) {
4342 printf("\nVkPhysicalDeviceFragmentDensityMapProperties\n");
4343 printf("============================================\n");
4344 printf("\tminFragmentDensityTexelSize\n");
4345 printf("\t\twidth = %" PRIuLEAST32 "\n", fragment_density_map_properties->minFragmentDensityTexelSize.width);
4346 printf("\t\theight = %" PRIuLEAST32 "\n", fragment_density_map_properties->minFragmentDensityTexelSize.height);
4347 printf("\tmaxFragmentDensityTexelSize\n");
4348 printf("\t\twidth = %" PRIuLEAST32 "\n", fragment_density_map_properties->maxFragmentDensityTexelSize.width);
4349 printf("\t\theight = %" PRIuLEAST32 "\n", fragment_density_map_properties->maxFragmentDensityTexelSize.height);
4350 printf("\tfragmentDensityInvocations = %" PRIuLEAST32 "\n",
4351 fragment_density_map_properties->fragmentDensityInvocations);
4354 place = structure->pNext;
4362 // Compare function for sorting extensions by name
4363 static int CompareExtensionName(const void *a, const void *b) {
4364 const char *this = ((const VkExtensionProperties *)a)->extensionName;
4365 const char *that = ((const VkExtensionProperties *)b)->extensionName;
4366 return strcmp(this, that);
4369 // Compare function for sorting layers by name
4370 static int CompareLayerName(const void *a, const void *b) {
4371 const char *this = ((const struct LayerExtensionList *)a)->layer_properties.layerName;
4372 const char *that = ((const struct LayerExtensionList *)b)->layer_properties.layerName;
4373 return strcmp(this, that);
4376 static void AppDumpExtensions(const char *indent, const char *layer_name, const uint32_t extension_count,
4377 VkExtensionProperties *extension_properties, FILE *out) {
4379 fprintf(out, "\t\t\t%s<details><summary>", indent);
4381 if (layer_name && (strlen(layer_name) > 0)) {
4383 fprintf(out, "%s Extensions", layer_name);
4384 } else if (human_readable_output) {
4385 printf("%s%s Extensions", indent, layer_name);
4389 fprintf(out, "Extensions");
4390 } else if (human_readable_output) {
4391 printf("%sExtensions", indent);
4395 fprintf(out, "\tcount = <div class='val'>%d</div></summary>", extension_count);
4396 if (extension_count > 0) {
4399 } else if (human_readable_output) {
4400 printf("\tcount = %d\n", extension_count);
4403 const bool is_device_type = strcmp(layer_name, "Device") == 0;
4404 if (is_device_type && json_output) {
4406 printf("\t\"ArrayOfVkExtensionProperties\": [");
4409 qsort(extension_properties, extension_count, sizeof(VkExtensionProperties), CompareExtensionName);
4411 for (uint32_t i = 0; i < extension_count; ++i) {
4412 VkExtensionProperties const *ext_prop = &extension_properties[i];
4414 fprintf(out, "\t\t\t\t%s<details><summary>", indent);
4415 fprintf(out, "<div class='type'>%s</div>: extension revision <div class='val'>%d</div>", ext_prop->extensionName,
4416 ext_prop->specVersion);
4417 fprintf(out, "</summary></details>\n");
4418 } else if (human_readable_output) {
4419 printf("%s\t", indent);
4420 printf("%-36s: extension revision %2d\n", ext_prop->extensionName, ext_prop->specVersion);
4422 if (is_device_type && json_output) {
4428 printf("\t\t\t\"extensionName\": \"%s\",\n", ext_prop->extensionName);
4429 printf("\t\t\t\"specVersion\": %u\n", ext_prop->specVersion);
4434 if (extension_count > 0) {
4435 fprintf(out, "\t\t\t%s</details>\n", indent);
4437 fprintf(out, "</details>\n");
4440 if (is_device_type && json_output) {
4441 if (extension_count > 0) {
4451 static void AppGpuDumpQueueProps(const struct AppGpu *gpu, uint32_t id, FILE *out) {
4452 VkQueueFamilyProperties props;
4454 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
4455 gpu->inst->inst_extensions_count)) {
4456 const VkQueueFamilyProperties *props2_const = &gpu->queue_props2[id].queueFamilyProperties;
4457 props = *props2_const;
4459 const VkQueueFamilyProperties *props_const = &gpu->queue_props[id];
4460 props = *props_const;
4463 VkBool32 supports_present = VK_FALSE;
4464 if (gpu->inst->surface) {
4465 VkResult err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu->obj, id, gpu->inst->surface, &supports_present);
4466 if (err) ERR_EXIT(err);
4470 fprintf(out, "\t\t\t\t\t<details><summary>VkQueueFamilyProperties[<div class='val'>%d</div>]</summary>\n", id);
4471 fprintf(out, "\t\t\t\t\t\t<details><summary>queueFlags = ");
4472 } else if (human_readable_output) {
4473 printf("VkQueueFamilyProperties[%d]:\n", id);
4474 printf("===========================\n");
4475 printf("\tqueueFlags = ");
4477 if (html_output || human_readable_output) {
4478 char *sep = ""; // separator character
4479 if (props.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
4480 fprintf(out, "GRAPHICS");
4483 if (props.queueFlags & VK_QUEUE_COMPUTE_BIT) {
4484 fprintf(out, "%sCOMPUTE", sep);
4487 if (props.queueFlags & VK_QUEUE_TRANSFER_BIT) {
4488 fprintf(out, "%sTRANSFER", sep);
4491 if (props.queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) {
4492 fprintf(out, "%sSPARSE", sep);
4497 fprintf(out, "</summary></details>\n");
4498 fprintf(out, "\t\t\t\t\t\t<details><summary>queueCount = <div class='val'>%u</div></summary></details>\n",
4500 fprintf(out, "\t\t\t\t\t\t<details><summary>timestampValidBits = <div class='val'>%u</div></summary></details>\n",
4501 props.timestampValidBits);
4503 "\t\t\t\t\t\t<details><summary>minImageTransferGranularity = (<div class='val'>%d</div>, <div "
4504 "class='val'>%d</div>, <div class='val'>%d</div>)</summary></details>\n",
4505 props.minImageTransferGranularity.width, props.minImageTransferGranularity.height,
4506 props.minImageTransferGranularity.depth);
4507 fprintf(out, "\t\t\t\t\t\t<details><summary>present support = <div class='val'>%s</div></summary></details>\n",
4508 supports_present ? "true" : "false");
4509 fprintf(out, "\t\t\t\t\t</details>\n");
4510 } else if (human_readable_output) {
4512 printf("\tqueueCount = %u\n", props.queueCount);
4513 printf("\ttimestampValidBits = %u\n", props.timestampValidBits);
4514 printf("\tminImageTransferGranularity = (%d, %d, %d)\n", props.minImageTransferGranularity.width,
4515 props.minImageTransferGranularity.height, props.minImageTransferGranularity.depth);
4516 printf("\tpresent support = %s\n", supports_present ? "true" : "false");
4520 printf("\t\t\t\"minImageTransferGranularity\": {\n");
4521 printf("\t\t\t\t\"depth\": %u,\n", props.minImageTransferGranularity.depth);
4522 printf("\t\t\t\t\"height\": %u,\n", props.minImageTransferGranularity.height);
4523 printf("\t\t\t\t\"width\": %u\n", props.minImageTransferGranularity.width);
4524 printf("\t\t\t},\n");
4525 printf("\t\t\t\"queueCount\": %u,\n", props.queueCount);
4526 printf("\t\t\t\"queueFlags\": %u,\n", props.queueFlags);
4527 printf("\t\t\t\"timestampValidBits\": %u,\n", props.timestampValidBits);
4528 printf("\t\t\t\"present_support\": %s\n", supports_present ? "\"true\"" : "\"false\"");
4536 // This prints a number of bytes in a human-readable format according to prefixes of the International System of Quantities (ISQ),
4537 // defined in ISO/IEC 80000. The prefixes used here are not SI prefixes, but rather the binary prefixes based on powers of 1024
4538 // (kibi-, mebi-, gibi- etc.).
4539 #define kBufferSize 32
4541 static char *HumanReadable(const size_t sz) {
4542 const char prefixes[] = "KMGTPEZY";
4543 char buf[kBufferSize];
4545 double result = (double)sz;
4546 while (result > 1024 && which < 7) {
4551 char unit[] = "\0i";
4553 unit[0] = prefixes[which];
4555 snprintf(buf, kBufferSize, "%.2f %sB", result, unit);
4556 return strndup(buf, kBufferSize);
4559 static void AppGpuDumpMemoryProps(const struct AppGpu *gpu, FILE *out) {
4560 VkPhysicalDeviceMemoryProperties props;
4562 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
4563 gpu->inst->inst_extensions_count)) {
4564 const VkPhysicalDeviceMemoryProperties *props2_const = &gpu->memory_props2.memoryProperties;
4565 props = *props2_const;
4567 const VkPhysicalDeviceMemoryProperties *props_const = &gpu->memory_props;
4568 props = *props_const;
4572 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceMemoryProperties</summary>\n");
4573 fprintf(out, "\t\t\t\t\t\t<details><summary>memoryHeapCount = <div class='val'>%u</div></summary>", props.memoryHeapCount);
4574 if (props.memoryHeapCount > 0) {
4577 } else if (human_readable_output) {
4578 printf("VkPhysicalDeviceMemoryProperties:\n");
4579 printf("=================================\n");
4580 printf("\tmemoryHeapCount = %u\n", props.memoryHeapCount);
4584 printf("\t\"VkPhysicalDeviceMemoryProperties\": {\n");
4585 printf("\t\t\"memoryHeaps\": [");
4587 for (uint32_t i = 0; i < props.memoryHeapCount; ++i) {
4588 const VkDeviceSize memSize = props.memoryHeaps[i].size;
4589 char *mem_size_human_readable = HumanReadable((const size_t)memSize);
4592 fprintf(out, "\t\t\t\t\t\t\t<details><summary>memoryHeaps[<div class='val'>%u</div>]</summary>\n", i);
4594 "\t\t\t\t\t\t\t\t<details><summary>size = <div class='val'>" PRINTF_SIZE_T_SPECIFIER
4595 "</div> (<div class='val'>0x%" PRIxLEAST64 "</div>) (<div class='val'>%s</div>)</summary></details>\n",
4596 (size_t)memSize, memSize, mem_size_human_readable);
4597 } else if (human_readable_output) {
4598 printf("\tmemoryHeaps[%u] :\n", i);
4599 printf("\t\tsize = " PRINTF_SIZE_T_SPECIFIER " (0x%" PRIxLEAST64 ") (%s)\n", (size_t)memSize, memSize,
4600 mem_size_human_readable);
4602 free(mem_size_human_readable);
4604 const VkMemoryHeapFlags heap_flags = props.memoryHeaps[i].flags;
4606 fprintf(out, "\t\t\t\t\t\t\t\t<details open><summary>flags</summary>\n");
4607 fprintf(out, "\t\t\t\t\t\t\t\t\t<details><summary>");
4608 fprintf(out, (heap_flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) ? "<div class='type'>VK_MEMORY_HEAP_DEVICE_LOCAL_BIT</div>"
4610 fprintf(out, "</summary></details>\n");
4611 fprintf(out, "\t\t\t\t\t\t\t\t</details>\n");
4612 fprintf(out, "\t\t\t\t\t\t\t</details>\n");
4613 } else if (human_readable_output) {
4614 printf("\t\tflags:\n\t\t\t");
4615 printf((heap_flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) ? "VK_MEMORY_HEAP_DEVICE_LOCAL_BIT\n" : "None\n");
4622 printf("\t\t\t{\n");
4623 printf("\t\t\t\t\"flags\": %u,\n", heap_flags);
4624 printf("\t\t\t\t\"size\": " PRINTF_SIZE_T_SPECIFIER "\n", (size_t)memSize);
4629 if (props.memoryHeapCount > 0) {
4630 fprintf(out, "\t\t\t\t\t\t");
4632 fprintf(out, "</details>\n");
4635 if (props.memoryHeapCount > 0) {
4642 fprintf(out, "\t\t\t\t\t\t<details><summary>memoryTypeCount = <div class='val'>%u</div></summary>", props.memoryTypeCount);
4643 if (props.memoryTypeCount > 0) {
4646 } else if (human_readable_output) {
4647 printf("\tmemoryTypeCount = %u\n", props.memoryTypeCount);
4651 printf("\t\t\"memoryTypes\": [");
4653 for (uint32_t i = 0; i < props.memoryTypeCount; ++i) {
4655 fprintf(out, "\t\t\t\t\t\t\t<details><summary>memoryTypes[<div class='val'>%u</div>]</summary>\n", i);
4656 fprintf(out, "\t\t\t\t\t\t\t\t<details><summary>heapIndex = <div class='val'>%u</div></summary></details>\n",
4657 props.memoryTypes[i].heapIndex);
4659 "\t\t\t\t\t\t\t\t<details open><summary>propertyFlags = <div class='val'>0x%" PRIxLEAST32 "</div></summary>",
4660 props.memoryTypes[i].propertyFlags);
4661 if (props.memoryTypes[i].propertyFlags == 0) {
4662 fprintf(out, "</details>\n");
4666 } else if (human_readable_output) {
4667 printf("\tmemoryTypes[%u] :\n", i);
4668 printf("\t\theapIndex = %u\n", props.memoryTypes[i].heapIndex);
4669 printf("\t\tpropertyFlags = 0x%" PRIxLEAST32 ":\n", props.memoryTypes[i].propertyFlags);
4676 printf("\t\t\t{\n");
4677 printf("\t\t\t\t\"heapIndex\": %u,\n", props.memoryTypes[i].heapIndex);
4678 printf("\t\t\t\t\"propertyFlags\": %u\n", props.memoryTypes[i].propertyFlags);
4682 // Print each named flag to html or std output if it is set
4683 const VkFlags flags = props.memoryTypes[i].propertyFlags;
4685 if (flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
4687 "\t\t\t\t\t\t\t\t\t<details><summary><div "
4688 "class='type'>VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT</div></summary></details>\n");
4689 if (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
4691 "\t\t\t\t\t\t\t\t\t<details><summary><div "
4692 "class='type'>VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT</div></summary></details>\n");
4693 if (flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
4695 "\t\t\t\t\t\t\t\t\t<details><summary><div "
4696 "class='type'>VK_MEMORY_PROPERTY_HOST_COHERENT_BIT</div></summary></details>\n");
4697 if (flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT)
4699 "\t\t\t\t\t\t\t\t\t<details><summary><div "
4700 "class='type'>VK_MEMORY_PROPERTY_HOST_CACHED_BIT</div></summary></details>\n");
4701 if (flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
4703 "\t\t\t\t\t\t\t\t\t<details><summary><div "
4704 "class='type'>VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT</div></summary></details>\n");
4705 if (flags & VK_MEMORY_PROPERTY_PROTECTED_BIT)
4707 "\t\t\t\t\t\t\t\t\t<details><summary><div "
4708 "class='type'>VK_MEMORY_PROPERTY_PROTECTED_BIT</div></summary></details>\n");
4709 if (props.memoryTypes[i].propertyFlags > 0) fprintf(out, "\t\t\t\t\t\t\t\t</details>\n");
4710 fprintf(out, "\t\t\t\t\t\t\t</details>\n");
4711 } else if (human_readable_output) {
4712 if (flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) printf("\t\t\tVK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT\n");
4713 if (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) printf("\t\t\tVK_MEMORY_PROPERTY_HOST_VISIBLE_BIT\n");
4714 if (flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) printf("\t\t\tVK_MEMORY_PROPERTY_HOST_COHERENT_BIT\n");
4715 if (flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) printf("\t\t\tVK_MEMORY_PROPERTY_HOST_CACHED_BIT\n");
4716 if (flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) printf("\t\t\tVK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT\n");
4717 if (flags & VK_MEMORY_PROPERTY_PROTECTED_BIT) printf("\t\t\tVK_MEMORY_PROPERTY_PROTECTED_BIT\n");
4721 if (props.memoryTypeCount > 0) {
4722 fprintf(out, "\t\t\t\t\t\t");
4724 fprintf(out, "</details>\n");
4725 fprintf(out, "\t\t\t\t\t</details>\n");
4728 if (props.memoryTypeCount > 0) {
4739 static void AppGpuDump(const struct AppGpu *gpu, FILE *out) {
4741 fprintf(out, "\t\t\t\t<details><summary>GPU%u</summary>\n", gpu->id);
4742 } else if (human_readable_output) {
4743 printf("\nDevice Properties and Extensions :\n");
4744 printf("==================================\n");
4745 printf("GPU%u\n", gpu->id);
4748 AppGpuDumpProps(gpu, out);
4750 AppDumpExtensions("\t\t", "Device", gpu->device_extension_count, gpu->device_extensions, out);
4751 } else if (human_readable_output) {
4753 AppDumpExtensions("", "Device", gpu->device_extension_count, gpu->device_extensions, out);
4759 printf("\t\"ArrayOfVkQueueFamilyProperties\": [");
4761 for (uint32_t i = 0; i < gpu->queue_count; ++i) {
4768 AppGpuDumpQueueProps(gpu, i, out);
4769 if (human_readable_output) {
4774 if (gpu->queue_count > 0) {
4780 AppGpuDumpMemoryProps(gpu, out);
4781 if (human_readable_output) {
4785 AppGpuDumpFeatures(gpu, out);
4786 if (human_readable_output) {
4790 AppDevDump(gpu, out);
4792 fprintf(out, "\t\t\t\t</details>\n");
4796 static void AppGroupDump(const VkPhysicalDeviceGroupProperties *group, const uint32_t id, const struct AppInstance *inst,
4799 fprintf(out, "\t\t\t\t<details><summary>Device Group Properties (Group %u)</summary>\n", id);
4800 fprintf(out, "\t\t\t\t\t<details><summary>physicalDeviceCount = <div class='val'>%u</div></summary>\n",
4801 group->physicalDeviceCount);
4802 } else if (human_readable_output) {
4803 printf("\tDevice Group Properties (Group %u) :\n", id);
4804 printf("\t\tphysicalDeviceCount = %u\n", group->physicalDeviceCount);
4807 // Keep a record of all physical device properties to give the user clearer information as output.
4808 VkPhysicalDeviceProperties *props = malloc(sizeof(props[0]) * group->physicalDeviceCount);
4810 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
4812 for (uint32_t i = 0; i < group->physicalDeviceCount; ++i) {
4813 vkGetPhysicalDeviceProperties(group->physicalDevices[i], &props[i]);
4816 // Output information to the user.
4817 for (uint32_t i = 0; i < group->physicalDeviceCount; ++i) {
4819 fprintf(out, "\t\t\t\t\t\t<details><summary>%s (ID: <div class='val'>%d</div>)</summary></details>\n",
4820 props[i].deviceName, i);
4821 } else if (human_readable_output) {
4822 printf("\n\t\t\t%s (ID: %d)\n", props[i].deviceName, i);
4827 fprintf(out, "\t\t\t\t\t</details>\n");
4831 fprintf(out, "\t\t\t\t\t<details><summary>subsetAllocation = <div class='val'>%u</div></summary></details>\n",
4832 group->subsetAllocation);
4833 } else if (human_readable_output) {
4834 printf("\n\t\tsubsetAllocation = %u\n", group->subsetAllocation);
4838 fprintf(out, "\t\t\t\t</details>\n");
4841 // Build create info for logical device made from all physical devices in this group.
4842 const char *extensions_list[] = {VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_DEVICE_GROUP_EXTENSION_NAME};
4844 VkDeviceGroupDeviceCreateInfoKHR dg_ci = {.sType = VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR,
4846 .physicalDeviceCount = group->physicalDeviceCount,
4847 .pPhysicalDevices = group->physicalDevices};
4849 VkDeviceQueueCreateInfo q_ci = {
4850 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, .pNext = NULL, .queueFamilyIndex = 0, .queueCount = 1};
4852 VkDeviceCreateInfo device_ci = {.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
4854 .queueCreateInfoCount = 1,
4855 .pQueueCreateInfos = &q_ci,
4856 .enabledExtensionCount = ARRAY_SIZE(extensions_list),
4857 .ppEnabledExtensionNames = extensions_list};
4859 VkDevice logical_device = VK_NULL_HANDLE;
4861 VkResult err = vkCreateDevice(group->physicalDevices[0], &device_ci, NULL, &logical_device);
4862 if (err != VK_SUCCESS && err != VK_ERROR_EXTENSION_NOT_PRESENT) ERR_EXIT(err);
4866 fprintf(out, "\t\t\t\t<details><summary>Device Group Present Capabilities (Group %d)</summary>\n", id);
4867 } else if (human_readable_output) {
4868 printf("\n\tDevice Group Present Capabilities (Group %d) :\n", id);
4871 VkDeviceGroupPresentCapabilitiesKHR group_capabilities = {.sType = VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR,
4874 // If the KHR_device_group extension is present, write the capabilities of the logical device into a struct for later output
4876 PFN_vkGetDeviceGroupPresentCapabilitiesKHR vkGetDeviceGroupPresentCapabilitiesKHR =
4877 (PFN_vkGetDeviceGroupPresentCapabilitiesKHR)vkGetInstanceProcAddr(inst->instance,
4878 "vkGetDeviceGroupPresentCapabilitiesKHR");
4879 err = vkGetDeviceGroupPresentCapabilitiesKHR(logical_device, &group_capabilities);
4880 if (err) ERR_EXIT(err);
4882 for (uint32_t i = 0; i < group->physicalDeviceCount; i++) {
4884 fprintf(out, "\t\t\t\t\t<details><summary>%s (ID: <div class='val'>%d</div>)</summary></details>\n",
4885 props[i].deviceName, i);
4886 fprintf(out, "\t\t\t\t\t<details><summary>Can present images from the following devices:</summary>\n");
4887 if (group_capabilities.presentMask[i] != 0) {
4888 for (uint32_t j = 0; j < group->physicalDeviceCount; ++j) {
4889 uint32_t mask = 1 << j;
4890 if (group_capabilities.presentMask[i] & mask) {
4891 fprintf(out, "\t\t\t\t\t\t<details><summary>%s (ID: <div class='val'>%d</div>)</summary></details>\n",
4892 props[j].deviceName, j);
4896 fprintf(out, "\t\t\t\t\t\t<details><summary>None</summary></details>\n");
4898 fprintf(out, "\t\t\t\t\t</details>\n");
4899 } else if (human_readable_output) {
4900 printf("\n\t\t%s (ID: %d)\n", props[i].deviceName, i);
4901 printf("\t\tCan present images from the following devices:\n");
4902 if (group_capabilities.presentMask[i] != 0) {
4903 for (uint32_t j = 0; j < group->physicalDeviceCount; ++j) {
4904 uint32_t mask = 1 << j;
4905 if (group_capabilities.presentMask[i] & mask) {
4906 printf("\t\t\t%s (ID: %d)\n", props[j].deviceName, j);
4910 printf("\t\t\tNone\n");
4917 fprintf(out, "\t\t\t\t\t<details><summary>Present modes</summary>\n");
4918 if (group_capabilities.modes & VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR)
4919 fprintf(out, "\t\t\t\t\t\t<details><summary>VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR</summary></details>\n");
4920 if (group_capabilities.modes & VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR)
4921 fprintf(out, "\t\t\t\t\t\t<details><summary>VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR</summary></details>\n");
4922 if (group_capabilities.modes & VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR)
4923 fprintf(out, "\t\t\t\t\t\t<details><summary>VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR</summary></details>\n");
4924 if (group_capabilities.modes & VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR)
4927 "\t\t\t\t\t\t<details><summary>VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR</summary></details>\n");
4928 fprintf(out, "\t\t\t\t\t</details>\n");
4929 } else if (human_readable_output) {
4930 printf("\t\tPresent modes:\n");
4931 if (group_capabilities.modes & VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR)
4932 printf("\t\t\tVK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR\n");
4933 if (group_capabilities.modes & VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR)
4934 printf("\t\t\tVK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR\n");
4935 if (group_capabilities.modes & VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR)
4936 printf("\t\t\tVK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR\n");
4937 if (group_capabilities.modes & VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR)
4938 printf("\t\t\tVK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR\n");
4942 fprintf(out, "\t\t\t\t</details>\n");
4946 // Clean up after ourselves.
4948 vkDestroyDevice(logical_device, NULL);
4952 // Enlarges the console window to have a large scrollback size.
4953 static void ConsoleEnlarge() {
4954 const HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
4956 // make the console window bigger
4957 CONSOLE_SCREEN_BUFFER_INFO csbi;
4959 if (GetConsoleScreenBufferInfo(console_handle, &csbi)) {
4960 buffer_size.X = csbi.dwSize.X + 30;
4961 buffer_size.Y = 20000;
4962 SetConsoleScreenBufferSize(console_handle, buffer_size);
4967 r.Right = csbi.dwSize.X - 1 + 30;
4969 SetConsoleWindowInfo(console_handle, true, &r);
4971 // change the console window title
4972 SetConsoleTitle(TEXT(APP_SHORT_NAME));
4976 void print_usage(char *argv0) {
4977 printf("\nvulkaninfo - Summarize Vulkan information in relation to the current environment.\n\n");
4978 printf("USAGE: %s [options]\n\n", argv0);
4979 printf("OPTIONS:\n");
4980 printf("-h, --help Print this help.\n");
4981 printf("--html Produce an html version of vulkaninfo output, saved as\n");
4982 printf(" \"vulkaninfo.html\" in the directory in which the command is\n");
4984 printf("-j, --json Produce a json version of vulkaninfo output to standard\n");
4985 printf(" output.\n");
4986 printf("--json=<gpu-number> For a multi-gpu system, a single gpu can be targetted by\n");
4987 printf(" specifying the gpu-number associated with the gpu of \n");
4988 printf(" interest. This number can be determined by running\n");
4989 printf(" vulkaninfo without any options specified.\n\n");
4992 int main(int argc, char **argv) {
4995 struct AppInstance inst = {0};
4999 if (ConsoleIsExclusive()) ConsoleEnlarge();
5002 // Combinations of output: html only, html AND json, json only, human readable only
5003 for (int i = 1; i < argc; ++i) {
5004 if (!CheckForJsonOption(argv[i])) {
5005 if (strcmp(argv[i], "--html") == 0) {
5006 human_readable_output = false;
5009 } else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
5010 print_usage(argv[0]);
5013 print_usage(argv[0]);
5019 AppCreateInstance(&inst);
5022 out = fopen("vulkaninfo.html", "w");
5023 PrintHtmlHeader(out);
5024 fprintf(out, "\t\t\t<details><summary>");
5025 } else if (human_readable_output) {
5026 printf("==========\n");
5027 printf("VULKANINFO\n");
5028 printf("==========\n\n");
5030 if (html_output || human_readable_output) {
5031 fprintf(out, "Vulkan Instance Version: ");
5034 fprintf(out, "<div class='val'>%d.%d.%d</div></summary></details>\n", inst.vulkan_major, inst.vulkan_minor,
5036 fprintf(out, "\t\t\t<br />\n");
5037 } else if (human_readable_output) {
5038 printf("%d.%d.%d\n\n", inst.vulkan_major, inst.vulkan_minor, inst.vulkan_patch);
5041 err = vkEnumeratePhysicalDevices(inst.instance, &gpu_count, NULL);
5046 VkPhysicalDevice *objs = malloc(sizeof(objs[0]) * gpu_count);
5048 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
5051 err = vkEnumeratePhysicalDevices(inst.instance, &gpu_count, objs);
5056 struct AppGpu *gpus = malloc(sizeof(gpus[0]) * gpu_count);
5058 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
5061 for (uint32_t i = 0; i < gpu_count; ++i) {
5062 AppGpuInit(&gpus[i], &inst, i, objs[i]);
5063 if (human_readable_output) {
5068 // If json output, confirm the desired gpu exists
5070 if (selected_gpu >= gpu_count) {
5073 PrintJsonHeader(inst.vulkan_major, inst.vulkan_minor, inst.vulkan_patch);
5076 if (human_readable_output) {
5077 printf("Instance Extensions:\n");
5078 printf("====================\n");
5080 AppDumpExtensions("", "Instance", inst.global_extension_count, inst.global_extensions, out);
5082 //---Layer-Device-Extensions---
5084 fprintf(out, "\t\t\t<details><summary>Layers: count = <div class='val'>%d</div></summary>", inst.global_layer_count);
5085 if (inst.global_layer_count > 0) {
5088 } else if (human_readable_output) {
5089 printf("Layers: count = %d\n", inst.global_layer_count);
5090 printf("=======\n");
5092 if (json_output && (inst.global_layer_count > 0)) {
5094 printf("\t\"ArrayOfVkLayerProperties\": [");
5097 qsort(inst.global_layers, inst.global_layer_count, sizeof(struct LayerExtensionList), CompareLayerName);
5099 for (uint32_t i = 0; i < inst.global_layer_count; ++i) {
5100 uint32_t layer_major, layer_minor, layer_patch;
5101 char spec_version[64], layer_version[64];
5102 VkLayerProperties const *layer_prop = &inst.global_layers[i].layer_properties;
5104 ExtractVersion(layer_prop->specVersion, &layer_major, &layer_minor, &layer_patch);
5105 snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", layer_major, layer_minor, layer_patch);
5106 snprintf(layer_version, sizeof(layer_version), "%d", layer_prop->implementationVersion);
5109 fprintf(out, "\t\t\t\t<details><summary>");
5110 fprintf(out, "<div class='type'>%s</div> (%s) Vulkan version <div class='val'>%s</div>, ", layer_prop->layerName,
5111 (char *)layer_prop->description, spec_version);
5112 fprintf(out, "layer version <div class='val'>%s</div></summary>\n", layer_version);
5113 AppDumpExtensions("\t\t", "Layer", inst.global_layers[i].extension_count, inst.global_layers[i].extension_properties,
5115 } else if (human_readable_output) {
5116 printf("%s (%s) Vulkan version %s, layer version %s\n", layer_prop->layerName, (char *)layer_prop->description,
5117 spec_version, layer_version);
5118 AppDumpExtensions("\t", "Layer", inst.global_layers[i].extension_count, inst.global_layers[i].extension_properties,
5127 printf("\t\t\t\"layerName\": \"%s\",\n", layer_prop->layerName);
5128 printf("\t\t\t\"specVersion\": %u,\n", layer_prop->specVersion);
5129 printf("\t\t\t\"implementationVersion\": %u,\n", layer_prop->implementationVersion);
5130 printf("\t\t\t\"description\": \"%s\"\n", layer_prop->description);
5135 fprintf(out, "\t\t\t\t\t<details><summary>Devices count = <div class='val'>%d</div></summary>\n", gpu_count);
5136 } else if (human_readable_output) {
5137 printf("\tDevices \tcount = %d\n", gpu_count);
5140 char *layer_name = inst.global_layers[i].layer_properties.layerName;
5142 for (uint32_t j = 0; j < gpu_count; ++j) {
5144 fprintf(out, "\t\t\t\t\t\t<details><summary>");
5145 fprintf(out, "GPU id: <div class='val'>%u</div> (%s)</summary></details>\n", j, gpus[j].props.deviceName);
5146 } else if (human_readable_output) {
5147 printf("\t\tGPU id : %u (%s)\n", j, gpus[j].props.deviceName);
5150 VkExtensionProperties *props;
5151 AppGetPhysicalDeviceLayerExtensions(&gpus[j], layer_name, &count, &props);
5153 AppDumpExtensions("\t\t\t", "Layer-Device", count, props, out);
5154 } else if (human_readable_output) {
5155 AppDumpExtensions("\t\t", "Layer-Device", count, props, out);
5161 fprintf(out, "\t\t\t\t\t</details>\n");
5162 fprintf(out, "\t\t\t\t</details>\n");
5163 } else if (human_readable_output) {
5169 fprintf(out, "\t\t\t</details>\n");
5171 if (json_output && (inst.global_layer_count > 0)) {
5177 //-----------------------------
5180 fprintf(out, "\t\t\t<details><summary>Presentable Surfaces</summary>");
5181 if (gpu_count > 0) {
5184 fprintf(out, "</details>\n");
5186 } else if (human_readable_output) {
5187 printf("Presentable Surfaces:\n");
5188 printf("=====================\n");
5192 int format_count = 0;
5193 int present_mode_count = 0;
5195 #if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR)
5196 bool has_display = true;
5197 const char *display_var = getenv("DISPLAY");
5198 if (display_var == NULL || strlen(display_var) == 0) {
5199 fprintf(stderr, "'DISPLAY' environment variable not set... skipping surface info\n");
5201 has_display = false;
5205 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
5206 struct wl_display *wayland_display = wl_display_connect(NULL);
5207 bool has_wayland_display = false;
5208 if (wayland_display != NULL) {
5209 wl_display_disconnect(wayland_display);
5210 has_wayland_display = true;
5215 #ifdef VK_USE_PLATFORM_WIN32_KHR
5216 struct SurfaceExtensionInfo surface_ext_win32;
5217 surface_ext_win32.name = VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
5218 surface_ext_win32.create_window = AppCreateWin32Window;
5219 surface_ext_win32.create_surface = AppCreateWin32Surface;
5220 surface_ext_win32.destroy_window = AppDestroyWin32Window;
5221 AppDumpSurfaceExtension(&inst, gpus, gpu_count, &surface_ext_win32, &format_count, &present_mode_count, out);
5224 #ifdef VK_USE_PLATFORM_XCB_KHR
5225 struct SurfaceExtensionInfo surface_ext_xcb;
5226 surface_ext_xcb.name = VK_KHR_XCB_SURFACE_EXTENSION_NAME;
5227 surface_ext_xcb.create_window = AppCreateXcbWindow;
5228 surface_ext_xcb.create_surface = AppCreateXcbSurface;
5229 surface_ext_xcb.destroy_window = AppDestroyXcbWindow;
5231 AppDumpSurfaceExtension(&inst, gpus, gpu_count, &surface_ext_xcb, &format_count, &present_mode_count, out);
5235 #ifdef VK_USE_PLATFORM_XLIB_KHR
5236 struct SurfaceExtensionInfo surface_ext_xlib;
5237 surface_ext_xlib.name = VK_KHR_XLIB_SURFACE_EXTENSION_NAME;
5238 surface_ext_xlib.create_window = AppCreateXlibWindow;
5239 surface_ext_xlib.create_surface = AppCreateXlibSurface;
5240 surface_ext_xlib.destroy_window = AppDestroyXlibWindow;
5242 AppDumpSurfaceExtension(&inst, gpus, gpu_count, &surface_ext_xlib, &format_count, &present_mode_count, out);
5246 #ifdef VK_USE_PLATFORM_MACOS_MVK
5247 struct SurfaceExtensionInfo surface_ext_macos;
5248 surface_ext_macos.name = VK_MVK_MACOS_SURFACE_EXTENSION_NAME;
5249 surface_ext_macos.create_window = AppCreateMacOSWindow;
5250 surface_ext_macos.create_surface = AppCreateMacOSSurface;
5251 surface_ext_macos.destroy_window = AppDestroyMacOSWindow;
5252 AppDumpSurfaceExtension(&inst, gpus, gpu_count, &surface_ext_macos, &format_count, &present_mode_count, out);
5255 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
5256 struct SurfaceExtensionInfo surface_ext_wayland;
5257 surface_ext_wayland.name = VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME;
5258 surface_ext_wayland.create_window = AppCreateWaylandWindow;
5259 surface_ext_wayland.create_surface = AppCreateWaylandSurface;
5260 surface_ext_wayland.destroy_window = AppDestroyWaylandWindow;
5261 if (has_wayland_display) {
5262 AppDumpSurfaceExtension(&inst, gpus, gpu_count, &surface_ext_wayland, &format_count, &present_mode_count, out);
5267 if (!format_count && !present_mode_count) {
5269 fprintf(out, "\t\t\t\t<details><summary>None found</summary></details>\n");
5270 } else if (human_readable_output) {
5271 printf("None found\n\n");
5276 fprintf(out, "\t\t\t</details>\n");
5280 if (CheckExtensionEnabled(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME, inst.inst_extensions, inst.inst_extensions_count)) {
5281 PFN_vkEnumeratePhysicalDeviceGroupsKHR vkEnumeratePhysicalDeviceGroupsKHR =
5282 (PFN_vkEnumeratePhysicalDeviceGroupsKHR)vkGetInstanceProcAddr(inst.instance, "vkEnumeratePhysicalDeviceGroupsKHR");
5284 uint32_t group_count;
5285 err = vkEnumeratePhysicalDeviceGroupsKHR(inst.instance, &group_count, NULL);
5290 VkPhysicalDeviceGroupProperties *groups = malloc(sizeof(groups[0]) * group_count);
5292 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
5295 err = vkEnumeratePhysicalDeviceGroupsKHR(inst.instance, &group_count, groups);
5301 fprintf(out, "\t\t\t<details><summary>Groups</summary>\n");
5302 } else if (human_readable_output) {
5303 printf("\nGroups :\n");
5304 printf("========\n");
5307 for (uint32_t i = 0; i < group_count; ++i) {
5308 AppGroupDump(&groups[i], i, &inst, out);
5309 if (human_readable_output) {
5315 fprintf(out, "\t\t\t</details>\n");
5322 fprintf(out, "\t\t\t<details><summary>Device Properties and Extensions</summary>\n");
5325 for (uint32_t i = 0; i < gpu_count; ++i) {
5326 if (json_output && selected_gpu != i) {
5327 // Toggle json_output to allow html output without json output
5328 json_output = false;
5329 AppGpuDump(&gpus[i], out);
5332 AppGpuDump(&gpus[i], out);
5334 if (human_readable_output) {
5340 fprintf(out, "\t\t\t</details>\n");
5343 for (uint32_t i = 0; i < gpu_count; ++i) {
5344 AppGpuDestroy(&gpus[i]);
5349 AppDestroySurface(&inst);
5350 AppDestroyInstance(&inst);
5353 PrintHtmlFooter(out);
5364 if (ConsoleIsExclusive() && human_readable_output) {