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 (at) LunarG.com> 19 * Author: David Pinedo <david (at) lunarg.com> 20 * Author: Mark Lobodzinski <mark (at) lunarg.com> 21 * Author: Rene Lindsay <rene (at) lunarg.com> 22 * Author: Jeremy Kniager <jeremyk (at) lunarg.com> 23 * Author: Shannon McPherson <shannon (at) 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. 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 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 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 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 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) 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 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 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 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 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 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 560 static void AppDevDestroy(struct AppDev *dev) { 561 vkDeviceWaitIdle(dev->obj); 562 vkDestroyDevice(dev->obj, NULL); 563 } 564 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 */ 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 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 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, ...) { 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 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 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 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: 951 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 952 return (DefWindowProc(hWnd, uMsg, wParam, lParam)); 953 } 954 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 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 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) 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 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 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 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 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 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 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) 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 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 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 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 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 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 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 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 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 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 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 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 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 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. 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 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