vulkaninfo.c revision c04519cd6e39256351df868dc721259d904f4542
1/* 2 * Vulkan 3 * 4 * Copyright (C) 2014 LunarG, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24#include <stdlib.h> 25#include <stdio.h> 26#include <stdbool.h> 27#include <string.h> 28#include <assert.h> 29#include <inttypes.h> 30 31#ifdef _WIN32 32#include <Windows.h> 33#include <fcntl.h> 34#include <io.h> 35#endif 36 37#include "vk_ext_khr_swapchain.h" 38#include "vk_ext_khr_device_swapchain.h" 39 40#include <vulkan.h> 41 42#define ERR(err) printf("%s:%d: failed with %s\n", \ 43 __FILE__, __LINE__, vk_result_string(err)); 44 45#ifdef _WIN32 46 47#define snprintf _snprintf 48 49bool consoleCreated = false; 50 51#define WAIT_FOR_CONSOLE_DESTROY \ 52 do { \ 53 if (consoleCreated) \ 54 Sleep(INFINITE); \ 55 } while (0) 56#else 57 #define WAIT_FOR_CONSOLE_DESTROY 58#endif 59 60 61#define ERR_EXIT(err) \ 62 do { \ 63 ERR(err); \ 64 fflush(stdout); \ 65 WAIT_FOR_CONSOLE_DESTROY; \ 66 exit(-1); \ 67 } while (0) 68 69#if defined(NDEBUG) && defined(__GNUC__) 70#define U_ASSERT_ONLY __attribute__((unused)) 71#else 72#define U_ASSERT_ONLY 73#endif 74 75#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 76 77#define MAX_GPUS 8 78 79#define MAX_QUEUE_TYPES 5 80#define APP_SHORT_NAME "vulkaninfo" 81 82struct app_gpu; 83 84struct app_dev { 85 struct app_gpu *gpu; /* point back to the GPU */ 86 87 VkDevice obj; 88 89 90 VkFormatProperties format_props[VK_FORMAT_RANGE_SIZE]; 91}; 92 93struct layer_extension_list { 94 VkLayerProperties layer_properties; 95 uint32_t extension_count; 96 VkExtensionProperties *extension_properties; 97}; 98 99struct app_instance { 100 VkInstance instance; 101 uint32_t global_layer_count; 102 struct layer_extension_list *global_layers; 103 uint32_t global_extension_count; 104 VkExtensionProperties *global_extensions; 105}; 106 107struct app_gpu { 108 uint32_t id; 109 VkPhysicalDevice obj; 110 111 VkPhysicalDeviceProperties props; 112 113 uint32_t queue_count; 114 VkQueueFamilyProperties *queue_props; 115 VkDeviceQueueCreateInfo *queue_reqs; 116 117 VkPhysicalDeviceMemoryProperties memory_props; 118 VkPhysicalDeviceFeatures features; 119 VkPhysicalDevice limits; 120 121 uint32_t device_layer_count; 122 struct layer_extension_list *device_layers; 123 124 uint32_t device_extension_count; 125 VkExtensionProperties *device_extensions; 126 127 struct app_dev dev; 128}; 129 130static const char *vk_result_string(VkResult err) 131{ 132 switch (err) { 133#define STR(r) case r: return #r 134 STR(VK_SUCCESS); 135 STR(VK_NOT_READY); 136 STR(VK_TIMEOUT); 137 STR(VK_EVENT_SET); 138 STR(VK_EVENT_RESET); 139 STR(VK_ERROR_INITIALIZATION_FAILED); 140 STR(VK_ERROR_OUT_OF_HOST_MEMORY); 141 STR(VK_ERROR_OUT_OF_DEVICE_MEMORY); 142 STR(VK_ERROR_DEVICE_LOST); 143 STR(VK_ERROR_LAYER_NOT_PRESENT); 144 STR(VK_ERROR_EXTENSION_NOT_PRESENT); 145 STR(VK_ERROR_MEMORY_MAP_FAILED); 146 STR(VK_ERROR_INCOMPATIBLE_DRIVER); 147#undef STR 148 default: return "UNKNOWN_RESULT"; 149 } 150} 151 152static const char *vk_physical_device_type_string(VkPhysicalDeviceType type) 153{ 154 switch (type) { 155#define STR(r) case VK_PHYSICAL_DEVICE_TYPE_ ##r: return #r 156 STR(OTHER); 157 STR(INTEGRATED_GPU); 158 STR(DISCRETE_GPU); 159 STR(VIRTUAL_GPU); 160#undef STR 161 default: return "UNKNOWN_DEVICE"; 162 } 163} 164 165static const char *vk_format_string(VkFormat fmt) 166{ 167 switch (fmt) { 168#define STR(r) case VK_FORMAT_ ##r: return #r 169 STR(UNDEFINED); 170 STR(R4G4_UNORM); 171 STR(R4G4_USCALED); 172 STR(R4G4B4A4_UNORM); 173 STR(R4G4B4A4_USCALED); 174 STR(R5G6B5_UNORM); 175 STR(R5G6B5_USCALED); 176 STR(R5G5B5A1_UNORM); 177 STR(R5G5B5A1_USCALED); 178 STR(R8_UNORM); 179 STR(R8_SNORM); 180 STR(R8_USCALED); 181 STR(R8_SSCALED); 182 STR(R8_UINT); 183 STR(R8_SINT); 184 STR(R8_SRGB); 185 STR(R8G8_UNORM); 186 STR(R8G8_SNORM); 187 STR(R8G8_USCALED); 188 STR(R8G8_SSCALED); 189 STR(R8G8_UINT); 190 STR(R8G8_SINT); 191 STR(R8G8_SRGB); 192 STR(R8G8B8_UNORM); 193 STR(R8G8B8_SNORM); 194 STR(R8G8B8_USCALED); 195 STR(R8G8B8_SSCALED); 196 STR(R8G8B8_UINT); 197 STR(R8G8B8_SINT); 198 STR(R8G8B8_SRGB); 199 STR(R8G8B8A8_UNORM); 200 STR(R8G8B8A8_SNORM); 201 STR(R8G8B8A8_USCALED); 202 STR(R8G8B8A8_SSCALED); 203 STR(R8G8B8A8_UINT); 204 STR(R8G8B8A8_SINT); 205 STR(R8G8B8A8_SRGB); 206 STR(R10G10B10A2_UNORM); 207 STR(R10G10B10A2_SNORM); 208 STR(R10G10B10A2_USCALED); 209 STR(R10G10B10A2_SSCALED); 210 STR(R10G10B10A2_UINT); 211 STR(R10G10B10A2_SINT); 212 STR(R16_UNORM); 213 STR(R16_SNORM); 214 STR(R16_USCALED); 215 STR(R16_SSCALED); 216 STR(R16_UINT); 217 STR(R16_SINT); 218 STR(R16_SFLOAT); 219 STR(R16G16_UNORM); 220 STR(R16G16_SNORM); 221 STR(R16G16_USCALED); 222 STR(R16G16_SSCALED); 223 STR(R16G16_UINT); 224 STR(R16G16_SINT); 225 STR(R16G16_SFLOAT); 226 STR(R16G16B16_UNORM); 227 STR(R16G16B16_SNORM); 228 STR(R16G16B16_USCALED); 229 STR(R16G16B16_SSCALED); 230 STR(R16G16B16_UINT); 231 STR(R16G16B16_SINT); 232 STR(R16G16B16_SFLOAT); 233 STR(R16G16B16A16_UNORM); 234 STR(R16G16B16A16_SNORM); 235 STR(R16G16B16A16_USCALED); 236 STR(R16G16B16A16_SSCALED); 237 STR(R16G16B16A16_UINT); 238 STR(R16G16B16A16_SINT); 239 STR(R16G16B16A16_SFLOAT); 240 STR(R32_UINT); 241 STR(R32_SINT); 242 STR(R32_SFLOAT); 243 STR(R32G32_UINT); 244 STR(R32G32_SINT); 245 STR(R32G32_SFLOAT); 246 STR(R32G32B32_UINT); 247 STR(R32G32B32_SINT); 248 STR(R32G32B32_SFLOAT); 249 STR(R32G32B32A32_UINT); 250 STR(R32G32B32A32_SINT); 251 STR(R32G32B32A32_SFLOAT); 252 STR(R64_SFLOAT); 253 STR(R64G64_SFLOAT); 254 STR(R64G64B64_SFLOAT); 255 STR(R64G64B64A64_SFLOAT); 256 STR(R11G11B10_UFLOAT); 257 STR(R9G9B9E5_UFLOAT); 258 STR(D16_UNORM); 259 STR(D24_UNORM_X8); 260 STR(D32_SFLOAT); 261 STR(S8_UINT); 262 STR(D16_UNORM_S8_UINT); 263 STR(D24_UNORM_S8_UINT); 264 STR(D32_SFLOAT_S8_UINT); 265 STR(BC1_RGB_UNORM); 266 STR(BC1_RGB_SRGB); 267 STR(BC2_UNORM); 268 STR(BC2_SRGB); 269 STR(BC3_UNORM); 270 STR(BC3_SRGB); 271 STR(BC4_UNORM); 272 STR(BC4_SNORM); 273 STR(BC5_UNORM); 274 STR(BC5_SNORM); 275 STR(BC6H_UFLOAT); 276 STR(BC6H_SFLOAT); 277 STR(BC7_UNORM); 278 STR(BC7_SRGB); 279 STR(ETC2_R8G8B8_UNORM); 280 STR(ETC2_R8G8B8A1_UNORM); 281 STR(ETC2_R8G8B8A8_UNORM); 282 STR(EAC_R11_UNORM); 283 STR(EAC_R11_SNORM); 284 STR(EAC_R11G11_UNORM); 285 STR(EAC_R11G11_SNORM); 286 STR(ASTC_4x4_UNORM); 287 STR(ASTC_4x4_SRGB); 288 STR(ASTC_5x4_UNORM); 289 STR(ASTC_5x4_SRGB); 290 STR(ASTC_5x5_UNORM); 291 STR(ASTC_5x5_SRGB); 292 STR(ASTC_6x5_UNORM); 293 STR(ASTC_6x5_SRGB); 294 STR(ASTC_6x6_UNORM); 295 STR(ASTC_6x6_SRGB); 296 STR(ASTC_8x5_UNORM); 297 STR(ASTC_8x5_SRGB); 298 STR(ASTC_8x6_UNORM); 299 STR(ASTC_8x6_SRGB); 300 STR(ASTC_8x8_UNORM); 301 STR(ASTC_8x8_SRGB); 302 STR(ASTC_10x5_UNORM); 303 STR(ASTC_10x5_SRGB); 304 STR(ASTC_10x6_UNORM); 305 STR(ASTC_10x6_SRGB); 306 STR(ASTC_10x8_UNORM); 307 STR(ASTC_10x8_SRGB); 308 STR(ASTC_10x10_UNORM); 309 STR(ASTC_10x10_SRGB); 310 STR(ASTC_12x10_UNORM); 311 STR(ASTC_12x10_SRGB); 312 STR(ASTC_12x12_UNORM); 313 STR(ASTC_12x12_SRGB); 314 STR(B5G6R5_UNORM); 315 STR(B5G6R5_USCALED); 316 STR(B8G8R8_UNORM); 317 STR(B8G8R8_SNORM); 318 STR(B8G8R8_USCALED); 319 STR(B8G8R8_SSCALED); 320 STR(B8G8R8_UINT); 321 STR(B8G8R8_SINT); 322 STR(B8G8R8_SRGB); 323 STR(B8G8R8A8_UNORM); 324 STR(B8G8R8A8_SNORM); 325 STR(B8G8R8A8_USCALED); 326 STR(B8G8R8A8_SSCALED); 327 STR(B8G8R8A8_UINT); 328 STR(B8G8R8A8_SINT); 329 STR(B8G8R8A8_SRGB); 330 STR(B10G10R10A2_UNORM); 331 STR(B10G10R10A2_SNORM); 332 STR(B10G10R10A2_USCALED); 333 STR(B10G10R10A2_SSCALED); 334 STR(B10G10R10A2_UINT); 335 STR(B10G10R10A2_SINT); 336#undef STR 337 default: return "UNKNOWN_FORMAT"; 338 } 339} 340 341static void app_dev_init_formats(struct app_dev *dev) 342{ 343 VkFormat f; 344 345 for (f = 0; f < VK_FORMAT_RANGE_SIZE; f++) { 346 const VkFormat fmt = f; 347 348 vkGetPhysicalDeviceFormatProperties(dev->gpu->obj, fmt, &dev->format_props[f]); 349 } 350} 351 352static void extract_version(uint32_t version, uint32_t *major, uint32_t *minor, uint32_t *patch) 353{ 354 *major = version >> 22; 355 *minor = (version >> 12) & 0x3ff; 356 *patch = version & 0xfff; 357} 358 359static void app_get_physical_device_layer_extensions( 360 struct app_gpu *gpu, 361 char *layer_name, 362 uint32_t *extension_count, 363 VkExtensionProperties **extension_properties) 364{ 365 VkResult err; 366 uint32_t ext_count = 0; 367 VkExtensionProperties *ext_ptr = NULL; 368 369 /* repeat get until VK_INCOMPLETE goes away */ 370 do { 371 err = vkEnumerateDeviceExtensionProperties(gpu->obj, layer_name, &ext_count, NULL); 372 assert(!err); 373 374 if (ext_ptr) { 375 free(ext_ptr); 376 } 377 ext_ptr = malloc(ext_count * sizeof(VkExtensionProperties)); 378 err = vkEnumerateDeviceExtensionProperties(gpu->obj, layer_name, &ext_count, ext_ptr); 379 } while (err == VK_INCOMPLETE); 380 assert(!err); 381 382 *extension_count = ext_count; 383 *extension_properties = ext_ptr; 384} 385 386static void app_dev_init(struct app_dev *dev, struct app_gpu *gpu) 387{ 388 VkDeviceCreateInfo info = { 389 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, 390 .pNext = NULL, 391 .requestedQueueCount = 0, 392 .pRequestedQueues = NULL, 393 .enabledLayerNameCount = 0, 394 .ppEnabledLayerNames = NULL, 395 .enabledExtensionNameCount = 0, 396 .ppEnabledExtensionNames = NULL, 397 }; 398 VkResult U_ASSERT_ONLY err; 399 // Extensions to enable 400 static const char *known_extensions[] = { 401 VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NAME, 402 }; 403 404 uint32_t count = 0; 405 406 /* Scan layers */ 407 VkLayerProperties *device_layer_properties = NULL; 408 struct layer_extension_list *device_layers = NULL; 409 410 do { 411 err = vkEnumerateDeviceLayerProperties(gpu->obj, &count, NULL); 412 assert(!err); 413 414 if (device_layer_properties) { 415 free(device_layer_properties); 416 } 417 device_layer_properties = malloc(sizeof(VkLayerProperties) * count); 418 assert(device_layer_properties); 419 420 if (device_layers) { 421 free(device_layers); 422 } 423 device_layers = malloc(sizeof(struct layer_extension_list) * count); 424 assert(device_layers); 425 426 err = vkEnumerateDeviceLayerProperties(gpu->obj, &count, device_layer_properties); 427 } while (err == VK_INCOMPLETE); 428 assert(!err); 429 430 gpu->device_layer_count = count; 431 gpu->device_layers = device_layers; 432 433 for (uint32_t i = 0; i < gpu->device_layer_count; i++) { 434 VkLayerProperties *src_info = &device_layer_properties[i]; 435 struct layer_extension_list *dst_info = &gpu->device_layers[i]; 436 memcpy(&dst_info->layer_properties, src_info, sizeof(VkLayerProperties)); 437 438 /* Save away layer extension info for report */ 439 app_get_physical_device_layer_extensions( 440 gpu, 441 src_info->layerName, 442 &dst_info->extension_count, 443 &dst_info->extension_properties); 444 } 445 free(device_layer_properties); 446 447 app_get_physical_device_layer_extensions( 448 gpu, 449 NULL, 450 &gpu->device_extension_count, 451 &gpu->device_extensions); 452 453 fflush(stdout); 454 455 uint32_t enabled_extension_count = 0; 456 uint32_t known_extension_count = ARRAY_SIZE(known_extensions); 457 458 for (uint32_t i = 0; i < known_extension_count; i++) { 459 VkBool32 extension_found = 0; 460 for (uint32_t j = 0; j < gpu->device_extension_count; j++) { 461 VkExtensionProperties *ext_prop = &gpu->device_extensions[j]; 462 if (!strcmp(known_extensions[i], ext_prop->extensionName)) { 463 464 extension_found = 1; 465 enabled_extension_count++; 466 } 467 } 468 if (!extension_found) { 469 printf("Cannot find extension: %s\n", known_extensions[i]); 470 ERR_EXIT(VK_ERROR_EXTENSION_NOT_PRESENT); 471 } 472 } 473 474 /* request all queues */ 475 info.requestedQueueCount = gpu->queue_count; 476 info.pRequestedQueues = gpu->queue_reqs; 477 478 info.enabledLayerNameCount = 0; 479 info.ppEnabledLayerNames = NULL; 480 info.enabledExtensionNameCount = enabled_extension_count; 481 info.ppEnabledExtensionNames = (const char*const*) known_extensions; 482 dev->gpu = gpu; 483 err = vkCreateDevice(gpu->obj, &info, NULL, &dev->obj); 484 if (err) 485 ERR_EXIT(err); 486 487} 488 489static void app_dev_destroy(struct app_dev *dev) 490{ 491 vkDestroyDevice(dev->obj, NULL); 492} 493 494static void app_get_global_layer_extensions( 495 char *layer_name, 496 uint32_t *extension_count, 497 VkExtensionProperties **extension_properties) 498{ 499 VkResult err; 500 uint32_t ext_count = 0; 501 VkExtensionProperties *ext_ptr = NULL; 502 503 /* repeat get until VK_INCOMPLETE goes away */ 504 do { 505 err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, NULL); 506 assert(!err); 507 508 if (ext_ptr) { 509 free(ext_ptr); 510 } 511 ext_ptr = malloc(ext_count * sizeof(VkExtensionProperties)); 512 err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, ext_ptr); 513 } while (err == VK_INCOMPLETE); 514 assert(!err); 515 516 *extension_count = ext_count; 517 *extension_properties = ext_ptr; 518} 519 520static void app_create_instance(struct app_instance *inst) 521{ 522 const VkApplicationInfo app_info = { 523 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, 524 .pNext = NULL, 525 .pApplicationName = APP_SHORT_NAME, 526 .applicationVersion = 1, 527 .pEngineName = APP_SHORT_NAME, 528 .engineVersion = 1, 529 .apiVersion = VK_API_VERSION, 530 }; 531 VkInstanceCreateInfo inst_info = { 532 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 533 .pNext = NULL, 534 .pApplicationInfo = &app_info, 535 .enabledLayerNameCount = 0, 536 .ppEnabledLayerNames = NULL, 537 .enabledExtensionNameCount = 0, 538 .ppEnabledExtensionNames = NULL, 539 }; 540 VkResult U_ASSERT_ONLY err; 541 // Global Extensions to enable 542 static char *known_extensions[] = { 543 "VK_EXT_KHR_swapchain", 544 }; 545 546 uint32_t global_extension_count = 0; 547 uint32_t count = 0; 548 549 /* Scan layers */ 550 VkLayerProperties *global_layer_properties = NULL; 551 struct layer_extension_list *global_layers = NULL; 552 553 do { 554 err = vkEnumerateInstanceLayerProperties(&count, NULL); 555 assert(!err); 556 557 if (global_layer_properties) { 558 free(global_layer_properties); 559 } 560 global_layer_properties = malloc(sizeof(VkLayerProperties) * count); 561 assert(global_layer_properties); 562 563 if (global_layers) { 564 free(global_layers); 565 } 566 global_layers = malloc(sizeof(struct layer_extension_list) * count); 567 assert(global_layers); 568 569 err = vkEnumerateInstanceLayerProperties(&count, global_layer_properties); 570 } while (err == VK_INCOMPLETE); 571 assert(!err); 572 573 inst->global_layer_count = count; 574 inst->global_layers = global_layers; 575 576 for (uint32_t i = 0; i < inst->global_layer_count; i++) { 577 VkLayerProperties *src_info = &global_layer_properties[i]; 578 struct layer_extension_list *dst_info = &inst->global_layers[i]; 579 memcpy(&dst_info->layer_properties, src_info, sizeof(VkLayerProperties)); 580 581 /* Save away layer extension info for report */ 582 app_get_global_layer_extensions( 583 src_info->layerName, 584 &dst_info->extension_count, 585 &dst_info->extension_properties); 586 } 587 free(global_layer_properties); 588 589 /* Collect global extensions */ 590 inst->global_extension_count = 0; 591 app_get_global_layer_extensions( 592 NULL, 593 &inst->global_extension_count, 594 &inst->global_extensions); 595 596 for (uint32_t i = 0; i < ARRAY_SIZE(known_extensions); i++) { 597 VkBool32 extension_found = 0; 598 for (uint32_t j = 0; j < inst->global_extension_count; j++) { 599 VkExtensionProperties *extension_prop = &inst->global_extensions[j]; 600 if (!strcmp(known_extensions[i], extension_prop->extensionName)) { 601 602 extension_found = 1; 603 global_extension_count++; 604 } 605 } 606 if (!extension_found) { 607 printf("Cannot find extension: %s\n", known_extensions[i]); 608 ERR_EXIT(VK_ERROR_EXTENSION_NOT_PRESENT); 609 } 610 } 611 612 inst_info.enabledExtensionNameCount = global_extension_count; 613 inst_info.ppEnabledExtensionNames = (const char * const *) known_extensions; 614 615 err = vkCreateInstance(&inst_info, NULL, &inst->instance); 616 if (err == VK_ERROR_INCOMPATIBLE_DRIVER) { 617 printf("Cannot create Vulkan instance.\n"); 618 ERR_EXIT(err); 619 } else if (err) { 620 ERR_EXIT(err); 621 } 622} 623 624static void app_destroy_instance(struct app_instance *inst) 625{ 626 free(inst->global_extensions); 627 vkDestroyInstance(inst->instance, NULL); 628} 629 630 631static void app_gpu_init(struct app_gpu *gpu, uint32_t id, VkPhysicalDevice obj) 632{ 633 uint32_t i; 634 635 memset(gpu, 0, sizeof(*gpu)); 636 637 gpu->id = id; 638 gpu->obj = obj; 639 640 vkGetPhysicalDeviceProperties(gpu->obj, &gpu->props); 641 642 /* get queue count */ 643 vkGetPhysicalDeviceQueueFamilyProperties(gpu->obj, &gpu->queue_count, NULL); 644 645 gpu->queue_props = 646 malloc(sizeof(gpu->queue_props[0]) * gpu->queue_count); 647 648 if (!gpu->queue_props) 649 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); 650 vkGetPhysicalDeviceQueueFamilyProperties(gpu->obj, &gpu->queue_count, gpu->queue_props); 651 652 /* set up queue requests */ 653 gpu->queue_reqs = malloc(sizeof(*gpu->queue_reqs) * gpu->queue_count); 654 if (!gpu->queue_reqs) 655 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); 656 for (i = 0; i < gpu->queue_count; i++) { 657 float *queue_priorities = malloc(gpu->queue_props[i].queueCount * sizeof(float)); 658 memset(queue_priorities, 0, gpu->queue_props[i].queueCount * sizeof(float)); 659 gpu->queue_reqs[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 660 gpu->queue_reqs[i].pNext = NULL; 661 gpu->queue_reqs[i].queueFamilyIndex = i; 662 gpu->queue_reqs[i].queuePriorityCount = gpu->queue_props[i].queueCount; 663 gpu->queue_reqs[i].pQueuePriorities = queue_priorities; 664 } 665 666 vkGetPhysicalDeviceMemoryProperties(gpu->obj, &gpu->memory_props); 667 668 vkGetPhysicalDeviceFeatures(gpu->obj, &gpu->features); 669 670 app_dev_init(&gpu->dev, gpu); 671 app_dev_init_formats(&gpu->dev); 672} 673 674static void app_gpu_destroy(struct app_gpu *gpu) 675{ 676 app_dev_destroy(&gpu->dev); 677 free(gpu->device_extensions); 678 free(gpu->queue_reqs); 679 for (uint32_t i = 0; i < gpu->queue_count; i++) { 680 free((void *) gpu->queue_reqs[i].pQueuePriorities); 681 } 682 free(gpu->queue_props); 683} 684 685static void app_dev_dump_format_props(const struct app_dev *dev, VkFormat fmt) 686{ 687 const VkFormatProperties *props = &dev->format_props[fmt]; 688 struct { 689 const char *name; 690 VkFlags flags; 691 } features[3]; 692 uint32_t i; 693 694 features[0].name = "linearTiling FormatFeatureFlags"; 695 features[0].flags = props->linearTilingFeatures; 696 features[1].name = "optimalTiling FormatFeatureFlags"; 697 features[1].flags = props->optimalTilingFeatures; 698 features[2].name = "bufferFeatures FormatFeatureFlags"; 699 features[2].flags = props->bufferFeatures; 700 701 printf("\nFORMAT_%s:", vk_format_string(fmt)); 702 for (i = 0; i < ARRAY_SIZE(features); i++) { 703 printf("\n\t%s:", features[i].name); 704 if (features[i].flags == 0) { 705 printf("\n\t\tNone"); 706 } else { 707 printf("%s%s%s%s%s%s%s%s%s%s%s%s", 708 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT" : ""), 709 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_BIT" : ""), 710 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT" : ""), 711 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT" : ""), 712 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT" : ""), 713 ((features[i].flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) ? "\n\t\tVK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT" : ""), 714 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_SRC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_SRC_BIT" : ""), 715 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_DST_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_DST_BIT" : ""), 716 ((features[i].flags & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT" : ""), 717 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT" : ""), 718 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT" : ""), 719 ((features[i].flags & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_VERTEX_BUFFER_BIT" : "")); 720 } 721 } 722 printf("\n"); 723} 724 725 726static void 727app_dev_dump(const struct app_dev *dev) 728{ 729 VkFormat fmt; 730 731 for (fmt = 0; fmt < VK_FORMAT_RANGE_SIZE; fmt++) { 732 app_dev_dump_format_props(dev, fmt); 733 } 734} 735 736#ifdef _WIN32 737#define PRINTF_SIZE_T_SPECIFIER "%Iu" 738#else 739#define PRINTF_SIZE_T_SPECIFIER "%zu" 740#endif 741 742static void app_gpu_dump_features(const struct app_gpu *gpu) 743{ 744 const VkPhysicalDeviceFeatures *features = &gpu->features; 745 746 printf("VkPhysicalDeviceFeatures:\n"); 747 printf("=========================\n"); 748 749 printf("\trobustBufferAccess = %u\n", features->robustBufferAccess ); 750 printf("\tfullDrawIndexUint32 = %u\n", features->fullDrawIndexUint32 ); 751 printf("\timageCubeArray = %u\n", features->imageCubeArray ); 752 printf("\tindependentBlend = %u\n", features->independentBlend ); 753 printf("\tgeometryShader = %u\n", features->geometryShader ); 754 printf("\ttessellationShader = %u\n", features->tessellationShader ); 755 printf("\tsampleRateShading = %u\n", features->sampleRateShading ); 756 printf("\tdualSrcBlend = %u\n", features->dualSrcBlend ); 757 printf("\tlogicOp = %u\n", features->logicOp ); 758 printf("\tmultiDrawIndirect = %u\n", features->multiDrawIndirect ); 759 printf("\tdepthClamp = %u\n", features->depthClamp ); 760 printf("\tdepthBiasClamp = %u\n", features->depthBiasClamp ); 761 printf("\tfillModeNonSolid = %u\n", features->fillModeNonSolid ); 762 printf("\tdepthBounds = %u\n", features->depthBounds ); 763 printf("\twideLines = %u\n", features->wideLines ); 764 printf("\tlargePoints = %u\n", features->largePoints ); 765 printf("\ttextureCompressionETC2 = %u\n", features->textureCompressionETC2 ); 766 printf("\ttextureCompressionASTC_LDR = %u\n", features->textureCompressionASTC_LDR ); 767 printf("\ttextureCompressionBC = %u\n", features->textureCompressionBC ); 768 printf("\tocclusionQueryNonConservative = %u\n", features->occlusionQueryNonConservative ); 769 printf("\tpipelineStatisticsQuery = %u\n", features->pipelineStatisticsQuery ); 770 printf("\tvertexSideEffects = %u\n", features->vertexPipelineStoresAndAtomics ); 771 printf("\ttessellationSideEffects = %u\n", features->fragmentStoresAndAtomics ); 772 printf("\tgeometrySideEffects = %u\n", features->shaderTessellationAndGeometryPointSize ); 773 printf("\tshaderImageGatherExtended = %u\n", features->shaderImageGatherExtended ); 774 printf("\tshaderStorageImageExtendedFormats = %u\n", features->shaderStorageImageExtendedFormats ); 775 printf("\tshaderStorageImageMultisample = %u\n", features->shaderStorageImageMultisample ); 776 printf("\tshaderUniformBufferArrayDynamicIndexing = %u\n", features->shaderUniformBufferArrayDynamicIndexing); 777 printf("\tshaderSampledImageArrayDynamicIndexing = %u\n", features->shaderSampledImageArrayDynamicIndexing ); 778 printf("\tshaderStorageBufferArrayDynamicIndexing = %u\n", features->shaderStorageBufferArrayDynamicIndexing); 779 printf("\tshaderStorageImageArrayDynamicIndexing = %u\n", features->shaderStorageImageArrayDynamicIndexing ); 780 printf("\tshaderClipDistance = %u\n", features->shaderClipDistance ); 781 printf("\tshaderCullDistance = %u\n", features->shaderCullDistance ); 782 printf("\tshaderFloat64 = %u\n", features->shaderFloat64 ); 783 printf("\tshaderInt64 = %u\n", features->shaderInt64 ); 784 printf("\tshaderInt16 = %u\n", features->shaderInt16 ); 785 printf("\tshaderResourceResidency = %u\n", features->shaderResourceResidency ); 786 printf("\tshaderResourceMinLOD = %u\n", features->shaderResourceMinLOD ); 787 printf("\talphaToOne = %u\n", features->alphaToOne ); 788 printf("\tsparseBinding = %u\n", features->sparseBinding ); 789 printf("\tsparseResidencyBuffer = %u\n", features->sparseResidencyBuffer ); 790 printf("\tsparseResidencyImage2D = %u\n", features->sparseResidencyImage2D ); 791 printf("\tsparseResidencyImage3D = %u\n", features->sparseResidencyImage3D ); 792 printf("\tsparseResidency2Samples = %u\n", features->sparseResidency2Samples ); 793 printf("\tsparseResidency4Samples = %u\n", features->sparseResidency4Samples ); 794 printf("\tsparseResidency8Samples = %u\n", features->sparseResidency8Samples ); 795 printf("\tsparseResidency16Samples = %u\n", features->sparseResidency16Samples ); 796 printf("\tsparseResidencyAliased = %u\n", features->sparseResidencyAliased ); 797} 798 799static void app_dump_sparse_props(const VkPhysicalDeviceSparseProperties *sparseProps) 800{ 801 802 printf("\tVkPhysicalDeviceSparseProperties:\n"); 803 printf("\t---------------------------------\n"); 804 805 printf("\t\tresidencyStandard2DBlockShape = %u\n", sparseProps->residencyStandard2DBlockShape ); 806 printf("\t\tresidencyStandard2DMultisampleBlockShape = %u\n", sparseProps->residencyStandard2DMultisampleBlockShape); 807 printf("\t\tresidencyStandard3DBlockShape = %u\n", sparseProps->residencyStandard3DBlockShape ); 808 printf("\t\tresidencyAlignedMipSize = %u\n", sparseProps->residencyAlignedMipSize ); 809 printf("\t\tresidencyNonResident = %u\n", sparseProps->residencyNonResident ); 810 printf("\t\tresidencyNonResidentStrict = %u\n", sparseProps->residencyNonResidentStrict ); 811} 812 813static void app_dump_limits(const VkPhysicalDeviceLimits *limits) 814{ 815 printf("\tVkPhysicalDeviceLimits:\n"); 816 printf("\t-----------------------\n"); 817 818 printf("\t\tmaxImageDimension1D = 0x%" PRIxLEAST32 "\n", limits->maxImageDimension1D ); 819 printf("\t\tmaxImageDimension2D = 0x%" PRIxLEAST32 "\n", limits->maxImageDimension2D ); 820 printf("\t\tmaxImageDimension3D = 0x%" PRIxLEAST32 "\n", limits->maxImageDimension3D ); 821 printf("\t\tmaxImageDimensionCube = 0x%" PRIxLEAST32 "\n", limits->maxImageDimensionCube ); 822 printf("\t\tmaxImageArrayLayers = 0x%" PRIxLEAST32 "\n", limits->maxImageArrayLayers ); 823 printf("\t\tsampleCounts = 0x%" PRIxLEAST32 "\n", limits->sampleCounts ); 824 printf("\t\tmaxTexelBufferElements = 0x%" PRIxLEAST32 "\n", limits->maxTexelBufferElements ); 825 printf("\t\tmaxUniformBufferRange = 0x%" PRIxLEAST32 "\n", limits->maxUniformBufferRange ); 826 printf("\t\tmaxStorageBufferRange = 0x%" PRIxLEAST32 "\n", limits->maxStorageBufferRange ); 827 printf("\t\tmaxPushConstantsSize = 0x%" PRIxLEAST32 "\n", limits->maxPushConstantsSize ); 828 printf("\t\tmaxMemoryAllocationCount = 0x%" PRIxLEAST32 "\n", limits->maxMemoryAllocationCount ); 829 printf("\t\tbufferImageGranularity = 0x%" PRIxLEAST64 "\n", limits->bufferImageGranularity ); 830 printf("\t\tsparseAddressSpaceSize = 0x%" PRIxLEAST64 "\n", limits->sparseAddressSpaceSize ); 831 printf("\t\tmaxBoundDescriptorSets = 0x%" PRIxLEAST32 "\n", limits->maxBoundDescriptorSets ); 832 printf("\t\tmaxPerStageDescriptorSamplers = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorSamplers ); 833 printf("\t\tmaxPerStageDescriptorUniformBuffers = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorUniformBuffers ); 834 printf("\t\tmaxPerStageDescriptorStorageBuffers = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorStorageBuffers ); 835 printf("\t\tmaxPerStageDescriptorSampledImages = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorSampledImages ); 836 printf("\t\tmaxPerStageDescriptorStorageImages = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorStorageImages ); 837 printf("\t\tmaxDescriptorSetSamplers = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetSamplers ); 838 printf("\t\tmaxDescriptorSetUniformBuffers = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetUniformBuffers ); 839 printf("\t\tmaxDescriptorSetUniformBuffersDynamic = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetUniformBuffersDynamic ); 840 printf("\t\tmaxDescriptorSetStorageBuffers = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetStorageBuffers ); 841 printf("\t\tmaxDescriptorSetStorageBuffersDynamic = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetStorageBuffersDynamic ); 842 printf("\t\tmaxDescriptorSetSampledImages = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetSampledImages ); 843 printf("\t\tmaxDescriptorSetStorageImages = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetStorageImages ); 844 printf("\t\tmaxVertexInputAttributes = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputAttributes ); 845 printf("\t\tmaxVertexInputBindings = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputBindings ); 846 printf("\t\tmaxVertexInputAttributeOffset = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputAttributeOffset ); 847 printf("\t\tmaxVertexInputBindingStride = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputBindingStride ); 848 printf("\t\tmaxVertexOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxVertexOutputComponents ); 849 printf("\t\tmaxTessellationGenerationLevel = 0x%" PRIxLEAST32 "\n", limits->maxTessellationGenerationLevel ); 850 printf("\t\tmaxTessellationPatchSize = 0x%" PRIxLEAST32 "\n", limits->maxTessellationPatchSize ); 851 printf("\t\tmaxTessellationControlPerVertexInputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessellationControlPerVertexInputComponents ); 852 printf("\t\tmaxTessellationControlPerVertexOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessellationControlPerVertexOutputComponents); 853 printf("\t\tmaxTessellationControlPerPatchOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessellationControlPerPatchOutputComponents ); 854 printf("\t\tmaxTessellationControlTotalOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessellationControlTotalOutputComponents ); 855 printf("\t\tmaxTessellationEvaluationInputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessellationEvaluationInputComponents ); 856 printf("\t\tmaxTessellationEvaluationOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessellationEvaluationOutputComponents ); 857 printf("\t\tmaxGeometryShaderInvocations = 0x%" PRIxLEAST32 "\n", limits->maxGeometryShaderInvocations ); 858 printf("\t\tmaxGeometryInputComponents = 0x%" PRIxLEAST32 "\n", limits->maxGeometryInputComponents ); 859 printf("\t\tmaxGeometryOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxGeometryOutputComponents ); 860 printf("\t\tmaxGeometryOutputVertices = 0x%" PRIxLEAST32 "\n", limits->maxGeometryOutputVertices ); 861 printf("\t\tmaxGeometryTotalOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxGeometryTotalOutputComponents ); 862 printf("\t\tmaxFragmentInputComponents = 0x%" PRIxLEAST32 "\n", limits->maxFragmentInputComponents ); 863 printf("\t\tmaxFragmentOutputAttachments = 0x%" PRIxLEAST32 "\n", limits->maxFragmentOutputAttachments ); 864 printf("\t\tmaxFragmentDualSrcAttachments = 0x%" PRIxLEAST32 "\n", limits->maxFragmentDualSrcAttachments ); 865 printf("\t\tmaxFragmentCombinedOutputResources = 0x%" PRIxLEAST32 "\n", limits->maxFragmentCombinedOutputResources ); 866 printf("\t\tmaxComputeSharedMemorySize = 0x%" PRIxLEAST32 "\n", limits->maxComputeSharedMemorySize ); 867 printf("\t\tmaxComputeWorkGroupCount[0] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupCount[0] ); 868 printf("\t\tmaxComputeWorkGroupCount[1] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupCount[1] ); 869 printf("\t\tmaxComputeWorkGroupCount[2] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupCount[2] ); 870 printf("\t\tmaxComputeWorkGroupInvocations = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupInvocations ); 871 printf("\t\tmaxComputeWorkGroupSize[0] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupSize[0] ); 872 printf("\t\tmaxComputeWorkGroupSize[1] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupSize[1] ); 873 printf("\t\tmaxComputeWorkGroupSize[2] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupSize[2] ); 874 printf("\t\tsubPixelPrecisionBits = 0x%" PRIxLEAST32 "\n", limits->subPixelPrecisionBits ); 875 printf("\t\tsubTexelPrecisionBits = 0x%" PRIxLEAST32 "\n", limits->subTexelPrecisionBits ); 876 printf("\t\tmipmapPrecisionBits = 0x%" PRIxLEAST32 "\n", limits->mipmapPrecisionBits ); 877 printf("\t\tmaxDrawIndexedIndexValue = 0x%" PRIxLEAST32 "\n", limits->maxDrawIndexedIndexValue ); 878 printf("\t\tmaxDrawIndirectInstanceCount = 0x%" PRIxLEAST32 "\n", limits->maxDrawIndirectInstanceCount ); 879 printf("\t\tmaxSamplerLodBias = %f\n", limits->maxSamplerLodBias ); 880 printf("\t\tmaxSamplerAnisotropy = %f\n", limits->maxSamplerAnisotropy ); 881 printf("\t\tmaxViewports = 0x%" PRIxLEAST32 "\n", limits->maxViewports ); 882 printf("\t\tmaxViewportDimensions[0] = 0x%" PRIxLEAST32 "\n", limits->maxViewportDimensions[0] ); 883 printf("\t\tmaxViewportDimensions[1] = 0x%" PRIxLEAST32 "\n", limits->maxViewportDimensions[1] ); 884 printf("\t\tviewportBoundsRange[0] = %f\n", limits->viewportBoundsRange[0] ); 885 printf("\t\tviewportBoundsRange[1] = %f\n", limits->viewportBoundsRange[1] ); 886 printf("\t\tviewportSubPixelBits = 0x%" PRIxLEAST32 "\n", limits->viewportSubPixelBits ); 887 printf("\t\tminMemoryMapAlignment = " PRINTF_SIZE_T_SPECIFIER "\n", limits->minMemoryMapAlignment ); 888 printf("\t\tminTexelBufferOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->minTexelBufferOffsetAlignment ); 889 printf("\t\tminUniformBufferOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->minUniformBufferOffsetAlignment ); 890 printf("\t\tminStorageBufferOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->minStorageBufferOffsetAlignment ); 891 printf("\t\tminTexelOffset = 0x%" PRIxLEAST32 "\n", limits->minTexelOffset ); 892 printf("\t\tmaxTexelOffset = 0x%" PRIxLEAST32 "\n", limits->maxTexelOffset ); 893 printf("\t\tminTexelGatherOffset = 0x%" PRIxLEAST32 "\n", limits->minTexelGatherOffset ); 894 printf("\t\tmaxTexelGatherOffset = 0x%" PRIxLEAST32 "\n", limits->maxTexelGatherOffset ); 895 printf("\t\tminInterpolationOffset = %f\n", limits->minInterpolationOffset ); 896 printf("\t\tmaxInterpolationOffset = %f\n", limits->maxInterpolationOffset ); 897 printf("\t\tsubPixelInterpolationOffsetBits = 0x%" PRIxLEAST32 "\n", limits->subPixelInterpolationOffsetBits ); 898 printf("\t\tmaxFramebufferWidth = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferWidth ); 899 printf("\t\tmaxFramebufferHeight = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferHeight ); 900 printf("\t\tmaxFramebufferLayers = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferLayers ); 901 printf("\t\tmaxFramebufferColorSamples = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferColorSamples ); 902 printf("\t\tmaxFramebufferDepthSamples = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferDepthSamples ); 903 printf("\t\tmaxFramebufferStencilSamples = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferStencilSamples ); 904 printf("\t\tmaxColorAttachments = 0x%" PRIxLEAST32 "\n", limits->maxColorAttachments ); 905 printf("\t\tmaxSampledImageColorSamples = 0x%" PRIxLEAST32 "\n", limits->maxSampledImageColorSamples ); 906 printf("\t\tmaxSampledImageDepthSamples = 0x%" PRIxLEAST32 "\n", limits->maxSampledImageDepthSamples ); 907 printf("\t\tmaxSampledImageIntegerSamples = 0x%" PRIxLEAST32 "\n", limits->maxSampledImageIntegerSamples ); 908 printf("\t\tmaxStorageImageSamples = 0x%" PRIxLEAST32 "\n", limits->maxStorageImageSamples ); 909 printf("\t\tmaxSampleMaskWords = 0x%" PRIxLEAST32 "\n", limits->maxSampleMaskWords ); 910 printf("\t\ttimestampPeriod = 0x%f\n", limits->timestampPeriod ); 911 printf("\t\tmaxClipDistances = 0x%" PRIxLEAST32 "\n", limits->maxClipDistances ); 912 printf("\t\tmaxCullDistances = 0x%" PRIxLEAST32 "\n", limits->maxCullDistances ); 913 printf("\t\tmaxCombinedClipAndCullDistances = 0x%" PRIxLEAST32 "\n", limits->maxCombinedClipAndCullDistances ); 914 printf("\t\tpointSizeRange[0] = %f\n", limits->pointSizeRange[0] ); 915 printf("\t\tpointSizeRange[1] = %f\n", limits->pointSizeRange[1] ); 916 printf("\t\tlineWidthRange[0] = %f\n", limits->lineWidthRange[0] ); 917 printf("\t\tlineWidthRange[1] = %f\n", limits->lineWidthRange[1] ); 918 printf("\t\tpointSizeGranularity = %f\n", limits->pointSizeGranularity ); 919 printf("\t\tlineWidthGranularity = %f\n", limits->lineWidthGranularity ); 920 printf("\t\tstrictLines = %u\n", limits->strictLines ); 921 printf("\t\trecommendedBufferCopyOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->recommendedBufferCopyOffsetAlignment ); 922 printf("\t\trecommendedBufferCopyRowPitchAlignment = 0x%" PRIxLEAST64 "\n", limits->recommendedBufferCopyRowPitchAlignment ); 923} 924 925static void app_gpu_dump_props(const struct app_gpu *gpu) 926{ 927 const VkPhysicalDeviceProperties *props = &gpu->props; 928 929 printf("VkPhysicalDeviceProperties:\n"); 930 printf("===========================\n"); 931 printf("\tapiVersion = %u\n", props->apiVersion); 932 printf("\tdriverVersion = %u\n", props->driverVersion); 933 printf("\tvendorId = 0x%04x\n", props->vendorId); 934 printf("\tdeviceId = 0x%04x\n", props->deviceId); 935 printf("\tdeviceType = %s\n", vk_physical_device_type_string(props->deviceType)); 936 printf("\tdeviceName = %s\n", props->deviceName); 937 938 app_dump_limits(&gpu->props.limits); 939 app_dump_sparse_props(&gpu->props.sparseProperties); 940 941 fflush(stdout); 942} 943 944static void app_dump_extensions( 945 const char *indent, 946 const char *layer_name, 947 const uint32_t extension_count, 948 const VkExtensionProperties *extension_properties) 949{ 950 uint32_t i; 951 if (layer_name && (strlen(layer_name) > 0)) { 952 printf("%s%s Extensions", indent, layer_name); 953 } else { 954 printf("Extensions"); 955 } 956 printf("\tcount = %d\n", extension_count); 957 for (i=0; i< extension_count; i++) { 958 VkExtensionProperties const *ext_prop = &extension_properties[i]; 959 960 if (i>0) 961 printf("\n"); // separator between extensions 962 963 printf("%s\t", indent); 964 printf("%-32s: extension revision %2d", 965 ext_prop->extensionName, ext_prop->specVersion); 966 } 967 printf("\n"); 968 fflush(stdout); 969} 970 971static void app_gpu_dump_queue_props(const struct app_gpu *gpu, uint32_t id) 972{ 973 const VkQueueFamilyProperties *props = &gpu->queue_props[id]; 974 975 printf("VkQueueFamilyProperties[%d]:\n", id); 976 printf("============================\n"); 977 printf("\tqueueFlags = %c%c%c\n", 978 (props->queueFlags & VK_QUEUE_GRAPHICS_BIT) ? 'G' : '.', 979 (props->queueFlags & VK_QUEUE_COMPUTE_BIT) ? 'C' : '.', 980 (props->queueFlags & VK_QUEUE_DMA_BIT) ? 'D' : '.'); 981 printf("\tqueueCount = %u\n", props->queueCount); 982 printf("\ttimestampValidBits = %u\n", props->timestampValidBits); 983 fflush(stdout); 984} 985 986static void app_gpu_dump_memory_props(const struct app_gpu *gpu) 987{ 988 const VkPhysicalDeviceMemoryProperties *props = &gpu->memory_props; 989 990 printf("VkPhysicalDeviceMemoryProperties:\n"); 991 printf("=================================\n"); 992 printf("\tmemoryTypeCount = %u\n", props->memoryTypeCount); 993 for (uint32_t i = 0; i < props->memoryTypeCount; i++) { 994 printf("\tmemoryTypes[%u] : \n", i); 995 printf("\t\tpropertyFlags = %u\n", props->memoryTypes[i].propertyFlags); 996 printf("\t\theapIndex = %u\n", props->memoryTypes[i].heapIndex); 997 } 998 printf("\tmemoryHeapCount = %u\n", props->memoryHeapCount); 999 for (uint32_t i = 0; i < props->memoryHeapCount; i++) { 1000 printf("\tmemoryHeaps[%u] : \n", i); 1001 printf("\t\tsize = " PRINTF_SIZE_T_SPECIFIER "\n", props->memoryHeaps[i].size); 1002 } 1003 fflush(stdout); 1004} 1005 1006static void app_gpu_dump(const struct app_gpu *gpu) 1007{ 1008 uint32_t i; 1009 1010 printf("Device Extensions and layers:\n"); 1011 printf("=============================\n"); 1012 printf("GPU%u\n", gpu->id); 1013 app_gpu_dump_props(gpu); 1014 printf("\n"); 1015 app_dump_extensions("", "Device", gpu->device_extension_count, gpu->device_extensions); 1016 printf("\n"); 1017 printf("Layers\tcount = %d\n", gpu->device_layer_count); 1018 for (uint32_t i = 0; i < gpu->device_layer_count; i++) { 1019 uint32_t major, minor, patch; 1020 char spec_version[64], layer_version[64]; 1021 struct layer_extension_list const *layer_info = &gpu->device_layers[i]; 1022 1023 extract_version(layer_info->layer_properties.specVersion, &major, &minor, &patch); 1024 snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", major, minor, patch); 1025 extract_version(layer_info->layer_properties.implementationVersion, &major, &minor, &patch); 1026 snprintf(layer_version, sizeof(layer_version), "%d.%d.%d", major, minor, patch); 1027 printf("\t%s (%s) Vulkan version %s, layer version %s\n", 1028 layer_info->layer_properties.layerName, 1029 (char*) layer_info->layer_properties.description, 1030 spec_version, layer_version); 1031 1032 app_dump_extensions("\t", 1033 layer_info->layer_properties.layerName, 1034 layer_info->extension_count, 1035 layer_info->extension_properties); 1036 fflush(stdout); 1037 } 1038 printf("\n"); 1039 for (i = 0; i < gpu->queue_count; i++) { 1040 app_gpu_dump_queue_props(gpu, i); 1041 printf("\n"); 1042 } 1043 app_gpu_dump_memory_props(gpu); 1044 printf("\n"); 1045 app_gpu_dump_features(gpu); 1046 printf("\n"); 1047 app_dev_dump(&gpu->dev); 1048} 1049 1050int main(int argc, char **argv) 1051{ 1052 unsigned int major, minor, patch; 1053 struct app_gpu gpus[MAX_GPUS]; 1054 VkPhysicalDevice objs[MAX_GPUS]; 1055 uint32_t gpu_count, i; 1056 VkResult err; 1057 struct app_instance inst; 1058 1059 major = VK_API_VERSION >> 22; 1060 minor = (VK_API_VERSION >> 12) & 0x4ff; 1061 patch = VK_API_VERSION & 0xfff; 1062 printf("===========\n"); 1063 printf("VULKAN INFO\n"); 1064 printf("===========\n\n"); 1065 printf("Vulkan API Version: %d %d %d\n\n", major, minor, patch); 1066 1067 app_create_instance(&inst); 1068 1069 printf("Instance Extensions and layers:\n"); 1070 printf("===============================\n"); 1071 app_dump_extensions("", "Instance", inst.global_extension_count, inst.global_extensions); 1072 1073 printf("Instance Layers\tcount = %d\n", inst.global_layer_count); 1074 for (uint32_t i = 0; i < inst.global_layer_count; i++) { 1075 uint32_t major, minor, patch; 1076 char spec_version[64], layer_version[64]; 1077 VkLayerProperties const *layer_prop = &inst.global_layers[i].layer_properties; 1078 1079 extract_version(layer_prop->specVersion, &major, &minor, &patch); 1080 snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", major, minor, patch); 1081 extract_version(layer_prop->implementationVersion, &major, &minor, &patch); 1082 snprintf(layer_version, sizeof(layer_version), "%d.%d.%d", major, minor, patch); 1083 printf("\t%s (%s) Vulkan version %s, layer version %s\n", 1084 layer_prop->layerName, (char*) layer_prop->description, spec_version, layer_version); 1085 1086 app_dump_extensions("\t", 1087 inst.global_layers[i].layer_properties.layerName, 1088 inst.global_layers[i].extension_count, 1089 inst.global_layers[i].extension_properties); 1090 } 1091 1092 err = vkEnumeratePhysicalDevices(inst.instance, &gpu_count, NULL); 1093 if (err) 1094 ERR_EXIT(err); 1095 if (gpu_count > MAX_GPUS) { 1096 printf("Too many GPUS found \n"); 1097 ERR_EXIT(-1); 1098 } 1099 err = vkEnumeratePhysicalDevices(inst.instance, &gpu_count, objs); 1100 if (err) 1101 ERR_EXIT(err); 1102 1103 for (i = 0; i < gpu_count; i++) { 1104 app_gpu_init(&gpus[i], i, objs[i]); 1105 app_gpu_dump(&gpus[i]); 1106 printf("\n\n"); 1107 } 1108 1109 for (i = 0; i < gpu_count; i++) 1110 app_gpu_destroy(&gpus[i]); 1111 1112 app_destroy_instance(&inst); 1113 1114 return 0; 1115} 1116 1117#ifdef _WIN32 1118 1119// Create a console window with a large scrollback size to which to send stdout. 1120// Returns true if console window was successfully created, false otherwise. 1121bool SetStdOutToNewConsole() 1122{ 1123 // don't do anything if we already have a console 1124 if (GetStdHandle(STD_OUTPUT_HANDLE)) 1125 return false; 1126 1127 // allocate a console for this app 1128 AllocConsole(); 1129 1130 // redirect unbuffered STDOUT to the console 1131 HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); 1132 int fileDescriptor = _open_osfhandle((intptr_t)consoleHandle, _O_TEXT); 1133 FILE *fp = _fdopen( fileDescriptor, "w" ); 1134 *stdout = *fp; 1135 setvbuf( stdout, NULL, _IONBF, 0 ); 1136 1137 // make the console window bigger 1138 CONSOLE_SCREEN_BUFFER_INFO csbi; 1139 SMALL_RECT r; 1140 COORD bufferSize; 1141 if (!GetConsoleScreenBufferInfo(consoleHandle, &csbi)) 1142 return false; 1143 bufferSize.X = csbi.dwSize.X+30; 1144 bufferSize.Y = 20000; 1145 if (!SetConsoleScreenBufferSize(consoleHandle, bufferSize)) 1146 return false; 1147 r.Left = r.Top = 0; 1148 r.Right = csbi.dwSize.X-1+30; 1149 r.Bottom = 50; 1150 if (!SetConsoleWindowInfo(consoleHandle, true, &r)) 1151 return false; 1152 1153 // change the console window title 1154 if (!SetConsoleTitle(TEXT(APP_SHORT_NAME))) 1155 return false; 1156 1157 return true; 1158} 1159 1160int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nCmdShow) 1161{ 1162 char *argv = pCmdLine; 1163 consoleCreated = SetStdOutToNewConsole(); 1164 main(1, &argv); 1165 fflush(stdout); 1166 if (consoleCreated) 1167 Sleep(INFINITE); 1168} 1169#endif 1170