1 /*
2 * Copyright (c) 2015-2016 The Khronos Group Inc.
3 * Copyright (c) 2015-2016 Valve Corporation
4 * Copyright (c) 2015-2016 LunarG, Inc.
5 *
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
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
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.
17 *
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 */
25
26 #ifdef __GNUC__
27 #ifndef _POSIX_C_SOURCE
28 #define _POSIX_C_SOURCE 200809L
29 #endif
30 #else
31 #define strndup(p, n) strdup(p)
32 #endif
33
34 #include <assert.h>
35 #include <inttypes.h>
36 #include <stdbool.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40
41 #ifdef _WIN32
42 #include <fcntl.h>
43 #include <io.h>
44 #endif // _WIN32
45
46 #if defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR)
47 #include <X11/Xutil.h>
48 #endif
49
50 #if defined(VK_USE_PLATFORM_MIR_KHR)
51 #warning "Vulkaninfo does not have code for Mir at this time"
52 #endif
53
54 #include <vulkan/vulkan.h>
55
56 #define ERR(err) printf("%s:%d: failed with %s\n", __FILE__, __LINE__, VkResultString(err));
57
58 #ifdef _WIN32
59
60 #define snprintf _snprintf
61 #define strdup _strdup
62
63 // Returns nonzero if the console is used only for this process. Will return
64 // zero if another process (such as cmd.exe) is also attached.
ConsoleIsExclusive(void)65 static int ConsoleIsExclusive(void) {
66 DWORD pids[2];
67 DWORD num_pids = GetConsoleProcessList(pids, ARRAYSIZE(pids));
68 return num_pids <= 1;
69 }
70
71 #define WAIT_FOR_CONSOLE_DESTROY \
72 do { \
73 if (ConsoleIsExclusive()) Sleep(INFINITE); \
74 } while (0)
75 #else
76 #define WAIT_FOR_CONSOLE_DESTROY
77 #endif
78
79 #define ERR_EXIT(err) \
80 do { \
81 ERR(err); \
82 fflush(stdout); \
83 WAIT_FOR_CONSOLE_DESTROY; \
84 exit(-1); \
85 } while (0)
86
87 #if defined(NDEBUG) && defined(__GNUC__)
88 #define U_ASSERT_ONLY __attribute__((unused))
89 #else
90 #define U_ASSERT_ONLY
91 #endif
92
93 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
94
95 #define MAX_QUEUE_TYPES 5
96 #define APP_SHORT_NAME "vulkaninfo"
97
98 static bool html_output;
99
100 struct VkStructureHeader {
101 VkStructureType sType;
102 void *pNext;
103 };
104
105 struct AppGpu;
106
107 struct AppDev {
108 struct AppGpu *gpu; /* point back to the GPU */
109
110 VkDevice obj;
111
112 VkFormatProperties format_props[VK_FORMAT_RANGE_SIZE];
113 VkFormatProperties2KHR format_props2[VK_FORMAT_RANGE_SIZE];
114 };
115
116 struct LayerExtensionList {
117 VkLayerProperties layer_properties;
118 uint32_t extension_count;
119 VkExtensionProperties *extension_properties;
120 };
121
122 struct AppInstance {
123 VkInstance instance;
124 uint32_t global_layer_count;
125 struct LayerExtensionList *global_layers;
126 uint32_t global_extension_count;
127 VkExtensionProperties *global_extensions; // Instance Extensions
128
129 const char **inst_extensions;
130 uint32_t inst_extensions_count;
131
132 PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
133 PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
134 PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
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;
143
144 VkSurfaceCapabilitiesKHR surface_capabilities;
145 VkSurfaceCapabilities2KHR surface_capabilities2;
146 VkSharedPresentSurfaceCapabilitiesKHR shared_surface_capabilities;
147 VkSurfaceCapabilities2EXT surface_capabilities2_ext;
148
149 VkSurfaceKHR surface;
150 int width, height;
151
152 #ifdef VK_USE_PLATFORM_WIN32_KHR
153 HINSTANCE h_instance; // Windows Instance
154 HWND h_wnd; // window handle
155 #elif VK_USE_PLATFORM_XCB_KHR
156 xcb_connection_t *xcb_connection;
157 xcb_screen_t *xcb_screen;
158 xcb_window_t xcb_window;
159 #elif VK_USE_PLATFORM_XLIB_KHR
160 Display *xlib_display;
161 Window xlib_window;
162 #elif VK_USE_PLATFORM_ANDROID_KHR // TODO
163 ANativeWindow *window;
164 #endif
165 };
166
167 struct AppGpu {
168 uint32_t id;
169 VkPhysicalDevice obj;
170
171 VkPhysicalDeviceProperties props;
172 VkPhysicalDeviceProperties2KHR props2;
173
174 uint32_t queue_count;
175 VkQueueFamilyProperties *queue_props;
176 VkQueueFamilyProperties2KHR *queue_props2;
177 VkDeviceQueueCreateInfo *queue_reqs;
178
179 struct AppInstance *inst;
180
181 VkPhysicalDeviceMemoryProperties memory_props;
182 VkPhysicalDeviceMemoryProperties2KHR memory_props2;
183
184 VkPhysicalDeviceFeatures features;
185 VkPhysicalDeviceFeatures2KHR features2;
186 VkPhysicalDevice limits;
187
188 uint32_t device_extension_count;
189 VkExtensionProperties *device_extensions;
190
191 struct AppDev dev;
192 };
193
DbgCallback(VkFlags msgFlags,VkDebugReportObjectTypeEXT objType,uint64_t srcObject,size_t location,int32_t msgCode,const char * pLayerPrefix,const char * pMsg,void * pUserData)194 static VKAPI_ATTR VkBool32 VKAPI_CALL DbgCallback(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject,
195 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg,
196 void *pUserData) {
197 char *message = (char *)malloc(strlen(pMsg) + 100);
198
199 assert(message);
200
201 if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
202 sprintf(message, "ERROR: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
203 } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
204 sprintf(message, "WARNING: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
205 } else if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
206 sprintf(message, "INFO: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
207 } else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
208 sprintf(message, "DEBUG: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
209 }
210
211 printf("%s\n", message);
212 fflush(stdout);
213 free(message);
214
215 /*
216 * false indicates that layer should not bail-out of an
217 * API call that had validation failures. This may mean that the
218 * app dies inside the driver due to invalid parameter(s).
219 * That's what would happen without validation layers, so we'll
220 * keep that behavior here.
221 */
222 return false;
223 }
224
VkResultString(VkResult err)225 static const char *VkResultString(VkResult err) {
226 switch (err) {
227 #define STR(r) \
228 case r: \
229 return #r
230 STR(VK_SUCCESS);
231 STR(VK_NOT_READY);
232 STR(VK_TIMEOUT);
233 STR(VK_EVENT_SET);
234 STR(VK_EVENT_RESET);
235 STR(VK_ERROR_INITIALIZATION_FAILED);
236 STR(VK_ERROR_OUT_OF_HOST_MEMORY);
237 STR(VK_ERROR_OUT_OF_DEVICE_MEMORY);
238 STR(VK_ERROR_DEVICE_LOST);
239 STR(VK_ERROR_LAYER_NOT_PRESENT);
240 STR(VK_ERROR_EXTENSION_NOT_PRESENT);
241 STR(VK_ERROR_MEMORY_MAP_FAILED);
242 STR(VK_ERROR_INCOMPATIBLE_DRIVER);
243 #undef STR
244 default:
245 return "UNKNOWN_RESULT";
246 }
247 }
248
VkPhysicalDeviceTypeString(VkPhysicalDeviceType type)249 static const char *VkPhysicalDeviceTypeString(VkPhysicalDeviceType type) {
250 switch (type) {
251 #define STR(r) \
252 case VK_PHYSICAL_DEVICE_TYPE_##r: \
253 return #r
254 STR(OTHER);
255 STR(INTEGRATED_GPU);
256 STR(DISCRETE_GPU);
257 STR(VIRTUAL_GPU);
258 STR(CPU);
259 #undef STR
260 default:
261 return "UNKNOWN_DEVICE";
262 }
263 }
264
VkFormatString(VkFormat fmt)265 static const char *VkFormatString(VkFormat fmt) {
266 switch (fmt) {
267 #define STR(r) \
268 case VK_FORMAT_##r: \
269 return #r
270 STR(UNDEFINED);
271 STR(R4G4_UNORM_PACK8);
272 STR(R4G4B4A4_UNORM_PACK16);
273 STR(B4G4R4A4_UNORM_PACK16);
274 STR(R5G6B5_UNORM_PACK16);
275 STR(B5G6R5_UNORM_PACK16);
276 STR(R5G5B5A1_UNORM_PACK16);
277 STR(B5G5R5A1_UNORM_PACK16);
278 STR(A1R5G5B5_UNORM_PACK16);
279 STR(R8_UNORM);
280 STR(R8_SNORM);
281 STR(R8_USCALED);
282 STR(R8_SSCALED);
283 STR(R8_UINT);
284 STR(R8_SINT);
285 STR(R8_SRGB);
286 STR(R8G8_UNORM);
287 STR(R8G8_SNORM);
288 STR(R8G8_USCALED);
289 STR(R8G8_SSCALED);
290 STR(R8G8_UINT);
291 STR(R8G8_SINT);
292 STR(R8G8_SRGB);
293 STR(R8G8B8_UNORM);
294 STR(R8G8B8_SNORM);
295 STR(R8G8B8_USCALED);
296 STR(R8G8B8_SSCALED);
297 STR(R8G8B8_UINT);
298 STR(R8G8B8_SINT);
299 STR(R8G8B8_SRGB);
300 STR(B8G8R8_UNORM);
301 STR(B8G8R8_SNORM);
302 STR(B8G8R8_USCALED);
303 STR(B8G8R8_SSCALED);
304 STR(B8G8R8_UINT);
305 STR(B8G8R8_SINT);
306 STR(B8G8R8_SRGB);
307 STR(R8G8B8A8_UNORM);
308 STR(R8G8B8A8_SNORM);
309 STR(R8G8B8A8_USCALED);
310 STR(R8G8B8A8_SSCALED);
311 STR(R8G8B8A8_UINT);
312 STR(R8G8B8A8_SINT);
313 STR(R8G8B8A8_SRGB);
314 STR(B8G8R8A8_UNORM);
315 STR(B8G8R8A8_SNORM);
316 STR(B8G8R8A8_USCALED);
317 STR(B8G8R8A8_SSCALED);
318 STR(B8G8R8A8_UINT);
319 STR(B8G8R8A8_SINT);
320 STR(B8G8R8A8_SRGB);
321 STR(A8B8G8R8_UNORM_PACK32);
322 STR(A8B8G8R8_SNORM_PACK32);
323 STR(A8B8G8R8_USCALED_PACK32);
324 STR(A8B8G8R8_SSCALED_PACK32);
325 STR(A8B8G8R8_UINT_PACK32);
326 STR(A8B8G8R8_SINT_PACK32);
327 STR(A8B8G8R8_SRGB_PACK32);
328 STR(A2R10G10B10_UNORM_PACK32);
329 STR(A2R10G10B10_SNORM_PACK32);
330 STR(A2R10G10B10_USCALED_PACK32);
331 STR(A2R10G10B10_SSCALED_PACK32);
332 STR(A2R10G10B10_UINT_PACK32);
333 STR(A2R10G10B10_SINT_PACK32);
334 STR(A2B10G10R10_UNORM_PACK32);
335 STR(A2B10G10R10_SNORM_PACK32);
336 STR(A2B10G10R10_USCALED_PACK32);
337 STR(A2B10G10R10_SSCALED_PACK32);
338 STR(A2B10G10R10_UINT_PACK32);
339 STR(A2B10G10R10_SINT_PACK32);
340 STR(R16_UNORM);
341 STR(R16_SNORM);
342 STR(R16_USCALED);
343 STR(R16_SSCALED);
344 STR(R16_UINT);
345 STR(R16_SINT);
346 STR(R16_SFLOAT);
347 STR(R16G16_UNORM);
348 STR(R16G16_SNORM);
349 STR(R16G16_USCALED);
350 STR(R16G16_SSCALED);
351 STR(R16G16_UINT);
352 STR(R16G16_SINT);
353 STR(R16G16_SFLOAT);
354 STR(R16G16B16_UNORM);
355 STR(R16G16B16_SNORM);
356 STR(R16G16B16_USCALED);
357 STR(R16G16B16_SSCALED);
358 STR(R16G16B16_UINT);
359 STR(R16G16B16_SINT);
360 STR(R16G16B16_SFLOAT);
361 STR(R16G16B16A16_UNORM);
362 STR(R16G16B16A16_SNORM);
363 STR(R16G16B16A16_USCALED);
364 STR(R16G16B16A16_SSCALED);
365 STR(R16G16B16A16_UINT);
366 STR(R16G16B16A16_SINT);
367 STR(R16G16B16A16_SFLOAT);
368 STR(R32_UINT);
369 STR(R32_SINT);
370 STR(R32_SFLOAT);
371 STR(R32G32_UINT);
372 STR(R32G32_SINT);
373 STR(R32G32_SFLOAT);
374 STR(R32G32B32_UINT);
375 STR(R32G32B32_SINT);
376 STR(R32G32B32_SFLOAT);
377 STR(R32G32B32A32_UINT);
378 STR(R32G32B32A32_SINT);
379 STR(R32G32B32A32_SFLOAT);
380 STR(R64_UINT);
381 STR(R64_SINT);
382 STR(R64_SFLOAT);
383 STR(R64G64_UINT);
384 STR(R64G64_SINT);
385 STR(R64G64_SFLOAT);
386 STR(R64G64B64_UINT);
387 STR(R64G64B64_SINT);
388 STR(R64G64B64_SFLOAT);
389 STR(R64G64B64A64_UINT);
390 STR(R64G64B64A64_SINT);
391 STR(R64G64B64A64_SFLOAT);
392 STR(B10G11R11_UFLOAT_PACK32);
393 STR(E5B9G9R9_UFLOAT_PACK32);
394 STR(D16_UNORM);
395 STR(X8_D24_UNORM_PACK32);
396 STR(D32_SFLOAT);
397 STR(S8_UINT);
398 STR(D16_UNORM_S8_UINT);
399 STR(D24_UNORM_S8_UINT);
400 STR(D32_SFLOAT_S8_UINT);
401 STR(BC1_RGB_UNORM_BLOCK);
402 STR(BC1_RGB_SRGB_BLOCK);
403 STR(BC1_RGBA_UNORM_BLOCK);
404 STR(BC1_RGBA_SRGB_BLOCK);
405 STR(BC2_UNORM_BLOCK);
406 STR(BC2_SRGB_BLOCK);
407 STR(BC3_UNORM_BLOCK);
408 STR(BC3_SRGB_BLOCK);
409 STR(BC4_UNORM_BLOCK);
410 STR(BC4_SNORM_BLOCK);
411 STR(BC5_UNORM_BLOCK);
412 STR(BC5_SNORM_BLOCK);
413 STR(BC6H_UFLOAT_BLOCK);
414 STR(BC6H_SFLOAT_BLOCK);
415 STR(BC7_UNORM_BLOCK);
416 STR(BC7_SRGB_BLOCK);
417 STR(ETC2_R8G8B8_UNORM_BLOCK);
418 STR(ETC2_R8G8B8_SRGB_BLOCK);
419 STR(ETC2_R8G8B8A1_UNORM_BLOCK);
420 STR(ETC2_R8G8B8A1_SRGB_BLOCK);
421 STR(ETC2_R8G8B8A8_UNORM_BLOCK);
422 STR(ETC2_R8G8B8A8_SRGB_BLOCK);
423 STR(EAC_R11_UNORM_BLOCK);
424 STR(EAC_R11_SNORM_BLOCK);
425 STR(EAC_R11G11_UNORM_BLOCK);
426 STR(EAC_R11G11_SNORM_BLOCK);
427 STR(ASTC_4x4_UNORM_BLOCK);
428 STR(ASTC_4x4_SRGB_BLOCK);
429 STR(ASTC_5x4_UNORM_BLOCK);
430 STR(ASTC_5x4_SRGB_BLOCK);
431 STR(ASTC_5x5_UNORM_BLOCK);
432 STR(ASTC_5x5_SRGB_BLOCK);
433 STR(ASTC_6x5_UNORM_BLOCK);
434 STR(ASTC_6x5_SRGB_BLOCK);
435 STR(ASTC_6x6_UNORM_BLOCK);
436 STR(ASTC_6x6_SRGB_BLOCK);
437 STR(ASTC_8x5_UNORM_BLOCK);
438 STR(ASTC_8x5_SRGB_BLOCK);
439 STR(ASTC_8x6_UNORM_BLOCK);
440 STR(ASTC_8x6_SRGB_BLOCK);
441 STR(ASTC_8x8_UNORM_BLOCK);
442 STR(ASTC_8x8_SRGB_BLOCK);
443 STR(ASTC_10x5_UNORM_BLOCK);
444 STR(ASTC_10x5_SRGB_BLOCK);
445 STR(ASTC_10x6_UNORM_BLOCK);
446 STR(ASTC_10x6_SRGB_BLOCK);
447 STR(ASTC_10x8_UNORM_BLOCK);
448 STR(ASTC_10x8_SRGB_BLOCK);
449 STR(ASTC_10x10_UNORM_BLOCK);
450 STR(ASTC_10x10_SRGB_BLOCK);
451 STR(ASTC_12x10_UNORM_BLOCK);
452 STR(ASTC_12x10_SRGB_BLOCK);
453 STR(ASTC_12x12_UNORM_BLOCK);
454 STR(ASTC_12x12_SRGB_BLOCK);
455 #undef STR
456 default:
457 return "UNKNOWN_FORMAT";
458 }
459 }
460 #if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR)
VkPresentModeString(VkPresentModeKHR mode)461 static const char *VkPresentModeString(VkPresentModeKHR mode) {
462 switch (mode) {
463 #define STR(r) \
464 case VK_PRESENT_MODE_##r: \
465 return #r
466 STR(IMMEDIATE_KHR);
467 STR(MAILBOX_KHR);
468 STR(FIFO_KHR);
469 STR(FIFO_RELAXED_KHR);
470 #undef STR
471 default:
472 return "UNKNOWN_FORMAT";
473 }
474 }
475 #endif
476
CheckExtensionEnabled(const char * extension_to_check,const char ** extension_list,uint32_t extension_count)477 static bool CheckExtensionEnabled(const char *extension_to_check, const char **extension_list, uint32_t extension_count) {
478 for (uint32_t i = 0; i < extension_count; i++) {
479 if (!strcmp(extension_to_check, extension_list[i])) return true;
480 }
481 return false;
482 }
483
AppDevInitFormats(struct AppDev * dev)484 static void AppDevInitFormats(struct AppDev *dev) {
485 VkFormat f;
486 for (f = 0; f < VK_FORMAT_RANGE_SIZE; f++) {
487 const VkFormat fmt = f;
488 vkGetPhysicalDeviceFormatProperties(dev->gpu->obj, fmt, &dev->format_props[f]);
489
490 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, dev->gpu->inst->inst_extensions,
491 dev->gpu->inst->inst_extensions_count)) {
492 dev->format_props2[f].sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR;
493 dev->format_props2[f].pNext = NULL;
494 dev->gpu->inst->vkGetPhysicalDeviceFormatProperties2KHR(dev->gpu->obj, fmt, &dev->format_props2[f]);
495 }
496 }
497 }
498
ExtractVersion(uint32_t version,uint32_t * major,uint32_t * minor,uint32_t * patch)499 static void ExtractVersion(uint32_t version, uint32_t *major, uint32_t *minor, uint32_t *patch) {
500 *major = version >> 22;
501 *minor = (version >> 12) & 0x3ff;
502 *patch = version & 0xfff;
503 }
504
AppGetPhysicalDeviceLayerExtensions(struct AppGpu * gpu,char * layer_name,uint32_t * extension_count,VkExtensionProperties ** extension_properties)505 static void AppGetPhysicalDeviceLayerExtensions(struct AppGpu *gpu, char *layer_name, uint32_t *extension_count,
506 VkExtensionProperties **extension_properties) {
507 VkResult err;
508 uint32_t ext_count = 0;
509 VkExtensionProperties *ext_ptr = NULL;
510
511 /* repeat get until VK_INCOMPLETE goes away */
512 do {
513 err = vkEnumerateDeviceExtensionProperties(gpu->obj, layer_name, &ext_count, NULL);
514 assert(!err);
515
516 if (ext_ptr) {
517 free(ext_ptr);
518 }
519 ext_ptr = malloc(ext_count * sizeof(VkExtensionProperties));
520 err = vkEnumerateDeviceExtensionProperties(gpu->obj, layer_name, &ext_count, ext_ptr);
521 } while (err == VK_INCOMPLETE);
522 assert(!err);
523
524 *extension_count = ext_count;
525 *extension_properties = ext_ptr;
526 }
527
AppDevInit(struct AppDev * dev,struct AppGpu * gpu)528 static void AppDevInit(struct AppDev *dev, struct AppGpu *gpu) {
529 VkDeviceCreateInfo info = {
530 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
531 .pNext = NULL,
532 .flags = 0,
533 .queueCreateInfoCount = 0,
534 .pQueueCreateInfos = NULL,
535 .enabledLayerCount = 0,
536 .ppEnabledLayerNames = NULL,
537 .enabledExtensionCount = 0,
538 .ppEnabledExtensionNames = NULL,
539 };
540 VkResult U_ASSERT_ONLY err;
541
542 // Device extensions
543 AppGetPhysicalDeviceLayerExtensions(gpu, NULL, &gpu->device_extension_count, &gpu->device_extensions);
544
545 fflush(stdout);
546
547 /* request all queues */
548 info.queueCreateInfoCount = gpu->queue_count;
549 info.pQueueCreateInfos = gpu->queue_reqs;
550
551 info.enabledLayerCount = 0;
552 info.ppEnabledLayerNames = NULL;
553 info.enabledExtensionCount = 0;
554 info.ppEnabledExtensionNames = NULL;
555 dev->gpu = gpu;
556 err = vkCreateDevice(gpu->obj, &info, NULL, &dev->obj);
557 if (err) ERR_EXIT(err);
558 }
559
AppDevDestroy(struct AppDev * dev)560 static void AppDevDestroy(struct AppDev *dev) {
561 vkDeviceWaitIdle(dev->obj);
562 vkDestroyDevice(dev->obj, NULL);
563 }
564
AppGetGlobalLayerExtensions(char * layer_name,uint32_t * extension_count,VkExtensionProperties ** extension_properties)565 static void AppGetGlobalLayerExtensions(char *layer_name, uint32_t *extension_count, VkExtensionProperties **extension_properties) {
566 VkResult err;
567 uint32_t ext_count = 0;
568 VkExtensionProperties *ext_ptr = NULL;
569
570 /* repeat get until VK_INCOMPLETE goes away */
571 do {
572 // gets the extension count if the last parameter is NULL
573 err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, NULL);
574 assert(!err);
575
576 if (ext_ptr) {
577 free(ext_ptr);
578 }
579 ext_ptr = malloc(ext_count * sizeof(VkExtensionProperties));
580 // gets the extension properties if the last parameter is not NULL
581 err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, ext_ptr);
582 } while (err == VK_INCOMPLETE);
583 assert(!err);
584 *extension_count = ext_count;
585 *extension_properties = ext_ptr;
586 }
587
588 /* Gets a list of layer and instance extensions */
AppGetInstanceExtensions(struct AppInstance * inst)589 static void AppGetInstanceExtensions(struct AppInstance *inst) {
590 VkResult U_ASSERT_ONLY err;
591
592 uint32_t count = 0;
593
594 /* Scan layers */
595 VkLayerProperties *global_layer_properties = NULL;
596 struct LayerExtensionList *global_layers = NULL;
597
598 do {
599 err = vkEnumerateInstanceLayerProperties(&count, NULL);
600 assert(!err);
601
602 if (global_layer_properties) {
603 free(global_layer_properties);
604 }
605 global_layer_properties = malloc(sizeof(VkLayerProperties) * count);
606 assert(global_layer_properties);
607
608 if (global_layers) {
609 free(global_layers);
610 }
611 global_layers = malloc(sizeof(struct LayerExtensionList) * count);
612 assert(global_layers);
613
614 err = vkEnumerateInstanceLayerProperties(&count, global_layer_properties);
615 } while (err == VK_INCOMPLETE);
616 assert(!err);
617
618 inst->global_layer_count = count;
619 inst->global_layers = global_layers;
620
621 for (uint32_t i = 0; i < inst->global_layer_count; i++) {
622 VkLayerProperties *src_info = &global_layer_properties[i];
623 struct LayerExtensionList *dst_info = &inst->global_layers[i];
624 memcpy(&dst_info->layer_properties, src_info, sizeof(VkLayerProperties));
625
626 // Save away layer extension info for report
627 // Gets layer extensions, if first parameter is not NULL
628 AppGetGlobalLayerExtensions(src_info->layerName, &dst_info->extension_count, &dst_info->extension_properties);
629 }
630 free(global_layer_properties);
631
632 // Collect global extensions
633 inst->global_extension_count = 0;
634 // Gets instance extensions, if no layer was specified in the first
635 // paramteter
636 AppGetGlobalLayerExtensions(NULL, &inst->global_extension_count, &inst->global_extensions);
637 }
638
639 // Prints opening CSS and HTML code for html output file
640 // Defines various div text styles
PrintHtmlHeader(FILE * out)641 void PrintHtmlHeader(FILE *out) {
642 fprintf(out, "<!doctype html>\n");
643 fprintf(out, "<html>\n");
644 fprintf(out, "\t<head>\n");
645 fprintf(out, "\t\t<title>Vulkan Info</title>\n");
646 fprintf(out, "\t\t<style type='text/css'>\n");
647 fprintf(out, "\t\thtml {\n");
648 fprintf(out, "\t\t\tbackground-color: #0b1e48;\n");
649 fprintf(out, "\t\t\tbackground-image: url(\"https://vulkan.lunarg.com/img/bg-starfield.jpg\");\n");
650 fprintf(out, "\t\t\tbackground-position: center;\n");
651 fprintf(out, "\t\t\t-webkit-background-size: cover;\n");
652 fprintf(out, "\t\t\t-moz-background-size: cover;\n");
653 fprintf(out, "\t\t\t-o-background-size: cover;\n");
654 fprintf(out, "\t\t\tbackground-size: cover;\n");
655 fprintf(out, "\t\t\tbackground-attachment: fixed;\n");
656 fprintf(out, "\t\t\tbackground-repeat: no-repeat;\n");
657 fprintf(out, "\t\t\theight: 100%%;\n");
658 fprintf(out, "\t\t}\n");
659 fprintf(out, "\t\t#header {\n");
660 fprintf(out, "\t\t\tz-index: -1;\n");
661 fprintf(out, "\t\t}\n");
662 fprintf(out, "\t\t#header>img {\n");
663 fprintf(out, "\t\t\tposition: absolute;\n");
664 fprintf(out, "\t\t\twidth: 160px;\n");
665 fprintf(out, "\t\t\tmargin-left: -280px;\n");
666 fprintf(out, "\t\t\ttop: -10px;\n");
667 fprintf(out, "\t\t\tleft: 50%%;\n");
668 fprintf(out, "\t\t}\n");
669 fprintf(out, "\t\t#header>h1 {\n");
670 fprintf(out, "\t\t\tfont-family: Arial, \"Helvetica Neue\", Helvetica, sans-serif;\n");
671 fprintf(out, "\t\t\tfont-size: 44px;\n");
672 fprintf(out, "\t\t\tfont-weight: 200;\n");
673 fprintf(out, "\t\t\ttext-shadow: 4px 4px 5px #000;\n");
674 fprintf(out, "\t\t\tcolor: #eee;\n");
675 fprintf(out, "\t\t\tposition: absolute;\n");
676 fprintf(out, "\t\t\twidth: 400px;\n");
677 fprintf(out, "\t\t\tmargin-left: -80px;\n");
678 fprintf(out, "\t\t\ttop: 8px;\n");
679 fprintf(out, "\t\t\tleft: 50%%;\n");
680 fprintf(out, "\t\t}\n");
681 fprintf(out, "\t\tbody {\n");
682 fprintf(out, "\t\t\tfont-family: Consolas, monaco, monospace;\n");
683 fprintf(out, "\t\t\tfont-size: 14px;\n");
684 fprintf(out, "\t\t\tline-height: 20px;\n");
685 fprintf(out, "\t\t\tcolor: #eee;\n");
686 fprintf(out, "\t\t\theight: 100%%;\n");
687 fprintf(out, "\t\t\tmargin: 0;\n");
688 fprintf(out, "\t\t\toverflow: hidden;\n");
689 fprintf(out, "\t\t}\n");
690 fprintf(out, "\t\t#wrapper {\n");
691 fprintf(out, "\t\t\tbackground-color: rgba(0, 0, 0, 0.7);\n");
692 fprintf(out, "\t\t\tborder: 1px solid #446;\n");
693 fprintf(out, "\t\t\tbox-shadow: 0px 0px 10px #000;\n");
694 fprintf(out, "\t\t\tpadding: 8px 12px;\n\n");
695 fprintf(out, "\t\t\tdisplay: inline-block;\n");
696 fprintf(out, "\t\t\tposition: absolute;\n");
697 fprintf(out, "\t\t\ttop: 80px;\n");
698 fprintf(out, "\t\t\tbottom: 25px;\n");
699 fprintf(out, "\t\t\tleft: 50px;\n");
700 fprintf(out, "\t\t\tright: 50px;\n");
701 fprintf(out, "\t\t\toverflow: auto;\n");
702 fprintf(out, "\t\t}\n");
703 fprintf(out, "\t\tdetails>details {\n");
704 fprintf(out, "\t\t\tmargin-left: 22px;\n");
705 fprintf(out, "\t\t}\n");
706 fprintf(out, "\t\tdetails>summary:only-child::-webkit-details-marker {\n");
707 fprintf(out, "\t\t\tdisplay: none;\n");
708 fprintf(out, "\t\t}\n");
709 fprintf(out, "\t\t.var, .type, .val {\n");
710 fprintf(out, "\t\t\tdisplay: inline;\n");
711 fprintf(out, "\t\t}\n");
712 fprintf(out, "\t\t.var {\n");
713 fprintf(out, "\t\t}\n");
714 fprintf(out, "\t\t.type {\n");
715 fprintf(out, "\t\t\tcolor: #acf;\n");
716 fprintf(out, "\t\t\tmargin: 0 12px;\n");
717 fprintf(out, "\t\t}\n");
718 fprintf(out, "\t\t.val {\n");
719 fprintf(out, "\t\t\tcolor: #afa;\n");
720 fprintf(out, "\t\t\tbackground: #222;\n");
721 fprintf(out, "\t\t\ttext-align: right;\n");
722 fprintf(out, "\t\t}\n");
723 fprintf(out, "\t\t</style>\n");
724 fprintf(out, "\t</head>\n");
725 fprintf(out, "\t<body>\n");
726 fprintf(out, "\t\t<div id='header'>\n");
727 fprintf(out, "\t\t\t<img src='C:/Git/VulkanTools/layersvt/images/lunarg.png' />\n");
728 fprintf(out, "\t\t\t<h1>Vulkan Info</h1>\n");
729 fprintf(out, "\t\t</div>\n");
730 fprintf(out, "\t\t<div id='wrapper'>\n");
731 }
732
733 // Prints closing HTML code for html output file
PrintHtmlFooter(FILE * out)734 void PrintHtmlFooter(FILE *out) {
735 fprintf(out, "\t\t</div>\n");
736 fprintf(out, "\t</body>\n");
737 fprintf(out, "</html>");
738 }
739
740 // static void AppCreateInstance(struct AppInstance *inst, int argc, ...) {
AppCreateInstance(struct AppInstance * inst)741 static void AppCreateInstance(struct AppInstance *inst) {
742 AppGetInstanceExtensions(inst);
743
744 //---Build a list of extensions to load---
745
746 const char *info_instance_extensions[] = {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
747 VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME,
748 VK_KHR_SURFACE_EXTENSION_NAME,
749 VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
750 VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME,
751 #ifdef VK_USE_PLATFORM_WIN32_KHR
752 VK_KHR_WIN32_SURFACE_EXTENSION_NAME
753 #elif VK_USE_PLATFORM_XCB_KHR
754 VK_KHR_XCB_SURFACE_EXTENSION_NAME
755 #elif VK_USE_PLATFORM_XLIB_KHR
756 VK_KHR_XLIB_SURFACE_EXTENSION_NAME
757 #elif VK_USE_PLATFORM_WAYLAND_KHR
758 VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
759 #elif VK_USE_PLATFORM_ANDROID_KHR
760 VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
761 #endif
762 };
763 uint32_t info_instance_extensions_count = ARRAY_SIZE(info_instance_extensions);
764 inst->inst_extensions = malloc(sizeof(char *) * ARRAY_SIZE(info_instance_extensions));
765 inst->inst_extensions_count = 0;
766
767 for (uint32_t k = 0; (k < info_instance_extensions_count); k++) {
768 for (uint32_t j = 0; (j < inst->global_extension_count); j++) {
769 const char *found_name = inst->global_extensions[j].extensionName;
770 if (!strcmp(info_instance_extensions[k], found_name)) {
771 inst->inst_extensions[inst->inst_extensions_count++] = info_instance_extensions[k];
772 break;
773 }
774 }
775 }
776
777 //----------------------------------------
778
779 const VkApplicationInfo app_info = {
780 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
781 .pNext = NULL,
782 .pApplicationName = APP_SHORT_NAME,
783 .applicationVersion = 1,
784 .pEngineName = APP_SHORT_NAME,
785 .engineVersion = 1,
786 .apiVersion = VK_API_VERSION_1_0,
787 };
788
789 VkInstanceCreateInfo inst_info = {.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
790 .pNext = NULL,
791 .pApplicationInfo = &app_info,
792 .enabledLayerCount = 0,
793 .ppEnabledLayerNames = NULL,
794 .enabledExtensionCount = inst->inst_extensions_count,
795 .ppEnabledExtensionNames = inst->inst_extensions};
796
797 VkDebugReportCallbackCreateInfoEXT dbg_info;
798 memset(&dbg_info, 0, sizeof(dbg_info));
799 dbg_info.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
800 dbg_info.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
801 dbg_info.pfnCallback = DbgCallback;
802 inst_info.pNext = &dbg_info;
803
804 VkResult U_ASSERT_ONLY err;
805 err = vkCreateInstance(&inst_info, NULL, &inst->instance);
806 if (err == VK_ERROR_INCOMPATIBLE_DRIVER) {
807 printf("Cannot create Vulkan instance.\n");
808 ERR_EXIT(err);
809 } else if (err) {
810 ERR_EXIT(err);
811 }
812
813 inst->vkGetPhysicalDeviceSurfaceSupportKHR =
814 (PFN_vkGetPhysicalDeviceSurfaceSupportKHR)vkGetInstanceProcAddr(inst->instance, "vkGetPhysicalDeviceSurfaceSupportKHR");
815 inst->vkGetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)vkGetInstanceProcAddr(
816 inst->instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
817 inst->vkGetPhysicalDeviceSurfaceFormatsKHR =
818 (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)vkGetInstanceProcAddr(inst->instance, "vkGetPhysicalDeviceSurfaceFormatsKHR");
819 inst->vkGetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)vkGetInstanceProcAddr(
820 inst->instance, "vkGetPhysicalDeviceSurfacePresentModesKHR");
821 inst->vkGetPhysicalDeviceProperties2KHR =
822 (PFN_vkGetPhysicalDeviceProperties2KHR)vkGetInstanceProcAddr(inst->instance, "vkGetPhysicalDeviceProperties2KHR");
823 inst->vkGetPhysicalDeviceFormatProperties2KHR = (PFN_vkGetPhysicalDeviceFormatProperties2KHR)vkGetInstanceProcAddr(
824 inst->instance, "vkGetPhysicalDeviceFormatProperties2KHR");
825 inst->vkGetPhysicalDeviceQueueFamilyProperties2KHR = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)vkGetInstanceProcAddr(
826 inst->instance, "vkGetPhysicalDeviceQueueFamilyProperties2KHR");
827 inst->vkGetPhysicalDeviceFeatures2KHR =
828 (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(inst->instance, "vkGetPhysicalDeviceFeatures2KHR");
829 inst->vkGetPhysicalDeviceMemoryProperties2KHR = (PFN_vkGetPhysicalDeviceMemoryProperties2KHR)vkGetInstanceProcAddr(
830 inst->instance, "vkGetPhysicalDeviceMemoryProperties2KHR");
831 inst->vkGetPhysicalDeviceSurfaceCapabilities2KHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR)vkGetInstanceProcAddr(
832 inst->instance, "vkGetPhysicalDeviceSurfaceCapabilities2KHR");
833 inst->vkGetPhysicalDeviceSurfaceCapabilities2EXT = (PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT)vkGetInstanceProcAddr(
834 inst->instance, "vkGetPhysicalDeviceSurfaceCapabilities2EXT");
835 }
836
837 //-----------------------------------------------------------
838
AppDestroyInstance(struct AppInstance * inst)839 static void AppDestroyInstance(struct AppInstance *inst) {
840 free(inst->global_extensions);
841 for (uint32_t i = 0; i < inst->global_layer_count; i++) {
842 free(inst->global_layers[i].extension_properties);
843 }
844 free(inst->global_layers);
845 free((char **)inst->inst_extensions);
846 vkDestroyInstance(inst->instance, NULL);
847 }
848
AppGpuInit(struct AppGpu * gpu,struct AppInstance * inst,uint32_t id,VkPhysicalDevice obj)849 static void AppGpuInit(struct AppGpu *gpu, struct AppInstance *inst, uint32_t id, VkPhysicalDevice obj) {
850 uint32_t i;
851
852 memset(gpu, 0, sizeof(*gpu));
853
854 gpu->id = id;
855 gpu->obj = obj;
856 gpu->inst = inst;
857
858 vkGetPhysicalDeviceProperties(gpu->obj, &gpu->props);
859
860 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
861 gpu->inst->inst_extensions_count)) {
862 gpu->props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
863 gpu->props2.pNext = NULL;
864
865 inst->vkGetPhysicalDeviceProperties2KHR(gpu->obj, &gpu->props2);
866 }
867
868 /* get queue count */
869 vkGetPhysicalDeviceQueueFamilyProperties(gpu->obj, &gpu->queue_count, NULL);
870
871 gpu->queue_props = malloc(sizeof(gpu->queue_props[0]) * gpu->queue_count);
872
873 if (!gpu->queue_props) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
874 vkGetPhysicalDeviceQueueFamilyProperties(gpu->obj, &gpu->queue_count, gpu->queue_props);
875
876 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
877 gpu->inst->inst_extensions_count)) {
878 gpu->queue_props2 = malloc(sizeof(gpu->queue_props2[0]) * gpu->queue_count);
879
880 if (!gpu->queue_props2) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
881
882 for (i = 0; i < gpu->queue_count; i++) {
883 gpu->queue_props2[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR;
884 gpu->queue_props2[i].pNext = NULL;
885 }
886
887 inst->vkGetPhysicalDeviceQueueFamilyProperties2KHR(gpu->obj, &gpu->queue_count, gpu->queue_props2);
888 }
889
890 /* set up queue requests */
891 gpu->queue_reqs = malloc(sizeof(*gpu->queue_reqs) * gpu->queue_count);
892 if (!gpu->queue_reqs) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
893 for (i = 0; i < gpu->queue_count; i++) {
894 float *queue_priorities = malloc(gpu->queue_props[i].queueCount * sizeof(float));
895 if (!queue_priorities) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
896 memset(queue_priorities, 0, gpu->queue_props[i].queueCount * sizeof(float));
897
898 gpu->queue_reqs[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
899 gpu->queue_reqs[i].pNext = NULL;
900 gpu->queue_reqs[i].flags = 0;
901 gpu->queue_reqs[i].queueFamilyIndex = i;
902 gpu->queue_reqs[i].queueCount = gpu->queue_props[i].queueCount;
903 gpu->queue_reqs[i].pQueuePriorities = queue_priorities;
904 }
905
906 vkGetPhysicalDeviceMemoryProperties(gpu->obj, &gpu->memory_props);
907
908 vkGetPhysicalDeviceFeatures(gpu->obj, &gpu->features);
909
910 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
911 gpu->inst->inst_extensions_count)) {
912 gpu->memory_props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR;
913 gpu->memory_props2.pNext = NULL;
914
915 inst->vkGetPhysicalDeviceMemoryProperties2KHR(gpu->obj, &gpu->memory_props2);
916
917 gpu->features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
918 gpu->features2.pNext = NULL;
919
920 inst->vkGetPhysicalDeviceFeatures2KHR(gpu->obj, &gpu->features2);
921 }
922
923 AppDevInit(&gpu->dev, gpu);
924 AppDevInitFormats(&gpu->dev);
925 }
926
AppGpuDestroy(struct AppGpu * gpu)927 static void AppGpuDestroy(struct AppGpu *gpu) {
928 AppDevDestroy(&gpu->dev);
929 free(gpu->device_extensions);
930
931 for (uint32_t i = 0; i < gpu->queue_count; i++) {
932 free((void *)gpu->queue_reqs[i].pQueuePriorities);
933 }
934 free(gpu->queue_reqs);
935
936 free(gpu->queue_props);
937 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions,
938 gpu->inst->inst_extensions_count)) {
939 free(gpu->queue_props2);
940 }
941 }
942
943 // clang-format off
944
945 //-----------------------------------------------------------
946
947 //---------------------------Win32---------------------------
948 #ifdef VK_USE_PLATFORM_WIN32_KHR
949
950 // MS-Windows event handling function:
WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)951 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
952 return (DefWindowProc(hWnd, uMsg, wParam, lParam));
953 }
954
AppCreateWin32Window(struct AppInstance * inst)955 static void AppCreateWin32Window(struct AppInstance *inst) {
956 inst->h_instance = GetModuleHandle(NULL);
957
958 WNDCLASSEX win_class;
959
960 // Initialize the window class structure:
961 win_class.cbSize = sizeof(WNDCLASSEX);
962 win_class.style = CS_HREDRAW | CS_VREDRAW;
963 win_class.lpfnWndProc = WndProc;
964 win_class.cbClsExtra = 0;
965 win_class.cbWndExtra = 0;
966 win_class.hInstance = inst->h_instance;
967 win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
968 win_class.hCursor = LoadCursor(NULL, IDC_ARROW);
969 win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
970 win_class.lpszMenuName = NULL;
971 win_class.lpszClassName = APP_SHORT_NAME;
972 win_class.hInstance = inst->h_instance;
973 win_class.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
974 // Register window class:
975 if (!RegisterClassEx(&win_class)) {
976 // It didn't work, so try to give a useful error:
977 printf("Failed to register the window class!\n");
978 fflush(stdout);
979 exit(1);
980 }
981 // Create window with the registered class:
982 RECT wr = { 0, 0, inst->width, inst->height };
983 AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
984 inst->h_wnd = CreateWindowEx(0,
985 APP_SHORT_NAME, // class name
986 APP_SHORT_NAME, // app name
987 //WS_VISIBLE | WS_SYSMENU |
988 WS_OVERLAPPEDWINDOW, // window style
989 100, 100, // x/y coords
990 wr.right - wr.left, // width
991 wr.bottom - wr.top, // height
992 NULL, // handle to parent
993 NULL, // handle to menu
994 inst->h_instance, // hInstance
995 NULL); // no extra parameters
996 if (!inst->h_wnd) {
997 // It didn't work, so try to give a useful error:
998 printf("Failed to create a window!\n");
999 fflush(stdout);
1000 exit(1);
1001 }
1002 }
1003
AppCreateWin32Surface(struct AppInstance * inst)1004 static void AppCreateWin32Surface(struct AppInstance *inst) {
1005 VkResult U_ASSERT_ONLY err;
1006 VkWin32SurfaceCreateInfoKHR createInfo;
1007 createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
1008 createInfo.pNext = NULL;
1009 createInfo.flags = 0;
1010 createInfo.hinstance = inst->h_instance;
1011 createInfo.hwnd = inst->h_wnd;
1012 err = vkCreateWin32SurfaceKHR(inst->instance, &createInfo, NULL, &inst->surface);
1013 assert(!err);
1014 }
1015
AppDestroyWin32Window(struct AppInstance * inst)1016 static void AppDestroyWin32Window(struct AppInstance *inst) {
1017 DestroyWindow(inst->h_wnd);
1018 }
1019 #endif //VK_USE_PLATFORM_WIN32_KHR
1020 //-----------------------------------------------------------
1021
1022 #if defined(VK_USE_PLATFORM_XCB_KHR) || \
1023 defined(VK_USE_PLATFORM_XLIB_KHR) || \
1024 defined(VK_USE_PLATFORM_WIN32_KHR)
AppDestroySurface(struct AppInstance * inst)1025 static void AppDestroySurface(struct AppInstance *inst) { //same for all platforms
1026 vkDestroySurfaceKHR(inst->instance, inst->surface, NULL);
1027 }
1028 #endif
1029
1030 //----------------------------XCB----------------------------
1031
1032 #ifdef VK_USE_PLATFORM_XCB_KHR
AppCreateXcbWindow(struct AppInstance * inst)1033 static void AppCreateXcbWindow(struct AppInstance *inst) {
1034 //--Init Connection--
1035 const xcb_setup_t *setup;
1036 xcb_screen_iterator_t iter;
1037 int scr;
1038
1039 // API guarantees non-null xcb_connection
1040 inst->xcb_connection = xcb_connect(NULL, &scr);
1041 int conn_error = xcb_connection_has_error(inst->xcb_connection);
1042 if (conn_error) {
1043 fprintf(stderr, "XCB failed to connect to the X server due to error:%d.\n", conn_error);
1044 fflush(stderr);
1045 inst->xcb_connection = NULL;
1046 }
1047
1048 setup = xcb_get_setup(inst->xcb_connection);
1049 iter = xcb_setup_roots_iterator(setup);
1050 while (scr-- > 0) {
1051 xcb_screen_next(&iter);
1052 }
1053
1054 inst->xcb_screen = iter.data;
1055 //-------------------
1056
1057 inst->xcb_window = xcb_generate_id(inst->xcb_connection);
1058 xcb_create_window(inst->xcb_connection, XCB_COPY_FROM_PARENT, inst->xcb_window,
1059 inst->xcb_screen->root, 0, 0, inst->width, inst->height, 0,
1060 XCB_WINDOW_CLASS_INPUT_OUTPUT, inst->xcb_screen->root_visual,
1061 0, NULL);
1062
1063 xcb_intern_atom_cookie_t cookie = xcb_intern_atom(inst->xcb_connection, 1, 12, "WM_PROTOCOLS");
1064 xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(inst->xcb_connection, cookie, 0);
1065 free(reply);
1066 }
1067
AppCreateXcbSurface(struct AppInstance * inst)1068 static void AppCreateXcbSurface(struct AppInstance *inst) {
1069 if (!inst->xcb_connection) {
1070 return;
1071 }
1072
1073 VkResult U_ASSERT_ONLY err;
1074 VkXcbSurfaceCreateInfoKHR xcb_createInfo;
1075 xcb_createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
1076 xcb_createInfo.pNext = NULL;
1077 xcb_createInfo.flags = 0;
1078 xcb_createInfo.connection = inst->xcb_connection;
1079 xcb_createInfo.window = inst->xcb_window;
1080 err = vkCreateXcbSurfaceKHR(inst->instance, &xcb_createInfo, NULL, &inst->surface);
1081 assert(!err);
1082 }
1083
AppDestroyXcbWindow(struct AppInstance * inst)1084 static void AppDestroyXcbWindow(struct AppInstance *inst) {
1085 if (!inst->xcb_connection) {
1086 return; // Nothing to destroy
1087 }
1088
1089 xcb_destroy_window(inst->xcb_connection, inst->xcb_window);
1090 xcb_disconnect(inst->xcb_connection);
1091 }
1092 //VK_USE_PLATFORM_XCB_KHR
1093 //-----------------------------------------------------------
1094
1095 //----------------------------XLib---------------------------
1096 #elif VK_USE_PLATFORM_XLIB_KHR
AppCreateXlibWindow(struct AppInstance * inst)1097 static void AppCreateXlibWindow(struct AppInstance *inst) {
1098 long visualMask = VisualScreenMask;
1099 int numberOfVisuals;
1100
1101 inst->xlib_display = XOpenDisplay(NULL);
1102 if (inst->xlib_display == NULL) {
1103 printf("XLib failed to connect to the X server.\nExiting ...\n");
1104 fflush(stdout);
1105 exit(1);
1106 }
1107
1108 XVisualInfo vInfoTemplate={};
1109 vInfoTemplate.screen = DefaultScreen(inst->xlib_display);
1110 XVisualInfo *visualInfo = XGetVisualInfo(inst->xlib_display, visualMask,
1111 &vInfoTemplate, &numberOfVisuals);
1112 inst->xlib_window = XCreateWindow(
1113 inst->xlib_display, RootWindow(inst->xlib_display, vInfoTemplate.screen), 0, 0,
1114 inst->width, inst->height, 0, visualInfo->depth, InputOutput,
1115 visualInfo->visual, 0, NULL);
1116
1117 XSync(inst->xlib_display,false);
1118 }
1119
AppCreateXlibSurface(struct AppInstance * inst)1120 static void AppCreateXlibSurface(struct AppInstance *inst) {
1121 VkResult U_ASSERT_ONLY err;
1122 VkXlibSurfaceCreateInfoKHR createInfo;
1123 createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
1124 createInfo.pNext = NULL;
1125 createInfo.flags = 0;
1126 createInfo.dpy = inst->xlib_display;
1127 createInfo.window = inst->xlib_window;
1128 err = vkCreateXlibSurfaceKHR(inst->instance, &createInfo, NULL, &inst->surface);
1129 assert(!err);
1130 }
1131
AppDestroyXlibWindow(struct AppInstance * inst)1132 static void AppDestroyXlibWindow(struct AppInstance *inst) {
1133 XDestroyWindow(inst->xlib_display, inst->xlib_window);
1134 XCloseDisplay(inst->xlib_display);
1135 }
1136 #endif //VK_USE_PLATFORM_XLIB_KHR
1137 //-----------------------------------------------------------
1138
1139 #if defined(VK_USE_PLATFORM_XCB_KHR) || \
1140 defined(VK_USE_PLATFORM_XLIB_KHR) || \
1141 defined(VK_USE_PLATFORM_WIN32_KHR)
AppDumpSurfaceFormats(struct AppInstance * inst,struct AppGpu * gpu,FILE * out)1142 static int AppDumpSurfaceFormats(struct AppInstance *inst, struct AppGpu *gpu, FILE *out){
1143 // Get the list of VkFormat's that are supported:
1144 VkResult U_ASSERT_ONLY err;
1145 uint32_t format_count = 0;
1146 err = inst->vkGetPhysicalDeviceSurfaceFormatsKHR(gpu->obj, inst->surface, &format_count, NULL);
1147 assert(!err);
1148
1149 VkSurfaceFormatKHR *surf_formats = (VkSurfaceFormatKHR *)malloc(format_count * sizeof(VkSurfaceFormatKHR));
1150 if (!surf_formats)
1151 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
1152 err = inst->vkGetPhysicalDeviceSurfaceFormatsKHR(gpu->obj, inst->surface, &format_count, surf_formats);
1153 assert(!err);
1154
1155 if (html_output) {
1156 fprintf(out, "\t\t\t\t<details><summary>Formats: count = <div class='val'>%d</div></summary>", format_count);
1157 if (format_count > 0) {
1158 fprintf(out, "\n");
1159 } else {
1160 fprintf(out, "</details>\n");
1161 }
1162 } else {
1163 printf("Formats:\t\tcount = %d\n", format_count);
1164 }
1165
1166 for (uint32_t i = 0; i < format_count; i++) {
1167 if (html_output) {
1168 fprintf(out, "\t\t\t\t\t<details><summary><div class='type'>%s</div></summary></details>\n",
1169 VkFormatString(surf_formats[i].format));
1170 } else {
1171 printf("\t%s\n", VkFormatString(surf_formats[i].format));
1172 }
1173 }
1174 if (html_output && format_count > 0) fprintf(out, "\t\t\t\t</details>\n");
1175
1176 fflush(out);
1177 free(surf_formats);
1178 return format_count;
1179 }
1180
AppDumpSurfacePresentModes(struct AppInstance * inst,struct AppGpu * gpu,FILE * out)1181 static int AppDumpSurfacePresentModes(struct AppInstance *inst, struct AppGpu *gpu, FILE *out) {
1182 // Get the list of VkPresentMode's that are supported:
1183 VkResult U_ASSERT_ONLY err;
1184 uint32_t present_mode_count = 0;
1185 err = inst->vkGetPhysicalDeviceSurfacePresentModesKHR(gpu->obj, inst->surface, &present_mode_count, NULL);
1186 assert(!err);
1187
1188 VkPresentModeKHR *surf_present_modes = (VkPresentModeKHR *)malloc(present_mode_count * sizeof(VkPresentInfoKHR));
1189 if (!surf_present_modes)
1190 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
1191 err = inst->vkGetPhysicalDeviceSurfacePresentModesKHR(gpu->obj, inst->surface, &present_mode_count, surf_present_modes);
1192 assert(!err);
1193
1194 if (html_output) {
1195 fprintf(out, "\t\t\t\t<details><summary>Present Modes: count = <div class='val'>%d</div></summary>", present_mode_count);
1196 if (present_mode_count > 0) {
1197 fprintf(out, "\n");
1198 } else {
1199 fprintf(out, "</details>");
1200 }
1201 } else {
1202 printf("Present Modes:\t\tcount = %d\n", present_mode_count);
1203 }
1204
1205 for (uint32_t i = 0; i < present_mode_count; i++) {
1206 if (html_output) {
1207 fprintf(out, "\t\t\t\t\t<details><summary><div class='type'>%s</div></summary></details>\n",
1208 VkPresentModeString(surf_present_modes[i]));
1209 } else {
1210 printf("\t%s\n", VkPresentModeString(surf_present_modes[i]));
1211 }
1212 }
1213 if (html_output && present_mode_count > 0) fprintf(out, "\t\t\t\t</details>\n");
1214
1215 fflush(out);
1216 free(surf_present_modes);
1217 return present_mode_count;
1218 }
1219
AppDumpSurfaceCapabilities(struct AppInstance * inst,struct AppGpu * gpu,FILE * out)1220 static void AppDumpSurfaceCapabilities(struct AppInstance *inst, struct AppGpu *gpu, FILE *out) {
1221 if (CheckExtensionEnabled(VK_KHR_SURFACE_EXTENSION_NAME, gpu->inst->inst_extensions, gpu->inst->inst_extensions_count)) {
1222 inst->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu->obj, inst->surface, &inst->surface_capabilities);
1223
1224 if (html_output) {
1225 fprintf(out, "\t\t\t\t<details><summary>VkSurfaceCapabilitiesKHR</summary>\n");
1226 fprintf(out, "\t\t\t\t\t<details><summary>minImageCount = <div class='val'>%u</div></summary></details>\n", inst->surface_capabilities.minImageCount);
1227 fprintf(out, "\t\t\t\t\t<details><summary>maxImageCount = <div class='val'>%u</div></summary></details>\n", inst->surface_capabilities.maxImageCount);
1228 fprintf(out, "\t\t\t\t\t<details><summary>currentExtent</summary>\n");
1229 fprintf(out, "\t\t\t\t\t\t<details><summary>width = <div class='val'>%u</div></summary></details>\n", inst->surface_capabilities.currentExtent.width);
1230 fprintf(out, "\t\t\t\t\t\t<details><summary>height = <div class='val'>%u</div></summary></details>\n", inst->surface_capabilities.currentExtent.height);
1231 fprintf(out, "\t\t\t\t\t</details>\n");
1232 fprintf(out, "\t\t\t\t\t<details><summary>minImageExtent</summary>\n");
1233 fprintf(out, "\t\t\t\t\t\t<details><summary>width = <div class='val'>%u</div></summary></details>\n", inst->surface_capabilities.minImageExtent.width);
1234 fprintf(out, "\t\t\t\t\t\t<details><summary>height = <div class='val'>%u</div></summary></details>\n", inst->surface_capabilities.minImageExtent.height);
1235 fprintf(out, "\t\t\t\t\t</details>\n");
1236 fprintf(out, "\t\t\t\t\t<details><summary>maxImageExtent</summary>\n");
1237 fprintf(out, "\t\t\t\t\t\t<details><summary>width = <div class='val'>%u</div></summary></details>\n", inst->surface_capabilities.maxImageExtent.width);
1238 fprintf(out, "\t\t\t\t\t\t<details><summary>height = <div class='val'>%u</div></summary></details>\n", inst->surface_capabilities.maxImageExtent.height);
1239 fprintf(out, "\t\t\t\t\t</details>\n");
1240 fprintf(out, "\t\t\t\t\t<details><summary>maxImageArrayLayers = <div class='val'>%u</div></summary></details>\n", inst->surface_capabilities.maxImageArrayLayers);
1241 fprintf(out, "\t\t\t\t\t<details><summary>supportedTransform</summary>\n");
1242 if (inst->surface_capabilities.supportedTransforms == 0) { fprintf(out, "\t\t\t\t\t\t<details><summary>None</summary></details>\n"); }
1243 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
1244 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR</div></summary></details>\n");
1245 }
1246 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR) {
1247 fprintf(out, "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR</div></summary></details>\n");
1248 }
1249 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR) {
1250 fprintf(out, "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR</div></summary></details>\n");
1251 }
1252 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) {
1253 fprintf(out, "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR</div></summary></details>\n");
1254 }
1255 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR) {
1256 fprintf(out, "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR</div></summary></details>\n");
1257 }
1258 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR) {
1259 fprintf(out, "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR</div></summary></details>\n");
1260 }
1261 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR) {
1262 fprintf(out, "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR</div></summary></details>\n");
1263 }
1264 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR) {
1265 fprintf(out, "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR</div></summary></details>\n");
1266 }
1267 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR) {
1268 fprintf(out, "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR</div></summary></details>\n");
1269 }
1270 fprintf(out, "\t\t\t\t\t</details>\n");
1271 fprintf(out, "\t\t\t\t\t<details><summary>currentTransform</summary>\n");
1272 if (inst->surface_capabilities.currentTransform == 0) { fprintf(out, "\t\t\t\t\t\t<details><summary>None</summary></details>\n"); }
1273 if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
1274 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR</div></summary></details>\n");
1275 }
1276 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR) {
1277 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR</div></summary></details>\n");
1278 }
1279 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR) {
1280 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR</div></summary></details>\n");
1281 }
1282 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) {
1283 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR</div></summary></details>\n");
1284 }
1285 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR) {
1286 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR</div></summary></details>\n");
1287 }
1288 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR) {
1289 fprintf(out, "\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR</div></summary></details>\n");
1290 }
1291 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR) {
1292 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR</div></summary></details>\n");
1293 }
1294 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR) {
1295 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR</div></summary></details>\n");
1296 }
1297 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR) {
1298 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR</div></summary></details>\n");
1299 }
1300 fprintf(out, "\t\t\t\t\t</details>\n");
1301 fprintf(out, "\t\t\t\t\t<details><summary>supportedCompositeAlpha</summary>\n");
1302 if (inst->surface_capabilities.supportedCompositeAlpha == 0) { fprintf(out, "\t\t\t\t\t\t<details><summary>None</summary></details>\n"); }
1303 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) {
1304 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR</div></summary></details>\n");
1305 }
1306 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR) {
1307 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR</div></summary></details>\n");
1308 }
1309 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR) {
1310 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR</div></summary></details>\n");
1311 }
1312 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) {
1313 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR</div></summary></details>\n");
1314 }
1315 fprintf(out, "\t\t\t\t\t</details>\n");
1316 fprintf(out, "\t\t\t\t\t<details><summary>supportedUsageFlags</summary>\n");
1317 if (inst->surface_capabilities.supportedUsageFlags == 0) { fprintf(out, "\t\t\t\t\t\t<details><summary>None</summary></details>\n"); }
1318 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
1319 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_IMAGE_USAGE_TRANSFER_SRC_BIT</div></summary></details>\n");
1320 }
1321 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
1322 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_IMAGE_USAGE_TRANSFER_DST_BIT</div></summary></details>\n");
1323 }
1324 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) {
1325 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_IMAGE_USAGE_SAMPLED_BIT</div></summary></details>\n");
1326 }
1327 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT) {
1328 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_IMAGE_USAGE_STORAGE_BIT</div></summary></details>\n");
1329 }
1330 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
1331 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT</div></summary></details>\n");
1332 }
1333 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
1334 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT</div></summary></details>\n");
1335 }
1336 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) {
1337 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT</div></summary></details>\n");
1338 }
1339 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
1340 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT</div></summary></details>\n");
1341 }
1342 fprintf(out, "\t\t\t\t\t</details>\n");
1343 } else {
1344 printf("\nVkSurfaceCapabilitiesKHR:\n");
1345 printf("=========================\n");
1346 printf("\tminImageCount = %u\n", inst->surface_capabilities.minImageCount);
1347 printf("\tmaxImageCount = %u\n", inst->surface_capabilities.maxImageCount);
1348 printf("\tcurrentExtent:\n");
1349 printf("\t\twidth = %u\n", inst->surface_capabilities.currentExtent.width);
1350 printf("\t\theight = %u\n", inst->surface_capabilities.currentExtent.height);
1351 printf("\tminImageExtent:\n");
1352 printf("\t\twidth = %u\n", inst->surface_capabilities.minImageExtent.width);
1353 printf("\t\theight = %u\n", inst->surface_capabilities.minImageExtent.height);
1354 printf("\tmaxImageExtent:\n");
1355 printf("\t\twidth = %u\n", inst->surface_capabilities.maxImageExtent.width);
1356 printf("\t\theight = %u\n", inst->surface_capabilities.maxImageExtent.height);
1357 printf("\tmaxImageArrayLayers = %u\n", inst->surface_capabilities.maxImageArrayLayers);
1358 printf("\tsupportedTransform:\n");
1359 if (inst->surface_capabilities.supportedTransforms == 0) { printf("\t\tNone\n"); }
1360 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR\n"); }
1361 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR\n"); }
1362 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR\n"); }
1363 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR\n"); }
1364 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR\n"); }
1365 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR\n"); }
1366 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR\n"); }
1367 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR\n"); }
1368 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_INHERIT_BIT_KHR\n"); }
1369 printf("\tcurrentTransform:\n");
1370 if (inst->surface_capabilities.currentTransform == 0) { printf("\t\tNone\n"); }
1371 if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR\n"); }
1372 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR\n"); }
1373 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR\n"); }
1374 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR\n"); }
1375 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR\n"); }
1376 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR\n"); }
1377 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR\n"); }
1378 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR\n"); }
1379 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_INHERIT_BIT_KHR\n"); }
1380 printf("\tsupportedCompositeAlpha:\n");
1381 if (inst->surface_capabilities.supportedCompositeAlpha == 0) { printf("\t\tNone\n"); }
1382 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) { printf("\t\tVK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR\n"); }
1383 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR) { printf("\t\tVK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR\n"); }
1384 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR) { printf("\t\tVK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR\n"); }
1385 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) { printf("\t\tVK_COMPOSITE_ALPHA_INHERIT_BIT_KHR\n"); }
1386 printf("\tsupportedUsageFlags:\n");
1387 if (inst->surface_capabilities.supportedUsageFlags == 0) { printf("\t\tNone\n"); }
1388 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) { printf("\t\tVK_IMAGE_USAGE_TRANSFER_SRC_BIT\n"); }
1389 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) { printf("\t\tVK_IMAGE_USAGE_TRANSFER_DST_BIT\n"); }
1390 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) { printf("\t\tVK_IMAGE_USAGE_SAMPLED_BIT\n"); }
1391 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT) { printf("\t\tVK_IMAGE_USAGE_STORAGE_BIT\n"); }
1392 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { printf("\t\tVK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT\n"); }
1393 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { printf("\t\tVK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT\n"); }
1394 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) { printf("\t\tVK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT\n"); }
1395 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) { printf("\t\tVK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT\n"); }
1396 }
1397
1398 // Get additional surface capability information from vkGetPhysicalDeviceSurfaceCapabilities2EXT
1399 if (CheckExtensionEnabled(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME, gpu->inst->inst_extensions, gpu->inst->inst_extensions_count)) {
1400 memset(&inst->surface_capabilities2_ext, 0, sizeof(VkSurfaceCapabilities2EXT));
1401 inst->surface_capabilities2_ext.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT;
1402 inst->surface_capabilities2_ext.pNext = NULL;
1403
1404 inst->vkGetPhysicalDeviceSurfaceCapabilities2EXT(gpu->obj, inst->surface, &inst->surface_capabilities2_ext);
1405
1406 if (html_output) {
1407 fprintf(out, "\t\t\t\t\t<details><summary>VkSurfaceCapabilities2EXT</summary>\n");
1408 fprintf(out, "\t\t\t\t\t\t<details><summary>supportedSurfaceCounters</summary>\n");
1409 if (inst->surface_capabilities2_ext.supportedSurfaceCounters == 0) { fprintf(out, "\t\t\t\t\t\t\t<details><summary>None</summary></details>\n"); }
1410 if (inst->surface_capabilities2_ext.supportedSurfaceCounters & VK_SURFACE_COUNTER_VBLANK_EXT) {
1411 fprintf(out, "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_SURFACE_COUNTER_VBLANK_EXT</div></summary></details>\n");
1412 }
1413 fprintf(out, "\t\t\t\t\t\t</details>\n");
1414 fprintf(out, "\t\t\t\t\t</details>\n");
1415 } else {
1416 printf("\nVkSurfaceCapabilities2EXT:\n");
1417 printf("==========================\n\n");
1418 printf("\tsupportedSurfaceCounters:\n");
1419 if (inst->surface_capabilities2_ext.supportedSurfaceCounters == 0) { printf("\t\tNone\n"); }
1420 if (inst->surface_capabilities2_ext.supportedSurfaceCounters & VK_SURFACE_COUNTER_VBLANK_EXT) { printf("\t\tVK_SURFACE_COUNTER_VBLANK_EXT\n"); }
1421 }
1422 }
1423
1424 // Get additional surface capability information from vkGetPhysicalDeviceSurfaceCapabilities2KHR
1425 if (CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, gpu->inst->inst_extensions_count)) {
1426 if (CheckExtensionEnabled(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, gpu->inst->inst_extensions, gpu->inst->inst_extensions_count)) {
1427 inst->shared_surface_capabilities.sType = VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR;
1428 inst->shared_surface_capabilities.pNext = NULL;
1429 inst->surface_capabilities2.pNext = &inst->shared_surface_capabilities;
1430 } else {
1431 inst->surface_capabilities2.pNext = NULL;
1432 }
1433
1434 inst->surface_capabilities2.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR;
1435
1436 VkPhysicalDeviceSurfaceInfo2KHR surface_info;
1437 surface_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR;
1438 surface_info.pNext = NULL;
1439 surface_info.surface = inst->surface;
1440
1441 inst->vkGetPhysicalDeviceSurfaceCapabilities2KHR(gpu->obj, &surface_info, &inst->surface_capabilities2);
1442
1443 void *place = inst->surface_capabilities2.pNext;
1444 while (place) {
1445 struct VkStructureHeader* work = (struct VkStructureHeader*) place;
1446 if (work->sType == VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR) {
1447 if (html_output) {
1448 fprintf(out, "\t\t\t\t\t<details><summary>VkSharedPresentSurfaceCapabilitiesKHR</summary>\n");
1449 VkSharedPresentSurfaceCapabilitiesKHR* shared_surface_capabilities = (VkSharedPresentSurfaceCapabilitiesKHR*)place;
1450 fprintf(out, "\t\t\t\t\t\t<details><summary>sharedPresentSupportedUsageFlags</summary>\n");
1451 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags == 0) { fprintf(out, "\t\t\t\t\t\t\t<details><summary>None</summary></details>\n"); }
1452 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
1453 fprintf(out, "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_IMAGE_USAGE_TRANSFER_SRC_BIT</div></summary></details>\n");
1454 }
1455 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
1456 fprintf(out, "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_IMAGE_USAGE_TRANSFER_DST_BIT</div></summary></details>\n");
1457 }
1458 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) {
1459 fprintf(out, "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_IMAGE_USAGE_SAMPLED_BIT</div></summary></details>\n");
1460 }
1461 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT) {
1462 fprintf(out, "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_IMAGE_USAGE_STORAGE_BIT</div></summary></details>\n");
1463 }
1464 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
1465 fprintf(out, "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT</div></summary></details>\n");
1466 }
1467 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
1468 fprintf(out, "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT</div></summary></details>\n");
1469 }
1470 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) {
1471 fprintf(out, "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT</div></summary></details>\n");
1472 }
1473 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
1474 fprintf(out, "\t\t\t\t\t\t\t<details><summary><div class='type'>VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT</div></summary></details>\n");
1475 }
1476 fprintf(out, "\t\t\t\t\t\t</details>\n");
1477 fprintf(out, "\t\t\t\t\t</details>\n");
1478 } else {
1479 printf("\nVkSharedPresentSurfaceCapabilitiesKHR:\n");
1480 printf("========================================\n");
1481 VkSharedPresentSurfaceCapabilitiesKHR* shared_surface_capabilities = (VkSharedPresentSurfaceCapabilitiesKHR*)place;
1482 printf("\tsharedPresentSupportedUsageFlags:\n");
1483 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags == 0) { printf("\t\tNone\n"); }
1484 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) { printf("\t\tVK_IMAGE_USAGE_TRANSFER_SRC_BIT\n"); }
1485 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) { printf("\t\tVK_IMAGE_USAGE_TRANSFER_DST_BIT\n"); }
1486 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) { printf("\t\tVK_IMAGE_USAGE_SAMPLED_BIT\n"); }
1487 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT) { printf("\t\tVK_IMAGE_USAGE_STORAGE_BIT\n"); }
1488 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { printf("\t\tVK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT\n"); }
1489 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { printf("\t\tVK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT\n"); }
1490 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) { printf("\t\tVK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT\n"); }
1491 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) { printf("\t\tVK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT\n"); }
1492 }
1493 }
1494 place = work->pNext;
1495 }
1496 }
1497 if (html_output) { fprintf(out, "\t\t\t\t</details>\n"); }
1498 }
1499 }
1500
1501 #endif
1502
AppDevDumpFormatProps(const struct AppDev * dev,VkFormat fmt,FILE * out)1503 static void AppDevDumpFormatProps(const struct AppDev *dev, VkFormat fmt, FILE *out) {
1504 const VkFormatProperties *props = &dev->format_props[fmt];
1505 struct {
1506 const char *name;
1507 VkFlags flags;
1508 } features[3];
1509
1510 features[0].name = "linearTiling FormatFeatureFlags";
1511 features[0].flags = props->linearTilingFeatures;
1512 features[1].name = "optimalTiling FormatFeatureFlags";
1513 features[1].flags = props->optimalTilingFeatures;
1514 features[2].name = "bufferFeatures FormatFeatureFlags";
1515 features[2].flags = props->bufferFeatures;
1516
1517 if (html_output) {
1518 fprintf(out, "\t\t\t\t\t\t<details><summary><div class='type'>FORMAT_%s</div></summary>\n", VkFormatString(fmt));
1519 } else {
1520 printf("\nFORMAT_%s:", VkFormatString(fmt));
1521 }
1522
1523 for (uint32_t i = 0; i < ARRAY_SIZE(features); i++) {
1524 if (html_output) {
1525 fprintf(out, "\t\t\t\t\t\t\t<details open><summary>%s</summary>\n", features[i].name);
1526 if (features[i].flags == 0) {
1527 fprintf(out, "\t\t\t\t\t\t\t\t<details><summary>None</summary></details>\n");
1528 } else {
1529 fprintf(out, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
1530 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT</div></summary></details>\n" : ""), //0x0001
1531 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT</div></summary></details>\n" : ""), //0x0002
1532 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT</div></summary></details>\n" : ""), //0x0004
1533 ((features[i].flags & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT</div></summary></details>\n" : ""), //0x0008
1534 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT</div></summary></details>\n" : ""), //0x0010
1535 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT</div></summary></details>\n" : ""), //0x0020
1536 ((features[i].flags & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT</div></summary></details>\n" : ""), //0x0040
1537 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT</div></summary></details>\n" : ""), //0x0080
1538 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT</div></summary></details>\n" : ""), //0x0100
1539 ((features[i].flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT</div></summary></details>\n" : ""), //0x0200
1540 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_SRC_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_FORMAT_FEATURE_BLIT_SRC_BIT</div></summary></details>\n" : ""), //0x0400
1541 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_DST_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_FORMAT_FEATURE_BLIT_DST_BIT</div></summary></details>\n" : ""), //0x0800
1542 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) ? "\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT</div></summary></details>\n" : ""), //0x1000
1543 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG) ? "\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG</div></summary></details>\n" : ""), //0x2000
1544 ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR) ? "\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR</div></summary></details>\n" : ""), //0x4000
1545 ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR) ? "\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR</div></summary></details>\n" : "")); //0x8000
1546 }
1547 fprintf(out, "\t\t\t\t\t\t\t</details>\n");
1548 } else {
1549 printf("\n\t%s:", features[i].name);
1550 if (features[i].flags == 0) {
1551 printf("\n\t\tNone");
1552 } else {
1553 printf("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
1554 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT" : ""), //0x0001
1555 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_BIT" : ""), //0x0002
1556 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT" : ""), //0x0004
1557 ((features[i].flags & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT" : ""), //0x0008
1558 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT" : ""), //0x0010
1559 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT" : ""), //0x0020
1560 ((features[i].flags & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_VERTEX_BUFFER_BIT" : ""), //0x0040
1561 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT" : ""), //0x0080
1562 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT" : ""), //0x0100
1563 ((features[i].flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) ? "\n\t\tVK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT" : ""), //0x0200
1564 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_SRC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_SRC_BIT" : ""), //0x0400
1565 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_DST_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_DST_BIT" : ""), //0x0800
1566 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT" : ""), //0x1000
1567 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG) ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG" : ""), //0x2000
1568 ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR) ? "\n\t\tVK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR" : ""), //0x4000
1569 ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR) ? "\n\t\tVK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR" : "")); //0x8000
1570 }
1571 }
1572 }
1573
1574 if (html_output) {
1575 fprintf(out, "\t\t\t\t\t\t</details>\n");
1576 } else {
1577 printf("\n");
1578 }
1579 }
1580
AppDevDump(const struct AppDev * dev,FILE * out)1581 static void AppDevDump(const struct AppDev *dev, FILE *out) {
1582 if (html_output) {
1583 fprintf(out, "\t\t\t\t\t<details><summary>Format Properties</summary>\n");
1584 } else {
1585 printf("Format Properties:\n");
1586 printf("==================");
1587 }
1588 VkFormat fmt;
1589 for (fmt = 0; fmt < VK_FORMAT_RANGE_SIZE; fmt++) {
1590 AppDevDumpFormatProps(dev, fmt, out);
1591 }
1592 if (html_output) fprintf(out, "\t\t\t\t\t</details>\n");
1593 }
1594
1595 #ifdef _WIN32
1596 #define PRINTF_SIZE_T_SPECIFIER "%Iu"
1597 #else
1598 #define PRINTF_SIZE_T_SPECIFIER "%zu"
1599 #endif
1600
AppGpuDumpFeatures(const struct AppGpu * gpu,FILE * out)1601 static void AppGpuDumpFeatures(const struct AppGpu *gpu, FILE *out) {
1602 const VkPhysicalDeviceFeatures *features = &gpu->features;
1603
1604 if (html_output) {
1605 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceFeatures</summary>\n");
1606 fprintf(out, "\t\t\t\t\t\t<details><summary>robustBufferAccess = <div class='val'>%u</div></summary></details>\n", features->robustBufferAccess );
1607 fprintf(out, "\t\t\t\t\t\t<details><summary>fullDrawIndexUint32 = <div class='val'>%u</div></summary></details>\n", features->fullDrawIndexUint32 );
1608 fprintf(out, "\t\t\t\t\t\t<details><summary>imageCubeArray = <div class='val'>%u</div></summary></details>\n", features->imageCubeArray );
1609 fprintf(out, "\t\t\t\t\t\t<details><summary>independentBlend = <div class='val'>%u</div></summary></details>\n", features->independentBlend );
1610 fprintf(out, "\t\t\t\t\t\t<details><summary>geometryShader = <div class='val'>%u</div></summary></details>\n", features->geometryShader );
1611 fprintf(out, "\t\t\t\t\t\t<details><summary>tessellationShader = <div class='val'>%u</div></summary></details>\n", features->tessellationShader );
1612 fprintf(out, "\t\t\t\t\t\t<details><summary>sampleRateShading = <div class='val'>%u</div></summary></details>\n", features->sampleRateShading );
1613 fprintf(out, "\t\t\t\t\t\t<details><summary>dualSrcBlend = <div class='val'>%u</div></summary></details>\n", features->dualSrcBlend );
1614 fprintf(out, "\t\t\t\t\t\t<details><summary>logicOp = <div class='val'>%u</div></summary></details>\n", features->logicOp );
1615 fprintf(out, "\t\t\t\t\t\t<details><summary>multiDrawIndirect = <div class='val'>%u</div></summary></details>\n", features->multiDrawIndirect );
1616 fprintf(out, "\t\t\t\t\t\t<details><summary>drawIndirectFirstInstance = <div class='val'>%u</div></summary></details>\n", features->drawIndirectFirstInstance );
1617 fprintf(out, "\t\t\t\t\t\t<details><summary>depthClamp = <div class='val'>%u</div></summary></details>\n", features->depthClamp );
1618 fprintf(out, "\t\t\t\t\t\t<details><summary>depthBiasClamp = <div class='val'>%u</div></summary></details>\n", features->depthBiasClamp );
1619 fprintf(out, "\t\t\t\t\t\t<details><summary>fillModeNonSolid = <div class='val'>%u</div></summary></details>\n", features->fillModeNonSolid );
1620 fprintf(out, "\t\t\t\t\t\t<details><summary>depthBounds = <div class='val'>%u</div></summary></details>\n", features->depthBounds );
1621 fprintf(out, "\t\t\t\t\t\t<details><summary>wideLines = <div class='val'>%u</div></summary></details>\n", features->wideLines );
1622 fprintf(out, "\t\t\t\t\t\t<details><summary>largePoints = <div class='val'>%u</div></summary></details>\n", features->largePoints );
1623 fprintf(out, "\t\t\t\t\t\t<details><summary>alphaToOne = <div class='val'>%u</div></summary></details>\n", features->alphaToOne );
1624 fprintf(out, "\t\t\t\t\t\t<details><summary>multiViewport = <div class='val'>%u</div></summary></details>\n", features->multiViewport );
1625 fprintf(out, "\t\t\t\t\t\t<details><summary>samplerAnisotropy = <div class='val'>%u</div></summary></details>\n", features->samplerAnisotropy );
1626 fprintf(out, "\t\t\t\t\t\t<details><summary>textureCompressionETC2 = <div class='val'>%u</div></summary></details>\n", features->textureCompressionETC2 );
1627 fprintf(out, "\t\t\t\t\t\t<details><summary>textureCompressionASTC_LDR = <div class='val'>%u</div></summary></details>\n", features->textureCompressionASTC_LDR );
1628 fprintf(out, "\t\t\t\t\t\t<details><summary>textureCompressionBC = <div class='val'>%u</div></summary></details>\n", features->textureCompressionBC );
1629 fprintf(out, "\t\t\t\t\t\t<details><summary>occlusionQueryPrecise = <div class='val'>%u</div></summary></details>\n", features->occlusionQueryPrecise );
1630 fprintf(out, "\t\t\t\t\t\t<details><summary>pipelineStatisticsQuery = <div class='val'>%u</div></summary></details>\n", features->pipelineStatisticsQuery );
1631 fprintf(out, "\t\t\t\t\t\t<details><summary>vertexPipelineStoresAndAtomics = <div class='val'>%u</div></summary></details>\n", features->vertexPipelineStoresAndAtomics );
1632 fprintf(out, "\t\t\t\t\t\t<details><summary>fragmentStoresAndAtomics = <div class='val'>%u</div></summary></details>\n", features->fragmentStoresAndAtomics );
1633 fprintf(out, "\t\t\t\t\t\t<details><summary>shaderTessellationAndGeometryPointSize = <div class='val'>%u</div></summary></details>\n", features->shaderTessellationAndGeometryPointSize );
1634 fprintf(out, "\t\t\t\t\t\t<details><summary>shaderImageGatherExtended = <div class='val'>%u</div></summary></details>\n", features->shaderImageGatherExtended );
1635 fprintf(out, "\t\t\t\t\t\t<details><summary>shaderStorageImageExtendedFormats = <div class='val'>%u</div></summary></details>\n", features->shaderStorageImageExtendedFormats );
1636 fprintf(out, "\t\t\t\t\t\t<details><summary>shaderStorageImageMultisample = <div class='val'>%u</div></summary></details>\n", features->shaderStorageImageMultisample );
1637 fprintf(out, "\t\t\t\t\t\t<details><summary>shaderStorageImageReadWithoutFormat = <div class='val'>%u</div></summary></details>\n", features->shaderStorageImageReadWithoutFormat );
1638 fprintf(out, "\t\t\t\t\t\t<details><summary>shaderStorageImageWriteWithoutFormat = <div class='val'>%u</div></summary></details>\n", features->shaderStorageImageWriteWithoutFormat );
1639 fprintf(out, "\t\t\t\t\t\t<details><summary>shaderUniformBufferArrayDynamicIndexing = <div class='val'>%u</div></summary></details>\n", features->shaderUniformBufferArrayDynamicIndexing);
1640 fprintf(out, "\t\t\t\t\t\t<details><summary>shaderSampledImageArrayDynamicIndexing = <div class='val'>%u</div></summary></details>\n", features->shaderSampledImageArrayDynamicIndexing );
1641 fprintf(out, "\t\t\t\t\t\t<details><summary>shaderStorageBufferArrayDynamicIndexing = <div class='val'>%u</div></summary></details>\n", features->shaderStorageBufferArrayDynamicIndexing);
1642 fprintf(out, "\t\t\t\t\t\t<details><summary>shaderStorageImageArrayDynamicIndexing = <div class='val'>%u</div></summary></details>\n", features->shaderStorageImageArrayDynamicIndexing );
1643 fprintf(out, "\t\t\t\t\t\t<details><summary>shaderClipDistance = <div class='val'>%u</div></summary></details>\n", features->shaderClipDistance );
1644 fprintf(out, "\t\t\t\t\t\t<details><summary>shaderCullDistance = <div class='val'>%u</div></summary></details>\n", features->shaderCullDistance );
1645 fprintf(out, "\t\t\t\t\t\t<details><summary>shaderFloat64 = <div class='val'>%u</div></summary></details>\n", features->shaderFloat64 );
1646 fprintf(out, "\t\t\t\t\t\t<details><summary>shaderInt64 = <div class='val'>%u</div></summary></details>\n", features->shaderInt64 );
1647 fprintf(out, "\t\t\t\t\t\t<details><summary>shaderInt16 = <div class='val'>%u</div></summary></details>\n", features->shaderInt16 );
1648 fprintf(out, "\t\t\t\t\t\t<details><summary>shaderResourceResidency = <div class='val'>%u</div></summary></details>\n", features->shaderResourceResidency );
1649 fprintf(out, "\t\t\t\t\t\t<details><summary>shaderResourceMinLod = <div class='val'>%u</div></summary></details>\n", features->shaderResourceMinLod );
1650 fprintf(out, "\t\t\t\t\t\t<details><summary>sparseBinding = <div class='val'>%u</div></summary></details>\n", features->sparseBinding );
1651 fprintf(out, "\t\t\t\t\t\t<details><summary>sparseResidencyBuffer = <div class='val'>%u</div></summary></details>\n", features->sparseResidencyBuffer );
1652 fprintf(out, "\t\t\t\t\t\t<details><summary>sparseResidencyImage2D = <div class='val'>%u</div></summary></details>\n", features->sparseResidencyImage2D );
1653 fprintf(out, "\t\t\t\t\t\t<details><summary>sparseResidencyImage3D = <div class='val'>%u</div></summary></details>\n", features->sparseResidencyImage3D );
1654 fprintf(out, "\t\t\t\t\t\t<details><summary>sparseResidency2Samples = <div class='val'>%u</div></summary></details>\n", features->sparseResidency2Samples );
1655 fprintf(out, "\t\t\t\t\t\t<details><summary>sparseResidency4Samples = <div class='val'>%u</div></summary></details>\n", features->sparseResidency4Samples );
1656 fprintf(out, "\t\t\t\t\t\t<details><summary>sparseResidency8Samples = <div class='val'>%u</div></summary></details>\n", features->sparseResidency8Samples );
1657 fprintf(out, "\t\t\t\t\t\t<details><summary>sparseResidency16Samples = <div class='val'>%u</div></summary></details>\n", features->sparseResidency16Samples );
1658 fprintf(out, "\t\t\t\t\t\t<details><summary>sparseResidencyAliased = <div class='val'>%u</div></summary></details>\n", features->sparseResidencyAliased );
1659 fprintf(out, "\t\t\t\t\t\t<details><summary>variableMultisampleRate = <div class='val'>%u</div></summary></details>\n", features->variableMultisampleRate );
1660 fprintf(out, "\t\t\t\t\t\t<details><summary>inheritedQueries = <div class='val'>%u</div></summary></details>\n", features->inheritedQueries );
1661 fprintf(out, "\t\t\t\t\t</details>\n");
1662 } else {
1663 printf("VkPhysicalDeviceFeatures:\n");
1664 printf("=========================\n");
1665 printf("\trobustBufferAccess = %u\n", features->robustBufferAccess );
1666 printf("\tfullDrawIndexUint32 = %u\n", features->fullDrawIndexUint32 );
1667 printf("\timageCubeArray = %u\n", features->imageCubeArray );
1668 printf("\tindependentBlend = %u\n", features->independentBlend );
1669 printf("\tgeometryShader = %u\n", features->geometryShader );
1670 printf("\ttessellationShader = %u\n", features->tessellationShader );
1671 printf("\tsampleRateShading = %u\n", features->sampleRateShading );
1672 printf("\tdualSrcBlend = %u\n", features->dualSrcBlend );
1673 printf("\tlogicOp = %u\n", features->logicOp );
1674 printf("\tmultiDrawIndirect = %u\n", features->multiDrawIndirect );
1675 printf("\tdrawIndirectFirstInstance = %u\n", features->drawIndirectFirstInstance );
1676 printf("\tdepthClamp = %u\n", features->depthClamp );
1677 printf("\tdepthBiasClamp = %u\n", features->depthBiasClamp );
1678 printf("\tfillModeNonSolid = %u\n", features->fillModeNonSolid );
1679 printf("\tdepthBounds = %u\n", features->depthBounds );
1680 printf("\twideLines = %u\n", features->wideLines );
1681 printf("\tlargePoints = %u\n", features->largePoints );
1682 printf("\talphaToOne = %u\n", features->alphaToOne );
1683 printf("\tmultiViewport = %u\n", features->multiViewport );
1684 printf("\tsamplerAnisotropy = %u\n", features->samplerAnisotropy );
1685 printf("\ttextureCompressionETC2 = %u\n", features->textureCompressionETC2 );
1686 printf("\ttextureCompressionASTC_LDR = %u\n", features->textureCompressionASTC_LDR );
1687 printf("\ttextureCompressionBC = %u\n", features->textureCompressionBC );
1688 printf("\tocclusionQueryPrecise = %u\n", features->occlusionQueryPrecise );
1689 printf("\tpipelineStatisticsQuery = %u\n", features->pipelineStatisticsQuery );
1690 printf("\tvertexPipelineStoresAndAtomics = %u\n", features->vertexPipelineStoresAndAtomics );
1691 printf("\tfragmentStoresAndAtomics = %u\n", features->fragmentStoresAndAtomics );
1692 printf("\tshaderTessellationAndGeometryPointSize = %u\n", features->shaderTessellationAndGeometryPointSize );
1693 printf("\tshaderImageGatherExtended = %u\n", features->shaderImageGatherExtended );
1694 printf("\tshaderStorageImageExtendedFormats = %u\n", features->shaderStorageImageExtendedFormats );
1695 printf("\tshaderStorageImageMultisample = %u\n", features->shaderStorageImageMultisample );
1696 printf("\tshaderStorageImageReadWithoutFormat = %u\n", features->shaderStorageImageReadWithoutFormat );
1697 printf("\tshaderStorageImageWriteWithoutFormat = %u\n", features->shaderStorageImageWriteWithoutFormat );
1698 printf("\tshaderUniformBufferArrayDynamicIndexing = %u\n", features->shaderUniformBufferArrayDynamicIndexing);
1699 printf("\tshaderSampledImageArrayDynamicIndexing = %u\n", features->shaderSampledImageArrayDynamicIndexing );
1700 printf("\tshaderStorageBufferArrayDynamicIndexing = %u\n", features->shaderStorageBufferArrayDynamicIndexing);
1701 printf("\tshaderStorageImageArrayDynamicIndexing = %u\n", features->shaderStorageImageArrayDynamicIndexing );
1702 printf("\tshaderClipDistance = %u\n", features->shaderClipDistance );
1703 printf("\tshaderCullDistance = %u\n", features->shaderCullDistance );
1704 printf("\tshaderFloat64 = %u\n", features->shaderFloat64 );
1705 printf("\tshaderInt64 = %u\n", features->shaderInt64 );
1706 printf("\tshaderInt16 = %u\n", features->shaderInt16 );
1707 printf("\tshaderResourceResidency = %u\n", features->shaderResourceResidency );
1708 printf("\tshaderResourceMinLod = %u\n", features->shaderResourceMinLod );
1709 printf("\tsparseBinding = %u\n", features->sparseBinding );
1710 printf("\tsparseResidencyBuffer = %u\n", features->sparseResidencyBuffer );
1711 printf("\tsparseResidencyImage2D = %u\n", features->sparseResidencyImage2D );
1712 printf("\tsparseResidencyImage3D = %u\n", features->sparseResidencyImage3D );
1713 printf("\tsparseResidency2Samples = %u\n", features->sparseResidency2Samples );
1714 printf("\tsparseResidency4Samples = %u\n", features->sparseResidency4Samples );
1715 printf("\tsparseResidency8Samples = %u\n", features->sparseResidency8Samples );
1716 printf("\tsparseResidency16Samples = %u\n", features->sparseResidency16Samples );
1717 printf("\tsparseResidencyAliased = %u\n", features->sparseResidencyAliased );
1718 printf("\tvariableMultisampleRate = %u\n", features->variableMultisampleRate );
1719 printf("\tinheritedQueries = %u\n", features->inheritedQueries );
1720 }
1721 }
1722
AppDumpSparseProps(const VkPhysicalDeviceSparseProperties * sparse_props,FILE * out)1723 static void AppDumpSparseProps(const VkPhysicalDeviceSparseProperties *sparse_props, FILE *out) {
1724 if (html_output) {
1725 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceSparseProperties</summary>\n");
1726 fprintf(out, "\t\t\t\t\t\t<details><summary>residencyStandard2DBlockShape = <div class='val'>%u</div></summary></details>\n", sparse_props->residencyStandard2DBlockShape );
1727 fprintf(out, "\t\t\t\t\t\t<details><summary>residencyStandard2DMultisampleBlockShape = <div class='val'>%u</div></summary></details>\n", sparse_props->residencyStandard2DMultisampleBlockShape);
1728 fprintf(out, "\t\t\t\t\t\t<details><summary>residencyStandard3DBlockShape = <div class='val'>%u</div></summary></details>\n", sparse_props->residencyStandard3DBlockShape );
1729 fprintf(out, "\t\t\t\t\t\t<details><summary>residencyAlignedMipSize = <div class='val'>%u</div></summary></details>\n", sparse_props->residencyAlignedMipSize );
1730 fprintf(out, "\t\t\t\t\t\t<details><summary>residencyNonResidentStrict = <div class='val'>%u</div></summary></details>\n", sparse_props->residencyNonResidentStrict );
1731 fprintf(out, "\t\t\t\t\t</details>\n");
1732 } else {
1733 printf("\tVkPhysicalDeviceSparseProperties:\n");
1734 printf("\t---------------------------------\n");
1735 printf("\t\tresidencyStandard2DBlockShape = %u\n", sparse_props->residencyStandard2DBlockShape );
1736 printf("\t\tresidencyStandard2DMultisampleBlockShape = %u\n", sparse_props->residencyStandard2DMultisampleBlockShape);
1737 printf("\t\tresidencyStandard3DBlockShape = %u\n", sparse_props->residencyStandard3DBlockShape );
1738 printf("\t\tresidencyAlignedMipSize = %u\n", sparse_props->residencyAlignedMipSize );
1739 printf("\t\tresidencyNonResidentStrict = %u\n", sparse_props->residencyNonResidentStrict );
1740 }
1741 }
1742
AppDumpLimits(const VkPhysicalDeviceLimits * limits,FILE * out)1743 static void AppDumpLimits(const VkPhysicalDeviceLimits *limits, FILE *out) {
1744 if (html_output) {
1745 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceLimits</summary>\n");
1746 fprintf(out, "\t\t\t\t\t\t<details><summary>maxImageDimension1D = <div class='val'>%u</div></summary></details>\n", limits->maxImageDimension1D );
1747 fprintf(out, "\t\t\t\t\t\t<details><summary>maxImageDimension2D = <div class='val'>%u</div></summary></details>\n", limits->maxImageDimension2D );
1748 fprintf(out, "\t\t\t\t\t\t<details><summary>maxImageDimension3D = <div class='val'>%u</div></summary></details>\n", limits->maxImageDimension3D );
1749 fprintf(out, "\t\t\t\t\t\t<details><summary>maxImageDimensionCube = <div class='val'>%u</div></summary></details>\n", limits->maxImageDimensionCube );
1750 fprintf(out, "\t\t\t\t\t\t<details><summary>maxImageArrayLayers = <div class='val'>%u</div></summary></details>\n", limits->maxImageArrayLayers );
1751 fprintf(out, "\t\t\t\t\t\t<details><summary>maxTexelBufferElements = <div class='val'>0x%" PRIxLEAST32 "</div></summary></details>\n", limits->maxTexelBufferElements );
1752 fprintf(out, "\t\t\t\t\t\t<details><summary>maxUniformBufferRange = <div class='val'>0x%" PRIxLEAST32 "</div></summary></details>\n", limits->maxUniformBufferRange );
1753 fprintf(out, "\t\t\t\t\t\t<details><summary>maxStorageBufferRange = <div class='val'>0x%" PRIxLEAST32 "</div></summary></details>\n", limits->maxStorageBufferRange );
1754 fprintf(out, "\t\t\t\t\t\t<details><summary>maxPushConstantsSize = <div class='val'>%u</div></summary></details>\n", limits->maxPushConstantsSize );
1755 fprintf(out, "\t\t\t\t\t\t<details><summary>maxMemoryAllocationCount = <div class='val'>%u</div></summary></details>\n", limits->maxMemoryAllocationCount );
1756 fprintf(out, "\t\t\t\t\t\t<details><summary>maxSamplerAllocationCount = <div class='val'>%u</div></summary></details>\n", limits->maxSamplerAllocationCount );
1757 fprintf(out, "\t\t\t\t\t\t<details><summary>bufferImageGranularity = <div class='val'>0x%" PRIxLEAST64 "</div></summary></details>\n", limits->bufferImageGranularity );
1758 fprintf(out, "\t\t\t\t\t\t<details><summary>sparseAddressSpaceSize = <div class='val'>0x%" PRIxLEAST64 "</div></summary></details>\n", limits->sparseAddressSpaceSize );
1759 fprintf(out, "\t\t\t\t\t\t<details><summary>maxBoundDescriptorSets = <div class='val'>%u</div></summary></details>\n", limits->maxBoundDescriptorSets );
1760 fprintf(out, "\t\t\t\t\t\t<details><summary>maxPerStageDescriptorSamplers = <div class='val'>%u</div></summary></details>\n", limits->maxPerStageDescriptorSamplers );
1761 fprintf(out, "\t\t\t\t\t\t<details><summary>maxPerStageDescriptorUniformBuffers = <div class='val'>%u</div></summary></details>\n", limits->maxPerStageDescriptorUniformBuffers );
1762 fprintf(out, "\t\t\t\t\t\t<details><summary>maxPerStageDescriptorStorageBuffers = <div class='val'>%u</div></summary></details>\n", limits->maxPerStageDescriptorStorageBuffers );
1763 fprintf(out, "\t\t\t\t\t\t<details><summary>maxPerStageDescriptorSampledImages = <div class='val'>%u</div></summary></details>\n", limits->maxPerStageDescriptorSampledImages );
1764 fprintf(out, "\t\t\t\t\t\t<details><summary>maxPerStageDescriptorStorageImages = <div class='val'>%u</div></summary></details>\n", limits->maxPerStageDescriptorStorageImages );
1765 fprintf(out, "\t\t\t\t\t\t<details><summary>maxPerStageDescriptorInputAttachments = <div class='val'>%u</div></summary></details>\n", limits->maxPerStageDescriptorInputAttachments );
1766 fprintf(out, "\t\t\t\t\t\t<details><summary>maxPerStageResources = <div class='val'>%u</div></summary></details>\n", limits->maxPerStageResources );
1767 fprintf(out, "\t\t\t\t\t\t<details><summary>maxDescriptorSetSamplers = <div class='val'>%u</div></summary></details>\n", limits->maxDescriptorSetSamplers );
1768 fprintf(out, "\t\t\t\t\t\t<details><summary>maxDescriptorSetUniformBuffers = <div class='val'>%u</div></summary></details>\n", limits->maxDescriptorSetUniformBuffers );
1769 fprintf(out, "\t\t\t\t\t\t<details><summary>maxDescriptorSetUniformBuffersDynamic = <div class='val'>%u</div></summary></details>\n", limits->maxDescriptorSetUniformBuffersDynamic );
1770 fprintf(out, "\t\t\t\t\t\t<details><summary>maxDescriptorSetStorageBuffers = <div class='val'>%u</div></summary></details>\n", limits->maxDescriptorSetStorageBuffers );
1771 fprintf(out, "\t\t\t\t\t\t<details><summary>maxDescriptorSetStorageBuffersDynamic = <div class='val'>%u</div></summary></details>\n", limits->maxDescriptorSetStorageBuffersDynamic );
1772 fprintf(out, "\t\t\t\t\t\t<details><summary>maxDescriptorSetSampledImages = <div class='val'>%u</div></summary></details>\n", limits->maxDescriptorSetSampledImages );
1773 fprintf(out, "\t\t\t\t\t\t<details><summary>maxDescriptorSetStorageImages = <div class='val'>%u</div></summary></details>\n", limits->maxDescriptorSetStorageImages );
1774 fprintf(out, "\t\t\t\t\t\t<details><summary>maxDescriptorSetInputAttachments = <div class='val'>%u</div></summary></details>\n", limits->maxDescriptorSetInputAttachments );
1775 fprintf(out, "\t\t\t\t\t\t<details><summary>maxVertexInputAttributes = <div class='val'>%u</div></summary></details>\n", limits->maxVertexInputAttributes );
1776 fprintf(out, "\t\t\t\t\t\t<details><summary>maxVertexInputBindings = <div class='val'>%u</div></summary></details>\n", limits->maxVertexInputBindings );
1777 fprintf(out, "\t\t\t\t\t\t<details><summary>maxVertexInputAttributeOffset = <div class='val'>0x%" PRIxLEAST32 "</div></summary></details>\n", limits->maxVertexInputAttributeOffset );
1778 fprintf(out, "\t\t\t\t\t\t<details><summary>maxVertexInputBindingStride = <div class='val'>0x%" PRIxLEAST32 "</div></summary></details>\n", limits->maxVertexInputBindingStride );
1779 fprintf(out, "\t\t\t\t\t\t<details><summary>maxVertexOutputComponents = <div class='val'>%u</div></summary></details>\n", limits->maxVertexOutputComponents );
1780 fprintf(out, "\t\t\t\t\t\t<details><summary>maxTessellationGenerationLevel = <div class='val'>%u</div></summary></details>\n", limits->maxTessellationGenerationLevel );
1781 fprintf(out, "\t\t\t\t\t\t<details><summary>maxTessellationPatchSize = <div class='val'>%u</div></summary></details>\n", limits->maxTessellationPatchSize );
1782 fprintf(out, "\t\t\t\t\t\t<details><summary>maxTessellationControlPerVertexInputComponents = <div class='val'>%u</div></summary></details>\n", limits->maxTessellationControlPerVertexInputComponents );
1783 fprintf(out, "\t\t\t\t\t\t<details><summary>maxTessellationControlPerVertexOutputComponents = <div class='val'>%u</div></summary></details>\n", limits->maxTessellationControlPerVertexOutputComponents);
1784 fprintf(out, "\t\t\t\t\t\t<details><summary>maxTessellationControlPerPatchOutputComponents = <div class='val'>%u</div></summary></details>\n", limits->maxTessellationControlPerPatchOutputComponents );
1785 fprintf(out, "\t\t\t\t\t\t<details><summary>maxTessellationControlTotalOutputComponents = <div class='val'>%u</div></summary></details>\n", limits->maxTessellationControlTotalOutputComponents );
1786 fprintf(out, "\t\t\t\t\t\t<details><summary>maxTessellationEvaluationInputComponents = <div class='val'>%u</div></summary></details>\n", limits->maxTessellationEvaluationInputComponents );
1787 fprintf(out, "\t\t\t\t\t\t<details><summary>maxTessellationEvaluationOutputComponents = <div class='val'>%u</div></summary></details>\n", limits->maxTessellationEvaluationOutputComponents );
1788 fprintf(out, "\t\t\t\t\t\t<details><summary>maxGeometryShaderInvocations = <div class='val'>%u</div></summary></details>\n", limits->maxGeometryShaderInvocations );
1789 fprintf(out, "\t\t\t\t\t\t<details><summary>maxGeometryInputComponents = <div class='val'>%u</div></summary></details>\n", limits->maxGeometryInputComponents );
1790 fprintf(out, "\t\t\t\t\t\t<details><summary>maxGeometryOutputComponents = <div class='val'>%u</div></summary></details>\n", limits->maxGeometryOutputComponents );
1791 fprintf(out, "\t\t\t\t\t\t<details><summary>maxGeometryOutputVertices = <div class='val'>%u</div></summary></details>\n", limits->maxGeometryOutputVertices );
1792 fprintf(out, "\t\t\t\t\t\t<details><summary>maxGeometryTotalOutputComponents = <div class='val'>%u</div></summary></details>\n", limits->maxGeometryTotalOutputComponents );
1793 fprintf(out, "\t\t\t\t\t\t<details><summary>maxFragmentInputComponents = <div class='val'>%u</div></summary></details>\n", limits->maxFragmentInputComponents );
1794 fprintf(out, "\t\t\t\t\t\t<details><summary>maxFragmentOutputAttachments = <div class='val'>%u</div></summary></details>\n", limits->maxFragmentOutputAttachments );
1795 fprintf(out, "\t\t\t\t\t\t<details><summary>maxFragmentDualSrcAttachments = <div class='val'>%u</div></summary></details>\n", limits->maxFragmentDualSrcAttachments );
1796 fprintf(out, "\t\t\t\t\t\t<details><summary>maxFragmentCombinedOutputResources = <div class='val'>%u</div></summary></details>\n", limits->maxFragmentCombinedOutputResources );
1797 fprintf(out, "\t\t\t\t\t\t<details><summary>maxComputeSharedMemorySize = <div class='val'>0x%" PRIxLEAST32 "</div></summary></details>\n", limits->maxComputeSharedMemorySize );
1798 fprintf(out, "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupCount[0] = <div class='val'>%u</div></summary></details>\n", limits->maxComputeWorkGroupCount[0] );
1799 fprintf(out, "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupCount[1] = <div class='val'>%u</div></summary></details>\n", limits->maxComputeWorkGroupCount[1] );
1800 fprintf(out, "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupCount[2] = <div class='val'>%u</div></summary></details>\n", limits->maxComputeWorkGroupCount[2] );
1801 fprintf(out, "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupInvocations = <div class='val'>%u</div></summary></details>\n", limits->maxComputeWorkGroupInvocations );
1802 fprintf(out, "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupSize[0] = <div class='val'>%u</div></summary></details>\n", limits->maxComputeWorkGroupSize[0] );
1803 fprintf(out, "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupSize[1] = <div class='val'>%u</div></summary></details>\n", limits->maxComputeWorkGroupSize[1] );
1804 fprintf(out, "\t\t\t\t\t\t<details><summary>maxComputeWorkGroupSize[2] = <div class='val'>%u</div></summary></details>\n", limits->maxComputeWorkGroupSize[2] );
1805 fprintf(out, "\t\t\t\t\t\t<details><summary>subPixelPrecisionBits = <div class='val'>%u</div></summary></details>\n", limits->subPixelPrecisionBits );
1806 fprintf(out, "\t\t\t\t\t\t<details><summary>subTexelPrecisionBits = <div class='val'>%u</div></summary></details>\n", limits->subTexelPrecisionBits );
1807 fprintf(out, "\t\t\t\t\t\t<details><summary>mipmapPrecisionBits = <div class='val'>%u</div></summary></details>\n", limits->mipmapPrecisionBits );
1808 fprintf(out, "\t\t\t\t\t\t<details><summary>maxDrawIndexedIndexValue = <div class='val'>%u</div></summary></details>\n", limits->maxDrawIndexedIndexValue );
1809 fprintf(out, "\t\t\t\t\t\t<details><summary>maxDrawIndirectCount = <div class='val'>%u</div></summary></details>\n", limits->maxDrawIndirectCount );
1810 fprintf(out, "\t\t\t\t\t\t<details><summary>maxSamplerLodBias = <div class='val'>%f</div></summary></details>\n", limits->maxSamplerLodBias );
1811 fprintf(out, "\t\t\t\t\t\t<details><summary>maxSamplerAnisotropy = <div class='val'>%f</div></summary></details>\n", limits->maxSamplerAnisotropy );
1812 fprintf(out, "\t\t\t\t\t\t<details><summary>maxViewports = <div class='val'>%u</div></summary></details>\n", limits->maxViewports );
1813 fprintf(out, "\t\t\t\t\t\t<details><summary>maxViewportDimensions[0] = <div class='val'>%u</div></summary></details>\n", limits->maxViewportDimensions[0] );
1814 fprintf(out, "\t\t\t\t\t\t<details><summary>maxViewportDimensions[1] = <div class='val'>%u</div></summary></details>\n", limits->maxViewportDimensions[1] );
1815 fprintf(out, "\t\t\t\t\t\t<details><summary>viewportBoundsRange[0] =<div class='val'>%13f</div></summary></details>\n", limits->viewportBoundsRange[0] );
1816 fprintf(out, "\t\t\t\t\t\t<details><summary>viewportBoundsRange[1] =<div class='val'>%13f</div></summary></details>\n", limits->viewportBoundsRange[1] );
1817 fprintf(out, "\t\t\t\t\t\t<details><summary>viewportSubPixelBits = <div class='val'>%u</div></summary></details>\n", limits->viewportSubPixelBits );
1818 fprintf(out, "\t\t\t\t\t\t<details><summary>minMemoryMapAlignment = <div class='val'>" PRINTF_SIZE_T_SPECIFIER "</div></summary></details>\n", limits->minMemoryMapAlignment );
1819 fprintf(out, "\t\t\t\t\t\t<details><summary>minTexelBufferOffsetAlignment = <div class='val'>0x%" PRIxLEAST64 "</div></summary></details>\n", limits->minTexelBufferOffsetAlignment );
1820 fprintf(out, "\t\t\t\t\t\t<details><summary>minUniformBufferOffsetAlignment = <div class='val'>0x%" PRIxLEAST64 "</div></summary></details>\n", limits->minUniformBufferOffsetAlignment );
1821 fprintf(out, "\t\t\t\t\t\t<details><summary>minStorageBufferOffsetAlignment = <div class='val'>0x%" PRIxLEAST64 "</div></summary></details>\n", limits->minStorageBufferOffsetAlignment );
1822 fprintf(out, "\t\t\t\t\t\t<details><summary>minTexelOffset =<div class='val'>%3d</div></summary></details>\n", limits->minTexelOffset );
1823 fprintf(out, "\t\t\t\t\t\t<details><summary>maxTexelOffset =<div class='val'>%3d</div></summary></details>\n", limits->maxTexelOffset );
1824 fprintf(out, "\t\t\t\t\t\t<details><summary>minTexelGatherOffset =<div class='val'>%3d</div></summary></details>\n", limits->minTexelGatherOffset );
1825 fprintf(out, "\t\t\t\t\t\t<details><summary>maxTexelGatherOffset =<div class='val'>%3d</div></summary></details>\n", limits->maxTexelGatherOffset );
1826 fprintf(out, "\t\t\t\t\t\t<details><summary>minInterpolationOffset =<div class='val'>%9f</div></summary></details>\n", limits->minInterpolationOffset );
1827 fprintf(out, "\t\t\t\t\t\t<details><summary>maxInterpolationOffset =<div class='val'>%9f</div></summary></details>\n", limits->maxInterpolationOffset );
1828 fprintf(out, "\t\t\t\t\t\t<details><summary>subPixelInterpolationOffsetBits = <div class='val'>%u</div></summary></details>\n", limits->subPixelInterpolationOffsetBits );
1829 fprintf(out, "\t\t\t\t\t\t<details><summary>maxFramebufferWidth = <div class='val'>%u</div></summary></details>\n", limits->maxFramebufferWidth );
1830 fprintf(out, "\t\t\t\t\t\t<details><summary>maxFramebufferHeight = <div class='val'>%u</div></summary></details>\n", limits->maxFramebufferHeight );
1831 fprintf(out, "\t\t\t\t\t\t<details><summary>maxFramebufferLayers = <div class='val'>%u</div></summary></details>\n", limits->maxFramebufferLayers );
1832 fprintf(out, "\t\t\t\t\t\t<details><summary>framebufferColorSampleCounts = <div class='val'>%u</div></summary></details>\n", limits->framebufferColorSampleCounts );
1833 fprintf(out, "\t\t\t\t\t\t<details><summary>framebufferDepthSampleCounts = <div class='val'>%u</div></summary></details>\n", limits->framebufferDepthSampleCounts );
1834 fprintf(out, "\t\t\t\t\t\t<details><summary>framebufferStencilSampleCounts = <div class='val'>%u</div></summary></details>\n", limits->framebufferStencilSampleCounts );
1835 fprintf(out, "\t\t\t\t\t\t<details><summary>framebufferNoAttachmentsSampleCounts = <div class='val'>%u</div></summary></details>\n", limits->framebufferNoAttachmentsSampleCounts );
1836 fprintf(out, "\t\t\t\t\t\t<details><summary>maxColorAttachments = <div class='val'>%u</div></summary></details>\n", limits->maxColorAttachments );
1837 fprintf(out, "\t\t\t\t\t\t<details><summary>sampledImageColorSampleCounts = <div class='val'>%u</div></summary></details>\n", limits->sampledImageColorSampleCounts );
1838 fprintf(out, "\t\t\t\t\t\t<details><summary>sampledImageDepthSampleCounts = <div class='val'>%u</div></summary></details>\n", limits->sampledImageDepthSampleCounts );
1839 fprintf(out, "\t\t\t\t\t\t<details><summary>sampledImageStencilSampleCounts = <div class='val'>%u</div></summary></details>\n", limits->sampledImageStencilSampleCounts );
1840 fprintf(out, "\t\t\t\t\t\t<details><summary>sampledImageIntegerSampleCounts = <div class='val'>%u</div></summary></details>\n", limits->sampledImageIntegerSampleCounts );
1841 fprintf(out, "\t\t\t\t\t\t<details><summary>storageImageSampleCounts = <div class='val'>%u</div></summary></details>\n", limits->storageImageSampleCounts );
1842 fprintf(out, "\t\t\t\t\t\t<details><summary>maxSampleMaskWords = <div class='val'>%u</div></summary></details>\n", limits->maxSampleMaskWords );
1843 fprintf(out, "\t\t\t\t\t\t<details><summary>timestampComputeAndGraphics = <div class='val'>%u</div></summary></details>\n", limits->timestampComputeAndGraphics );
1844 fprintf(out, "\t\t\t\t\t\t<details><summary>timestampPeriod = <div class='val'>%f</div></summary></details>\n", limits->timestampPeriod );
1845 fprintf(out, "\t\t\t\t\t\t<details><summary>maxClipDistances = <div class='val'>%u</div></summary></details>\n", limits->maxClipDistances );
1846 fprintf(out, "\t\t\t\t\t\t<details><summary>maxCullDistances = <div class='val'>%u</div></summary></details>\n", limits->maxCullDistances );
1847 fprintf(out, "\t\t\t\t\t\t<details><summary>maxCombinedClipAndCullDistances = <div class='val'>%u</div></summary></details>\n", limits->maxCombinedClipAndCullDistances );
1848 fprintf(out, "\t\t\t\t\t\t<details><summary>discreteQueuePriorities = <div class='val'>%u</div></summary></details>\n", limits->discreteQueuePriorities );
1849 fprintf(out, "\t\t\t\t\t\t<details><summary>pointSizeRange[0] = <div class='val'>%f</div></summary></details>\n", limits->pointSizeRange[0] );
1850 fprintf(out, "\t\t\t\t\t\t<details><summary>pointSizeRange[1] = <div class='val'>%f</div></summary></details>\n", limits->pointSizeRange[1] );
1851 fprintf(out, "\t\t\t\t\t\t<details><summary>lineWidthRange[0] = <div class='val'>%f</div></summary></details>\n", limits->lineWidthRange[0] );
1852 fprintf(out, "\t\t\t\t\t\t<details><summary>lineWidthRange[1] = <div class='val'>%f</div></summary></details>\n", limits->lineWidthRange[1] );
1853 fprintf(out, "\t\t\t\t\t\t<details><summary>pointSizeGranularity = <div class='val'>%f</div></summary></details>\n", limits->pointSizeGranularity );
1854 fprintf(out, "\t\t\t\t\t\t<details><summary>lineWidthGranularity = <div class='val'>%f</div></summary></details>\n", limits->lineWidthGranularity );
1855 fprintf(out, "\t\t\t\t\t\t<details><summary>strictLines = <div class='val'>%u</div></summary></details>\n", limits->strictLines );
1856 fprintf(out, "\t\t\t\t\t\t<details><summary>standardSampleLocations = <div class='val'>%u</div></summary></details>\n", limits->standardSampleLocations );
1857 fprintf(out, "\t\t\t\t\t\t<details><summary>optimalBufferCopyOffsetAlignment = <div class='val'>0x%" PRIxLEAST64 "</div></summary></details>\n", limits->optimalBufferCopyOffsetAlignment );
1858 fprintf(out, "\t\t\t\t\t\t<details><summary>optimalBufferCopyRowPitchAlignment = <div class='val'>0x%" PRIxLEAST64 "</div></summary></details>\n", limits->optimalBufferCopyRowPitchAlignment );
1859 fprintf(out, "\t\t\t\t\t\t<details><summary>nonCoherentAtomSize = <div class='val'>0x%" PRIxLEAST64 "</div></summary></details>\n", limits->nonCoherentAtomSize );
1860 fprintf(out, "\t\t\t\t\t</details>\n");
1861 } else {
1862 printf("\tVkPhysicalDeviceLimits:\n");
1863 printf("\t-----------------------\n");
1864 printf("\t\tmaxImageDimension1D = %u\n", limits->maxImageDimension1D );
1865 printf("\t\tmaxImageDimension2D = %u\n", limits->maxImageDimension2D );
1866 printf("\t\tmaxImageDimension3D = %u\n", limits->maxImageDimension3D );
1867 printf("\t\tmaxImageDimensionCube = %u\n", limits->maxImageDimensionCube );
1868 printf("\t\tmaxImageArrayLayers = %u\n", limits->maxImageArrayLayers );
1869 printf("\t\tmaxTexelBufferElements = 0x%" PRIxLEAST32 "\n", limits->maxTexelBufferElements );
1870 printf("\t\tmaxUniformBufferRange = 0x%" PRIxLEAST32 "\n", limits->maxUniformBufferRange );
1871 printf("\t\tmaxStorageBufferRange = 0x%" PRIxLEAST32 "\n", limits->maxStorageBufferRange );
1872 printf("\t\tmaxPushConstantsSize = %u\n", limits->maxPushConstantsSize );
1873 printf("\t\tmaxMemoryAllocationCount = %u\n", limits->maxMemoryAllocationCount );
1874 printf("\t\tmaxSamplerAllocationCount = %u\n", limits->maxSamplerAllocationCount );
1875 printf("\t\tbufferImageGranularity = 0x%" PRIxLEAST64 "\n", limits->bufferImageGranularity );
1876 printf("\t\tsparseAddressSpaceSize = 0x%" PRIxLEAST64 "\n", limits->sparseAddressSpaceSize );
1877 printf("\t\tmaxBoundDescriptorSets = %u\n", limits->maxBoundDescriptorSets );
1878 printf("\t\tmaxPerStageDescriptorSamplers = %u\n", limits->maxPerStageDescriptorSamplers );
1879 printf("\t\tmaxPerStageDescriptorUniformBuffers = %u\n", limits->maxPerStageDescriptorUniformBuffers );
1880 printf("\t\tmaxPerStageDescriptorStorageBuffers = %u\n", limits->maxPerStageDescriptorStorageBuffers );
1881 printf("\t\tmaxPerStageDescriptorSampledImages = %u\n", limits->maxPerStageDescriptorSampledImages );
1882 printf("\t\tmaxPerStageDescriptorStorageImages = %u\n", limits->maxPerStageDescriptorStorageImages );
1883 printf("\t\tmaxPerStageDescriptorInputAttachments = %u\n", limits->maxPerStageDescriptorInputAttachments );
1884 printf("\t\tmaxPerStageResources = %u\n", limits->maxPerStageResources );
1885 printf("\t\tmaxDescriptorSetSamplers = %u\n", limits->maxDescriptorSetSamplers );
1886 printf("\t\tmaxDescriptorSetUniformBuffers = %u\n", limits->maxDescriptorSetUniformBuffers );
1887 printf("\t\tmaxDescriptorSetUniformBuffersDynamic = %u\n", limits->maxDescriptorSetUniformBuffersDynamic );
1888 printf("\t\tmaxDescriptorSetStorageBuffers = %u\n", limits->maxDescriptorSetStorageBuffers );
1889 printf("\t\tmaxDescriptorSetStorageBuffersDynamic = %u\n", limits->maxDescriptorSetStorageBuffersDynamic );
1890 printf("\t\tmaxDescriptorSetSampledImages = %u\n", limits->maxDescriptorSetSampledImages );
1891 printf("\t\tmaxDescriptorSetStorageImages = %u\n", limits->maxDescriptorSetStorageImages );
1892 printf("\t\tmaxDescriptorSetInputAttachments = %u\n", limits->maxDescriptorSetInputAttachments );
1893 printf("\t\tmaxVertexInputAttributes = %u\n", limits->maxVertexInputAttributes );
1894 printf("\t\tmaxVertexInputBindings = %u\n", limits->maxVertexInputBindings );
1895 printf("\t\tmaxVertexInputAttributeOffset = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputAttributeOffset );
1896 printf("\t\tmaxVertexInputBindingStride = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputBindingStride );
1897 printf("\t\tmaxVertexOutputComponents = %u\n", limits->maxVertexOutputComponents );
1898 printf("\t\tmaxTessellationGenerationLevel = %u\n", limits->maxTessellationGenerationLevel );
1899 printf("\t\tmaxTessellationPatchSize = %u\n", limits->maxTessellationPatchSize );
1900 printf("\t\tmaxTessellationControlPerVertexInputComponents = %u\n", limits->maxTessellationControlPerVertexInputComponents );
1901 printf("\t\tmaxTessellationControlPerVertexOutputComponents = %u\n", limits->maxTessellationControlPerVertexOutputComponents);
1902 printf("\t\tmaxTessellationControlPerPatchOutputComponents = %u\n", limits->maxTessellationControlPerPatchOutputComponents );
1903 printf("\t\tmaxTessellationControlTotalOutputComponents = %u\n", limits->maxTessellationControlTotalOutputComponents );
1904 printf("\t\tmaxTessellationEvaluationInputComponents = %u\n", limits->maxTessellationEvaluationInputComponents );
1905 printf("\t\tmaxTessellationEvaluationOutputComponents = %u\n", limits->maxTessellationEvaluationOutputComponents );
1906 printf("\t\tmaxGeometryShaderInvocations = %u\n", limits->maxGeometryShaderInvocations );
1907 printf("\t\tmaxGeometryInputComponents = %u\n", limits->maxGeometryInputComponents );
1908 printf("\t\tmaxGeometryOutputComponents = %u\n", limits->maxGeometryOutputComponents );
1909 printf("\t\tmaxGeometryOutputVertices = %u\n", limits->maxGeometryOutputVertices );
1910 printf("\t\tmaxGeometryTotalOutputComponents = %u\n", limits->maxGeometryTotalOutputComponents );
1911 printf("\t\tmaxFragmentInputComponents = %u\n", limits->maxFragmentInputComponents );
1912 printf("\t\tmaxFragmentOutputAttachments = %u\n", limits->maxFragmentOutputAttachments );
1913 printf("\t\tmaxFragmentDualSrcAttachments = %u\n", limits->maxFragmentDualSrcAttachments );
1914 printf("\t\tmaxFragmentCombinedOutputResources = %u\n", limits->maxFragmentCombinedOutputResources );
1915 printf("\t\tmaxComputeSharedMemorySize = 0x%" PRIxLEAST32 "\n", limits->maxComputeSharedMemorySize );
1916 printf("\t\tmaxComputeWorkGroupCount[0] = %u\n", limits->maxComputeWorkGroupCount[0] );
1917 printf("\t\tmaxComputeWorkGroupCount[1] = %u\n", limits->maxComputeWorkGroupCount[1] );
1918 printf("\t\tmaxComputeWorkGroupCount[2] = %u\n", limits->maxComputeWorkGroupCount[2] );
1919 printf("\t\tmaxComputeWorkGroupInvocations = %u\n", limits->maxComputeWorkGroupInvocations );
1920 printf("\t\tmaxComputeWorkGroupSize[0] = %u\n", limits->maxComputeWorkGroupSize[0] );
1921 printf("\t\tmaxComputeWorkGroupSize[1] = %u\n", limits->maxComputeWorkGroupSize[1] );
1922 printf("\t\tmaxComputeWorkGroupSize[2] = %u\n", limits->maxComputeWorkGroupSize[2] );
1923 printf("\t\tsubPixelPrecisionBits = %u\n", limits->subPixelPrecisionBits );
1924 printf("\t\tsubTexelPrecisionBits = %u\n", limits->subTexelPrecisionBits );
1925 printf("\t\tmipmapPrecisionBits = %u\n", limits->mipmapPrecisionBits );
1926 printf("\t\tmaxDrawIndexedIndexValue = %u\n", limits->maxDrawIndexedIndexValue );
1927 printf("\t\tmaxDrawIndirectCount = %u\n", limits->maxDrawIndirectCount );
1928 printf("\t\tmaxSamplerLodBias = %f\n", limits->maxSamplerLodBias );
1929 printf("\t\tmaxSamplerAnisotropy = %f\n", limits->maxSamplerAnisotropy );
1930 printf("\t\tmaxViewports = %u\n", limits->maxViewports );
1931 printf("\t\tmaxViewportDimensions[0] = %u\n", limits->maxViewportDimensions[0] );
1932 printf("\t\tmaxViewportDimensions[1] = %u\n", limits->maxViewportDimensions[1] );
1933 printf("\t\tviewportBoundsRange[0] =%13f\n", limits->viewportBoundsRange[0] );
1934 printf("\t\tviewportBoundsRange[1] =%13f\n", limits->viewportBoundsRange[1] );
1935 printf("\t\tviewportSubPixelBits = %u\n", limits->viewportSubPixelBits );
1936 printf("\t\tminMemoryMapAlignment = " PRINTF_SIZE_T_SPECIFIER "\n", limits->minMemoryMapAlignment );
1937 printf("\t\tminTexelBufferOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->minTexelBufferOffsetAlignment );
1938 printf("\t\tminUniformBufferOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->minUniformBufferOffsetAlignment );
1939 printf("\t\tminStorageBufferOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->minStorageBufferOffsetAlignment );
1940 printf("\t\tminTexelOffset =%3d\n", limits->minTexelOffset );
1941 printf("\t\tmaxTexelOffset =%3d\n", limits->maxTexelOffset );
1942 printf("\t\tminTexelGatherOffset =%3d\n", limits->minTexelGatherOffset );
1943 printf("\t\tmaxTexelGatherOffset =%3d\n", limits->maxTexelGatherOffset );
1944 printf("\t\tminInterpolationOffset =%9f\n", limits->minInterpolationOffset );
1945 printf("\t\tmaxInterpolationOffset =%9f\n", limits->maxInterpolationOffset );
1946 printf("\t\tsubPixelInterpolationOffsetBits = %u\n", limits->subPixelInterpolationOffsetBits );
1947 printf("\t\tmaxFramebufferWidth = %u\n", limits->maxFramebufferWidth );
1948 printf("\t\tmaxFramebufferHeight = %u\n", limits->maxFramebufferHeight );
1949 printf("\t\tmaxFramebufferLayers = %u\n", limits->maxFramebufferLayers );
1950 printf("\t\tframebufferColorSampleCounts = %u\n", limits->framebufferColorSampleCounts );
1951 printf("\t\tframebufferDepthSampleCounts = %u\n", limits->framebufferDepthSampleCounts );
1952 printf("\t\tframebufferStencilSampleCounts = %u\n", limits->framebufferStencilSampleCounts );
1953 printf("\t\tframebufferNoAttachmentsSampleCounts = %u\n", limits->framebufferNoAttachmentsSampleCounts );
1954 printf("\t\tmaxColorAttachments = %u\n", limits->maxColorAttachments );
1955 printf("\t\tsampledImageColorSampleCounts = %u\n", limits->sampledImageColorSampleCounts );
1956 printf("\t\tsampledImageDepthSampleCounts = %u\n", limits->sampledImageDepthSampleCounts );
1957 printf("\t\tsampledImageStencilSampleCounts = %u\n", limits->sampledImageStencilSampleCounts );
1958 printf("\t\tsampledImageIntegerSampleCounts = %u\n", limits->sampledImageIntegerSampleCounts );
1959 printf("\t\tstorageImageSampleCounts = %u\n", limits->storageImageSampleCounts );
1960 printf("\t\tmaxSampleMaskWords = %u\n", limits->maxSampleMaskWords );
1961 printf("\t\ttimestampComputeAndGraphics = %u\n", limits->timestampComputeAndGraphics );
1962 printf("\t\ttimestampPeriod = %f\n", limits->timestampPeriod );
1963 printf("\t\tmaxClipDistances = %u\n", limits->maxClipDistances );
1964 printf("\t\tmaxCullDistances = %u\n", limits->maxCullDistances );
1965 printf("\t\tmaxCombinedClipAndCullDistances = %u\n", limits->maxCombinedClipAndCullDistances );
1966 printf("\t\tdiscreteQueuePriorities = %u\n", limits->discreteQueuePriorities );
1967 printf("\t\tpointSizeRange[0] = %f\n", limits->pointSizeRange[0] );
1968 printf("\t\tpointSizeRange[1] = %f\n", limits->pointSizeRange[1] );
1969 printf("\t\tlineWidthRange[0] = %f\n", limits->lineWidthRange[0] );
1970 printf("\t\tlineWidthRange[1] = %f\n", limits->lineWidthRange[1] );
1971 printf("\t\tpointSizeGranularity = %f\n", limits->pointSizeGranularity );
1972 printf("\t\tlineWidthGranularity = %f\n", limits->lineWidthGranularity );
1973 printf("\t\tstrictLines = %u\n", limits->strictLines );
1974 printf("\t\tstandardSampleLocations = %u\n", limits->standardSampleLocations );
1975 printf("\t\toptimalBufferCopyOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->optimalBufferCopyOffsetAlignment );
1976 printf("\t\toptimalBufferCopyRowPitchAlignment = 0x%" PRIxLEAST64 "\n", limits->optimalBufferCopyRowPitchAlignment );
1977 printf("\t\tnonCoherentAtomSize = 0x%" PRIxLEAST64 "\n", limits->nonCoherentAtomSize );
1978 }
1979 }
1980
AppGpuDumpProps(const struct AppGpu * gpu,FILE * out)1981 static void AppGpuDumpProps(const struct AppGpu *gpu, FILE *out) {
1982 const VkPhysicalDeviceProperties *props = &gpu->props;
1983 const uint32_t apiVersion=props->apiVersion;
1984 const uint32_t major = VK_VERSION_MAJOR(apiVersion);
1985 const uint32_t minor = VK_VERSION_MINOR(apiVersion);
1986 const uint32_t patch = VK_VERSION_PATCH(apiVersion);
1987
1988 if (html_output) {
1989 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceProperties</summary>\n");
1990 fprintf(out, "\t\t\t\t\t\t<details><summary>apiVersion = <div class='val'>0x%" PRIxLEAST32 "</div> (<div class='val'>%d.%d.%d</div>)</summary></details>\n", apiVersion, major, minor, patch);
1991 fprintf(out, "\t\t\t\t\t\t<details><summary>driverVersion = <div class='val'>%u</div> (<div class='val'>0x%" PRIxLEAST32 "</div>)</summary></details>\n", props->driverVersion, props->driverVersion);
1992 fprintf(out, "\t\t\t\t\t\t<details><summary>vendorID = <div class='val'>0x%04x</div></summary></details>\n", props->vendorID);
1993 fprintf(out, "\t\t\t\t\t\t<details><summary>deviceID = <div class='val'>0x%04x</div></summary></details>\n", props->deviceID);
1994 fprintf(out, "\t\t\t\t\t\t<details><summary>deviceType = %s</summary></details>\n", VkPhysicalDeviceTypeString(props->deviceType));
1995 fprintf(out, "\t\t\t\t\t\t<details><summary>deviceName = %s</summary></details>\n", props->deviceName);
1996 } else {
1997 printf("VkPhysicalDeviceProperties:\n");
1998 printf("===========================\n");
1999 printf("\tapiVersion = 0x%" PRIxLEAST32 " (%d.%d.%d)\n", apiVersion, major, minor, patch);
2000 printf("\tdriverVersion = %u (0x%" PRIxLEAST32 ")\n", props->driverVersion, props->driverVersion);
2001 printf("\tvendorID = 0x%04x\n", props->vendorID);
2002 printf("\tdeviceID = 0x%04x\n", props->deviceID);
2003 printf("\tdeviceType = %s\n", VkPhysicalDeviceTypeString(props->deviceType));
2004 printf("\tdeviceName = %s\n", props->deviceName);
2005 }
2006 if (html_output) fprintf(out, "\t\t\t\t\t</details>\n");
2007
2008 AppDumpLimits(&gpu->props.limits, out);
2009 AppDumpSparseProps(&gpu->props.sparseProperties, out);
2010
2011 fflush(out);
2012 }
2013
AppDumpExtensions(const char * indent,const char * layer_name,const uint32_t extension_count,const VkExtensionProperties * extension_properties,FILE * out)2014 static void AppDumpExtensions(const char *indent, const char *layer_name, const uint32_t extension_count,
2015 const VkExtensionProperties *extension_properties, FILE *out) {
2016 uint32_t i;
2017
2018 if (html_output) fprintf(out, "\t\t\t%s<details><summary>", indent);
2019 if (layer_name && (strlen(layer_name) > 0)) {
2020 if (html_output) {
2021 fprintf(out, "%s Extensions", layer_name);
2022 } else {
2023 printf("%s%s Extensions", indent, layer_name);
2024 }
2025 } else {
2026 fprintf(out, "%sExtensions", indent);
2027 }
2028 if (html_output) {
2029 fprintf(out, "\tcount = <div class='val'>%d</div></summary>", extension_count);
2030 if (extension_count > 0) fprintf(out, "\n");
2031 } else {
2032 printf("\tcount = %d\n", extension_count);
2033 }
2034
2035 for (i = 0; i < extension_count; i++) {
2036 VkExtensionProperties const *ext_prop = &extension_properties[i];
2037
2038 if (html_output) {
2039 fprintf(out, "\t\t\t\t%s<details><summary>", indent);
2040 fprintf(out, "<div class='type'>%s</div>: extension revision <div class='val'>%d</div>", ext_prop->extensionName,
2041 ext_prop->specVersion);
2042 fprintf(out, "</summary></details>\n");
2043 } else {
2044 printf("%s\t", indent);
2045 printf("%-36s: extension revision %2d\n", ext_prop->extensionName, ext_prop->specVersion);
2046 }
2047 }
2048 if (html_output) {
2049 if (extension_count > 0) {
2050 fprintf(out, "\t\t\t%s</details>\n", indent);
2051 } else {
2052 fprintf(out, "</details>\n");
2053 }
2054 }
2055
2056 fflush(out);
2057 }
2058
AppGpuDumpQueueProps(const struct AppGpu * gpu,uint32_t id,FILE * out)2059 static void AppGpuDumpQueueProps(const struct AppGpu *gpu, uint32_t id, FILE *out) {
2060 const VkQueueFamilyProperties *props = &gpu->queue_props[id];
2061
2062 if (html_output) {
2063 fprintf(out, "\t\t\t\t\t<details><summary>VkQueueFamilyProperties[<div class='val'>%d</div>]</summary>\n", id);
2064 fprintf(out, "\t\t\t\t\t\t<details><summary>queueFlags = ");
2065 } else {
2066 printf("VkQueueFamilyProperties[%d]:\n", id);
2067 printf("===========================\n");
2068 printf("\tqueueFlags = ");
2069 }
2070
2071 char *sep = ""; // separator character
2072 if (props->queueFlags & VK_QUEUE_GRAPHICS_BIT) {
2073 fprintf(out, "GRAPHICS");
2074 sep = " | ";
2075 }
2076 if (props->queueFlags & VK_QUEUE_COMPUTE_BIT) {
2077 fprintf(out, "%sCOMPUTE", sep);
2078 sep = " | ";
2079 }
2080 if (props->queueFlags & VK_QUEUE_TRANSFER_BIT) {
2081 fprintf(out, "%sTRANSFER", sep);
2082 sep = " | ";
2083 }
2084 if (props->queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) {
2085 fprintf(out, "%sSPARSE", sep);
2086 }
2087 if (html_output) {
2088 fprintf(out, "</summary></details>\n");
2089 fprintf(out, "\t\t\t\t\t\t<details><summary>queueCount = <div class='val'>%u</div></summary></details>\n", props->queueCount);
2090 fprintf(out, "\t\t\t\t\t\t<details><summary>timestampValidBits = <div class='val'>%u</div></summary></details>\n", props->timestampValidBits);
2091 fprintf(out, "\t\t\t\t\t\t<details><summary>minImageTransferGranularity = (<div class='val'>%d</div>, <div class='val'>%d</div>, <div class='val'>%d</div>)</summary></details>\n", props->minImageTransferGranularity.width,
2092 props->minImageTransferGranularity.height, props->minImageTransferGranularity.depth);
2093 fprintf(out, "\t\t\t\t\t</details>\n");
2094 } else {
2095 printf("\n");
2096 printf("\tqueueCount = %u\n", props->queueCount);
2097 printf("\ttimestampValidBits = %u\n", props->timestampValidBits);
2098 printf("\tminImageTransferGranularity = (%d, %d, %d)\n", props->minImageTransferGranularity.width,
2099 props->minImageTransferGranularity.height, props->minImageTransferGranularity.depth);
2100 }
2101
2102 fflush(out);
2103 }
2104
2105 // This prints a number of bytes in a human-readable format according to prefixes of the International System of Quantities (ISQ),
2106 // defined in ISO/IEC 80000. The prefixes used here are not SI prefixes, but rather the binary prefixes based on powers of 1024
2107 // (kibi-, mebi-, gibi- etc.).
2108 #define kBufferSize 32
2109
HumanReadable(const size_t sz)2110 static char *HumanReadable(const size_t sz) {
2111 const char prefixes[] = "KMGTPEZY";
2112 char buf[kBufferSize];
2113 int which = -1;
2114 double result = (double)sz;
2115 while (result > 1024 && which < 7) {
2116 result /= 1024;
2117 ++which;
2118 }
2119
2120 char unit[] = "\0i";
2121 if (which >= 0) {
2122 unit[0] = prefixes[which];
2123 }
2124 snprintf(buf, kBufferSize, "%.2f %sB", result, unit);
2125 return strndup(buf, kBufferSize);
2126 }
2127
AppGpuDumpMemoryProps(const struct AppGpu * gpu,FILE * out)2128 static void AppGpuDumpMemoryProps(const struct AppGpu *gpu, FILE *out) {
2129 const VkPhysicalDeviceMemoryProperties *props = &gpu->memory_props;
2130
2131 if (html_output) {
2132 fprintf(out, "\t\t\t\t\t<details><summary>VkPhysicalDeviceMemoryProperties</summary>\n");
2133 fprintf(out, "\t\t\t\t\t\t<details><summary>memoryTypeCount = <div class='val'>%u</div></summary>", props->memoryTypeCount);
2134 if (props->memoryTypeCount > 0) {
2135 fprintf(out, "\n");
2136 } else {
2137 fprintf(out, "</details>\n");
2138 }
2139 } else {
2140 printf("VkPhysicalDeviceMemoryProperties:\n");
2141 printf("=================================\n");
2142 printf("\tmemoryTypeCount = %u\n", props->memoryTypeCount);
2143 }
2144 for (uint32_t i = 0; i < props->memoryTypeCount; i++) {
2145 if (html_output) {
2146 fprintf(out, "\t\t\t\t\t\t\t<details><summary>memoryTypes[<div class='val'>%u</div>]</summary>\n", i);
2147 fprintf(out, "\t\t\t\t\t\t\t\t<details><summary>heapIndex = <div class='val'>%u</div></summary></summary></details>\n", props->memoryTypes[i].heapIndex);
2148 fprintf(out, "\t\t\t\t\t\t\t\t<details open><summary>propertyFlags = <div class='val'>0x%" PRIxLEAST32 "</div></summary>", props->memoryTypes[i].propertyFlags);
2149 if (props->memoryTypes[i].propertyFlags == 0) {
2150 fprintf(out, "</details>\n");
2151 } else {
2152 fprintf(out, "\n");
2153 }
2154 } else {
2155 printf("\tmemoryTypes[%u] :\n", i);
2156 printf("\t\theapIndex = %u\n", props->memoryTypes[i].heapIndex);
2157 printf("\t\tpropertyFlags = 0x%" PRIxLEAST32 ":\n", props->memoryTypes[i].propertyFlags);
2158 }
2159
2160 // Print each named flag, if it is set
2161 VkFlags flags = props->memoryTypes[i].propertyFlags;
2162 if (html_output) {
2163 if (flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) { fprintf(out, "\t\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT</div></summary></details>\n"); }
2164 if (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { fprintf(out, "\t\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT</div></summary></details>\n"); }
2165 if (flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) { fprintf(out, "\t\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_MEMORY_PROPERTY_HOST_COHERENT_BIT</div></summary></details>\n"); }
2166 if (flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) { fprintf(out, "\t\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_MEMORY_PROPERTY_HOST_CACHED_BIT</div></summary></details>\n"); }
2167 if (flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) { fprintf(out, "\t\t\t\t\t\t\t\t\t<details><summary><div class='type'>VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT</div></summary></details>\n"); }
2168 if (props->memoryTypes[i].propertyFlags > 0) fprintf(out, "\t\t\t\t\t\t\t\t</details>\n");
2169 fprintf(out, "\t\t\t\t\t\t\t</details>\n");
2170 } else {
2171 if (flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) { printf("\t\t\tVK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT\n"); }
2172 if (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { printf("\t\t\tVK_MEMORY_PROPERTY_HOST_VISIBLE_BIT\n"); }
2173 if (flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) { printf("\t\t\tVK_MEMORY_PROPERTY_HOST_COHERENT_BIT\n"); }
2174 if (flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) { printf("\t\t\tVK_MEMORY_PROPERTY_HOST_CACHED_BIT\n"); }
2175 if (flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) { printf("\t\t\tVK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT\n"); }
2176 }
2177 }
2178
2179 if (html_output && props->memoryTypeCount > 0) {
2180 fprintf(out, "\t\t\t\t\t\t</details>\n");
2181 }
2182
2183 if (html_output) {
2184 fprintf(out, "\t\t\t\t\t\t<details><summary>memoryHeapCount = <div class='val'>%u</div></summary>", props->memoryHeapCount);
2185 if (props->memoryTypeCount > 0) fprintf(out, "\n");
2186 } else {
2187 printf("\tmemoryHeapCount = %u\n", props->memoryHeapCount);
2188 }
2189 for (uint32_t i = 0; i < props->memoryHeapCount; i++) {
2190 const VkDeviceSize memSize = props->memoryHeaps[i].size;
2191 char *mem_size_human_readable = HumanReadable((const size_t)memSize);
2192
2193 if (html_output) {
2194 fprintf(out, "\t\t\t\t\t\t\t<details><summary>memoryHeaps[<div class='val'>%u</div>]</summary>\n", i);
2195 fprintf(out, "\t\t\t\t\t\t\t\t<details><summary>size = <div class='val'>" PRINTF_SIZE_T_SPECIFIER "</div> (<div class='val'>0x%" PRIxLEAST64 "</div>) (<div class='val'>%s</div>)</summary></details>\n",
2196 (size_t)memSize, memSize, mem_size_human_readable);
2197 } else {
2198 printf("\tmemoryHeaps[%u] :\n", i);
2199 printf("\t\tsize = " PRINTF_SIZE_T_SPECIFIER " (0x%" PRIxLEAST64 ") (%s)\n", (size_t)memSize, memSize,
2200 mem_size_human_readable);
2201 }
2202 free(mem_size_human_readable);
2203
2204 VkMemoryHeapFlags heap_flags = props->memoryHeaps[i].flags;
2205 if (html_output) {
2206 fprintf(out, "\t\t\t\t\t\t\t\t<details open><summary>flags</summary>\n");
2207 fprintf(out, "\t\t\t\t\t\t\t\t\t<details><summary>");
2208 fprintf(out, (heap_flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) ? "<div class='type'>VK_MEMORY_HEAP_DEVICE_LOCAL_BIT</div>" : "None");
2209 fprintf(out, "</summary></details>\n");
2210 fprintf(out, "\t\t\t\t\t\t\t\t</details>\n");
2211 fprintf(out, "\t\t\t\t\t\t\t</details>\n");
2212 } else {
2213 printf("\t\tflags:\n\t\t\t");
2214 printf((heap_flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) ? "VK_MEMORY_HEAP_DEVICE_LOCAL_BIT\n" : "None\n");
2215 }
2216 }
2217
2218 if (html_output) {
2219 fprintf(out, "\t\t\t\t\t\t</details>\n");
2220 fprintf(out, "\t\t\t\t\t</details>\n");
2221 }
2222
2223 fflush(out);
2224 }
2225 // clang-format on
2226
AppGpuDump(const struct AppGpu * gpu,FILE * out)2227 static void AppGpuDump(const struct AppGpu *gpu, FILE *out) {
2228 uint32_t i;
2229
2230 if (html_output) {
2231 fprintf(out, "\t\t\t<details><summary>Device Properties and Extensions</summary>\n");
2232 fprintf(out, "\t\t\t\t<details><summary>GPU%u</summary>\n", gpu->id);
2233 } else {
2234 printf("\nDevice Properties and Extensions :\n");
2235 printf("==================================\n");
2236 printf("GPU%u\n", gpu->id);
2237 }
2238
2239 AppGpuDumpProps(gpu, out);
2240 if (html_output) {
2241 AppDumpExtensions("\t\t", "Device", gpu->device_extension_count, gpu->device_extensions, out);
2242 } else {
2243 printf("\n");
2244 AppDumpExtensions("", "Device", gpu->device_extension_count, gpu->device_extensions, out);
2245 printf("\n");
2246 }
2247
2248 for (i = 0; i < gpu->queue_count; i++) {
2249 AppGpuDumpQueueProps(gpu, i, out);
2250 if (!html_output) printf("\n");
2251 }
2252 AppGpuDumpMemoryProps(gpu, out);
2253 if (!html_output) printf("\n");
2254 AppGpuDumpFeatures(gpu, out);
2255 if (!html_output) printf("\n");
2256 AppDevDump(&gpu->dev, out);
2257 if (html_output) {
2258 fprintf(out, "\t\t\t\t</details>\n");
2259 fprintf(out, "\t\t\t</details>\n");
2260 }
2261 }
2262
2263 #ifdef _WIN32
2264 // Enlarges the console window to have a large scrollback size.
ConsoleEnlarge()2265 static void ConsoleEnlarge() {
2266 HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
2267
2268 // make the console window bigger
2269 CONSOLE_SCREEN_BUFFER_INFO csbi;
2270 COORD buffer_size;
2271 if (GetConsoleScreenBufferInfo(console_handle, &csbi)) {
2272 buffer_size.X = csbi.dwSize.X + 30;
2273 buffer_size.Y = 20000;
2274 SetConsoleScreenBufferSize(console_handle, buffer_size);
2275 }
2276
2277 SMALL_RECT r;
2278 r.Left = r.Top = 0;
2279 r.Right = csbi.dwSize.X - 1 + 30;
2280 r.Bottom = 50;
2281 SetConsoleWindowInfo(console_handle, true, &r);
2282
2283 // change the console window title
2284 SetConsoleTitle(TEXT(APP_SHORT_NAME));
2285 }
2286 #endif
2287
main(int argc,char ** argv)2288 int main(int argc, char **argv) {
2289 uint32_t vulkan_major, vulkan_minor, vulkan_patch;
2290 struct AppGpu *gpus;
2291 VkPhysicalDevice *objs;
2292 uint32_t gpu_count;
2293 VkResult err;
2294 struct AppInstance inst;
2295 FILE *out = stdout;
2296
2297 #ifdef _WIN32
2298 if (ConsoleIsExclusive()) ConsoleEnlarge();
2299 #endif
2300
2301 vulkan_major = VK_VERSION_MAJOR(VK_API_VERSION_1_0);
2302 vulkan_minor = VK_VERSION_MINOR(VK_API_VERSION_1_0);
2303 vulkan_patch = VK_VERSION_PATCH(VK_HEADER_VERSION);
2304 for (int i = 1; i < argc; i++) {
2305 if (strcmp(argv[i], "--html") == 0) {
2306 out = fopen("vulkaninfo.html", "w");
2307 html_output = true;
2308 continue;
2309 }
2310 }
2311
2312 if (html_output) {
2313 PrintHtmlHeader(out);
2314 fprintf(out, "\t\t\t<details><summary>");
2315 } else {
2316 printf("===========\n");
2317 printf("VULKAN INFO\n");
2318 printf("===========\n\n");
2319 }
2320 fprintf(out, "Vulkan API Version: ");
2321 if (html_output) {
2322 fprintf(out, "<div class='val'>%d.%d.%d</div></summary></details>\n", vulkan_major, vulkan_minor, vulkan_patch);
2323 fprintf(out, "\t\t\t<br />\n");
2324 } else {
2325 printf("%d.%d.%d\n\n", vulkan_major, vulkan_minor, vulkan_patch);
2326 }
2327
2328 AppCreateInstance(&inst);
2329
2330 if (!html_output) {
2331 printf("Instance Extensions:\n");
2332 printf("====================\n");
2333 }
2334 AppDumpExtensions("", "Instance", inst.global_extension_count, inst.global_extensions, out);
2335
2336 err = vkEnumeratePhysicalDevices(inst.instance, &gpu_count, NULL);
2337 if (err) ERR_EXIT(err);
2338 objs = malloc(sizeof(objs[0]) * gpu_count);
2339 if (!objs) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
2340 err = vkEnumeratePhysicalDevices(inst.instance, &gpu_count, objs);
2341 if (err) ERR_EXIT(err);
2342
2343 gpus = malloc(sizeof(gpus[0]) * gpu_count);
2344 if (!gpus) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
2345 for (uint32_t i = 0; i < gpu_count; i++) {
2346 AppGpuInit(&gpus[i], &inst, i, objs[i]);
2347 if (!html_output) printf("\n\n");
2348 }
2349
2350 //---Layer-Device-Extensions---
2351 if (html_output) {
2352 fprintf(out, "\t\t\t<details><summary>Layers: count = <div class='val'>%d</div></summary>", inst.global_layer_count);
2353 if (inst.global_layer_count > 0) {
2354 fprintf(out, "\n");
2355 }
2356 } else {
2357 printf("Layers: count = %d\n", inst.global_layer_count);
2358 printf("=======\n");
2359 }
2360
2361 for (uint32_t i = 0; i < inst.global_layer_count; i++) {
2362 uint32_t layer_major, layer_minor, layer_patch;
2363 char spec_version[64], layer_version[64];
2364 VkLayerProperties const *layer_prop = &inst.global_layers[i].layer_properties;
2365
2366 ExtractVersion(layer_prop->specVersion, &layer_major, &layer_minor, &layer_patch);
2367 snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", layer_major, layer_minor, layer_patch);
2368 snprintf(layer_version, sizeof(layer_version), "%d", layer_prop->implementationVersion);
2369
2370 if (html_output) {
2371 fprintf(out, "\t\t\t\t<details><summary>");
2372 fprintf(out, "<div class='type'>%s</div> (%s) Vulkan version <div class='val'>%s</div>, ", layer_prop->layerName,
2373 (char *)layer_prop->description, spec_version);
2374 fprintf(out, "layer version <div class='val'>%s</div></summary>\n", layer_version);
2375 AppDumpExtensions("\t\t", "Layer", inst.global_layers[i].extension_count, inst.global_layers[i].extension_properties,
2376 out);
2377 } else {
2378 printf("%s (%s) Vulkan version %s, layer version %s\n", layer_prop->layerName, (char *) layer_prop->description,
2379 spec_version, layer_version);
2380 AppDumpExtensions("\t", "Layer", inst.global_layers[i].extension_count, inst.global_layers[i].extension_properties,
2381 out);
2382 }
2383
2384 char *layer_name = inst.global_layers[i].layer_properties.layerName;
2385
2386 if (html_output) {
2387 fprintf(out, "\t\t\t\t\t<details><summary>Devices count = <div class='val'>%d</div></summary>\n", gpu_count);
2388 } else {
2389 printf("\tDevices \tcount = %d\n", gpu_count);
2390 }
2391 for (uint32_t j = 0; j < gpu_count; j++) {
2392 if (html_output) {
2393 fprintf(out, "\t\t\t\t\t\t<details><summary>");
2394 fprintf(out, "GPU id: <div class='val'>%u</div> (%s)</summary></details>\n", j, gpus[j].props.deviceName);
2395 } else {
2396 printf("\t\tGPU id : %u (%s)\n", j, gpus[j].props.deviceName);
2397 }
2398 uint32_t count = 0;
2399 VkExtensionProperties *props;
2400 AppGetPhysicalDeviceLayerExtensions(&gpus[j], layer_name, &count, &props);
2401 if (html_output) {
2402 AppDumpExtensions("\t\t\t", "Layer-Device", count, props, out);
2403 } else {
2404 AppDumpExtensions("\t\t", "Layer-Device", count, props, out);
2405 }
2406 if (html_output) { fprintf(out, "\t\t\t\t\t</details>\n"); }
2407 free(props);
2408 }
2409 if (html_output) {
2410 fprintf(out, "\t\t\t\t</details>\n");
2411 } else {
2412 printf("\n");
2413 }
2414 }
2415
2416 if (html_output) { fprintf(out, "\t\t\t</details>\n"); }
2417
2418 fflush(out);
2419 //-----------------------------
2420
2421 if (html_output) {
2422 fprintf(out, "\t\t\t<details><summary>Presentable Surfaces</summary>");
2423 if (gpu_count > 0) {
2424 fprintf(out, "\n");
2425 } else {
2426 fprintf(out, "</details>\n");
2427 }
2428 } else {
2429 printf("Presentable Surfaces:\n");
2430 printf("=====================\n");
2431 }
2432 inst.width = 256;
2433 inst.height = 256;
2434 int format_count = 0;
2435 int present_mode_count = 0;
2436
2437 #if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR)
2438 bool has_display = true;
2439 const char *display_var = getenv("DISPLAY");
2440 if (display_var == NULL || strlen(display_var) == 0) {
2441 printf("'DISPLAY' environment variable not set... skipping surface info\n");
2442 has_display = false;
2443 }
2444 #endif
2445
2446 //--WIN32--
2447 #ifdef VK_USE_PLATFORM_WIN32_KHR
2448 if (CheckExtensionEnabled(VK_KHR_WIN32_SURFACE_EXTENSION_NAME, inst.inst_extensions, inst.inst_extensions_count)) {
2449 AppCreateWin32Window(&inst);
2450 for (uint32_t i = 0; i < gpu_count; i++) {
2451 AppCreateWin32Surface(&inst);
2452 if (html_output) {
2453 fprintf(out, "\t\t\t\t<details><summary>GPU id : <div class='val'>%u</div> (%s)</summary></details>\n", i,
2454 gpus[i].props.deviceName);
2455 fprintf(out, "\t\t\t\t<details><summary>Surface type : <div class='type'>%s</div></summary></details>\n",
2456 VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
2457 } else {
2458 printf("GPU id : %u (%s)\n", i, gpus[i].props.deviceName);
2459 printf("Surface type : %s\n", VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
2460 }
2461 format_count += AppDumpSurfaceFormats(&inst, &gpus[i], out);
2462 present_mode_count += AppDumpSurfacePresentModes(&inst, &gpus[i], out);
2463 AppDumpSurfaceCapabilities(&inst, &gpus[i], out);
2464 AppDestroySurface(&inst);
2465 }
2466 AppDestroyWin32Window(&inst);
2467 }
2468 //--XCB--
2469 #elif VK_USE_PLATFORM_XCB_KHR
2470 if (has_display && CheckExtensionEnabled(VK_KHR_XCB_SURFACE_EXTENSION_NAME, inst.inst_extensions, inst.inst_extensions_count)) {
2471 AppCreateXcbWindow(&inst);
2472 for (uint32_t i = 0; i < gpu_count; i++) {
2473 AppCreateXcbSurface(&inst);
2474 if (html_output) {
2475 fprintf(out, "\t\t\t\t<details><summary>GPU id : <div class='val'>%u</div> (%s)</summary></details>\n", i,
2476 gpus[i].props.deviceName);
2477 fprintf(out, "\t\t\t\t<details><summary>Surface type : <div class='type'>%s</div></summary></details>\n",
2478 VK_KHR_XCB_SURFACE_EXTENSION_NAME);
2479 } else {
2480 printf("GPU id : %u (%s)\n", i, gpus[i].props.deviceName);
2481 printf("Surface type : %s\n", VK_KHR_XCB_SURFACE_EXTENSION_NAME);
2482 }
2483 format_count += AppDumpSurfaceFormats(&inst, &gpus[i], out);
2484 present_mode_count += AppDumpSurfacePresentModes(&inst, &gpus[i], out);
2485 AppDumpSurfaceCapabilities(&inst, &gpus[i], out);
2486 AppDestroySurface(&inst);
2487 }
2488 AppDestroyXcbWindow(&inst);
2489 }
2490 //--XLIB--
2491 #elif VK_USE_PLATFORM_XLIB_KHR
2492 if (has_display && CheckExtensionEnabled(VK_KHR_XLIB_SURFACE_EXTENSION_NAME, inst.inst_extensions, inst.inst_extensions_count)) {
2493 AppCreateXlibWindow(&inst);
2494 for (uint32_t i = 0; i < gpu_count; i++) {
2495 AppCreateXlibSurface(&inst);
2496 if (html_output) {
2497 fprintf(out, "\t\t\t\t<details><summary>GPU id : <div class='val'>%u</div> (%s)</summary></details>\n", i,
2498 gpus[i].props.deviceName);
2499 fprintf(out, "\t\t\t\t<details><summary>Surface type : <div class='type'>%s</div></summary></details>\n",
2500 VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
2501 } else {
2502 printf("GPU id : %u (%s)\n", i, gpus[i].props.deviceName);
2503 printf("Surface type : %s\n", VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
2504 }
2505 format_count += AppDumpSurfaceFormats(&inst, &gpus[i], out);
2506 present_mode_count += AppDumpSurfacePresentModes(&inst, &gpus[i], out);
2507 AppDumpSurfaceCapabilities(&inst, &gpus[i], out);
2508 AppDestroySurface(&inst);
2509 }
2510 AppDestroyXlibWindow(&inst);
2511 }
2512 #endif
2513
2514 // TODO: Android / Wayland / MIR
2515 if (!format_count && !present_mode_count) {
2516 if (html_output) {
2517 fprintf(out, "\t\t\t\t<details><summary>None found</summary></details>\n");
2518 } else {
2519 printf( "None found\n");
2520 }
2521 }
2522
2523 if (html_output) {
2524 fprintf(out, "\t\t\t</details>\n");
2525 } else {
2526 printf("\n");
2527 }
2528 //---------
2529
2530 for (uint32_t i = 0; i < gpu_count; i++) {
2531 AppGpuDump(&gpus[i], out);
2532 printf("\n\n");
2533 }
2534
2535 for (uint32_t i = 0; i < gpu_count; i++) AppGpuDestroy(&gpus[i]);
2536 free(gpus);
2537 free(objs);
2538
2539 AppDestroyInstance(&inst);
2540
2541 fflush(out);
2542 #ifdef _WIN32
2543 if (ConsoleIsExclusive() && !html_output) Sleep(INFINITE);
2544 #endif
2545
2546 if (html_output) {
2547 PrintHtmlFooter(out);
2548 fclose(out);
2549 }
2550
2551 return 0;
2552 }
2553