vulkaninfo.c revision e1b115fdf18e54ebfd90e3990ad775527a38534b
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_NUM]; 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_UNSUPPORTED); 136 STR(VK_NOT_READY); 137 STR(VK_TIMEOUT); 138 STR(VK_EVENT_SET); 139 STR(VK_EVENT_RESET); 140 STR(VK_ERROR_INITIALIZATION_FAILED); 141 STR(VK_ERROR_OUT_OF_HOST_MEMORY); 142 STR(VK_ERROR_OUT_OF_DEVICE_MEMORY); 143 STR(VK_ERROR_DEVICE_LOST); 144 STR(VK_ERROR_LAYER_NOT_PRESENT); 145 STR(VK_ERROR_EXTENSION_NOT_PRESENT); 146 STR(VK_ERROR_MEMORY_MAP_FAILED); 147 STR(VK_ERROR_INCOMPATIBLE_DRIVER); 148#undef STR 149 default: return "UNKNOWN_RESULT"; 150 } 151} 152 153static const char *vk_physical_device_type_string(VkPhysicalDeviceType type) 154{ 155 switch (type) { 156#define STR(r) case VK_PHYSICAL_DEVICE_TYPE_ ##r: return #r 157 STR(OTHER); 158 STR(INTEGRATED_GPU); 159 STR(DISCRETE_GPU); 160 STR(VIRTUAL_GPU); 161#undef STR 162 default: return "UNKNOWN_DEVICE"; 163 } 164} 165 166static const char *vk_format_string(VkFormat fmt) 167{ 168 switch (fmt) { 169#define STR(r) case VK_FORMAT_ ##r: return #r 170 STR(UNDEFINED); 171 STR(R4G4_UNORM); 172 STR(R4G4_USCALED); 173 STR(R4G4B4A4_UNORM); 174 STR(R4G4B4A4_USCALED); 175 STR(R5G6B5_UNORM); 176 STR(R5G6B5_USCALED); 177 STR(R5G5B5A1_UNORM); 178 STR(R5G5B5A1_USCALED); 179 STR(R8_UNORM); 180 STR(R8_SNORM); 181 STR(R8_USCALED); 182 STR(R8_SSCALED); 183 STR(R8_UINT); 184 STR(R8_SINT); 185 STR(R8_SRGB); 186 STR(R8G8_UNORM); 187 STR(R8G8_SNORM); 188 STR(R8G8_USCALED); 189 STR(R8G8_SSCALED); 190 STR(R8G8_UINT); 191 STR(R8G8_SINT); 192 STR(R8G8_SRGB); 193 STR(R8G8B8_UNORM); 194 STR(R8G8B8_SNORM); 195 STR(R8G8B8_USCALED); 196 STR(R8G8B8_SSCALED); 197 STR(R8G8B8_UINT); 198 STR(R8G8B8_SINT); 199 STR(R8G8B8_SRGB); 200 STR(R8G8B8A8_UNORM); 201 STR(R8G8B8A8_SNORM); 202 STR(R8G8B8A8_USCALED); 203 STR(R8G8B8A8_SSCALED); 204 STR(R8G8B8A8_UINT); 205 STR(R8G8B8A8_SINT); 206 STR(R8G8B8A8_SRGB); 207 STR(R10G10B10A2_UNORM); 208 STR(R10G10B10A2_SNORM); 209 STR(R10G10B10A2_USCALED); 210 STR(R10G10B10A2_SSCALED); 211 STR(R10G10B10A2_UINT); 212 STR(R10G10B10A2_SINT); 213 STR(R16_UNORM); 214 STR(R16_SNORM); 215 STR(R16_USCALED); 216 STR(R16_SSCALED); 217 STR(R16_UINT); 218 STR(R16_SINT); 219 STR(R16_SFLOAT); 220 STR(R16G16_UNORM); 221 STR(R16G16_SNORM); 222 STR(R16G16_USCALED); 223 STR(R16G16_SSCALED); 224 STR(R16G16_UINT); 225 STR(R16G16_SINT); 226 STR(R16G16_SFLOAT); 227 STR(R16G16B16_UNORM); 228 STR(R16G16B16_SNORM); 229 STR(R16G16B16_USCALED); 230 STR(R16G16B16_SSCALED); 231 STR(R16G16B16_UINT); 232 STR(R16G16B16_SINT); 233 STR(R16G16B16_SFLOAT); 234 STR(R16G16B16A16_UNORM); 235 STR(R16G16B16A16_SNORM); 236 STR(R16G16B16A16_USCALED); 237 STR(R16G16B16A16_SSCALED); 238 STR(R16G16B16A16_UINT); 239 STR(R16G16B16A16_SINT); 240 STR(R16G16B16A16_SFLOAT); 241 STR(R32_UINT); 242 STR(R32_SINT); 243 STR(R32_SFLOAT); 244 STR(R32G32_UINT); 245 STR(R32G32_SINT); 246 STR(R32G32_SFLOAT); 247 STR(R32G32B32_UINT); 248 STR(R32G32B32_SINT); 249 STR(R32G32B32_SFLOAT); 250 STR(R32G32B32A32_UINT); 251 STR(R32G32B32A32_SINT); 252 STR(R32G32B32A32_SFLOAT); 253 STR(R64_SFLOAT); 254 STR(R64G64_SFLOAT); 255 STR(R64G64B64_SFLOAT); 256 STR(R64G64B64A64_SFLOAT); 257 STR(R11G11B10_UFLOAT); 258 STR(R9G9B9E5_UFLOAT); 259 STR(D16_UNORM); 260 STR(D24_UNORM_X8); 261 STR(D32_SFLOAT); 262 STR(S8_UINT); 263 STR(D16_UNORM_S8_UINT); 264 STR(D24_UNORM_S8_UINT); 265 STR(D32_SFLOAT_S8_UINT); 266 STR(BC1_RGB_UNORM); 267 STR(BC1_RGB_SRGB); 268 STR(BC2_UNORM); 269 STR(BC2_SRGB); 270 STR(BC3_UNORM); 271 STR(BC3_SRGB); 272 STR(BC4_UNORM); 273 STR(BC4_SNORM); 274 STR(BC5_UNORM); 275 STR(BC5_SNORM); 276 STR(BC6H_UFLOAT); 277 STR(BC6H_SFLOAT); 278 STR(BC7_UNORM); 279 STR(BC7_SRGB); 280 STR(ETC2_R8G8B8_UNORM); 281 STR(ETC2_R8G8B8A1_UNORM); 282 STR(ETC2_R8G8B8A8_UNORM); 283 STR(EAC_R11_UNORM); 284 STR(EAC_R11_SNORM); 285 STR(EAC_R11G11_UNORM); 286 STR(EAC_R11G11_SNORM); 287 STR(ASTC_4x4_UNORM); 288 STR(ASTC_4x4_SRGB); 289 STR(ASTC_5x4_UNORM); 290 STR(ASTC_5x4_SRGB); 291 STR(ASTC_5x5_UNORM); 292 STR(ASTC_5x5_SRGB); 293 STR(ASTC_6x5_UNORM); 294 STR(ASTC_6x5_SRGB); 295 STR(ASTC_6x6_UNORM); 296 STR(ASTC_6x6_SRGB); 297 STR(ASTC_8x5_UNORM); 298 STR(ASTC_8x5_SRGB); 299 STR(ASTC_8x6_UNORM); 300 STR(ASTC_8x6_SRGB); 301 STR(ASTC_8x8_UNORM); 302 STR(ASTC_8x8_SRGB); 303 STR(ASTC_10x5_UNORM); 304 STR(ASTC_10x5_SRGB); 305 STR(ASTC_10x6_UNORM); 306 STR(ASTC_10x6_SRGB); 307 STR(ASTC_10x8_UNORM); 308 STR(ASTC_10x8_SRGB); 309 STR(ASTC_10x10_UNORM); 310 STR(ASTC_10x10_SRGB); 311 STR(ASTC_12x10_UNORM); 312 STR(ASTC_12x10_SRGB); 313 STR(ASTC_12x12_UNORM); 314 STR(ASTC_12x12_SRGB); 315 STR(B5G6R5_UNORM); 316 STR(B5G6R5_USCALED); 317 STR(B8G8R8_UNORM); 318 STR(B8G8R8_SNORM); 319 STR(B8G8R8_USCALED); 320 STR(B8G8R8_SSCALED); 321 STR(B8G8R8_UINT); 322 STR(B8G8R8_SINT); 323 STR(B8G8R8_SRGB); 324 STR(B8G8R8A8_UNORM); 325 STR(B8G8R8A8_SNORM); 326 STR(B8G8R8A8_USCALED); 327 STR(B8G8R8A8_SSCALED); 328 STR(B8G8R8A8_UINT); 329 STR(B8G8R8A8_SINT); 330 STR(B8G8R8A8_SRGB); 331 STR(B10G10R10A2_UNORM); 332 STR(B10G10R10A2_SNORM); 333 STR(B10G10R10A2_USCALED); 334 STR(B10G10R10A2_SSCALED); 335 STR(B10G10R10A2_UINT); 336 STR(B10G10R10A2_SINT); 337#undef STR 338 default: return "UNKNOWN_FORMAT"; 339 } 340} 341 342static void app_dev_init_formats(struct app_dev *dev) 343{ 344 VkFormat f; 345 346 for (f = 0; f < VK_FORMAT_NUM; f++) { 347 const VkFormat fmt = f; 348 VkResult err; 349 350 err = vkGetPhysicalDeviceFormatProperties(dev->gpu->obj, fmt, &dev->format_props[f]); 351 if (err) { 352 memset(&dev->format_props[f], 0, 353 sizeof(dev->format_props[f])); 354 } 355 } 356} 357 358static void extract_version(uint32_t version, uint32_t *major, uint32_t *minor, uint32_t *patch) 359{ 360 *major = version >> 22; 361 *minor = (version >> 12) & 0x3ff; 362 *patch = version & 0xfff; 363} 364 365static void app_get_physical_device_layer_extensions( 366 struct app_gpu *gpu, 367 char *layer_name, 368 uint32_t *extension_count, 369 VkExtensionProperties **extension_properties) 370{ 371 VkResult err; 372 uint32_t ext_count = 0; 373 VkExtensionProperties *ext_ptr = NULL; 374 375 /* repeat get until VK_INCOMPLETE goes away */ 376 do { 377 err = vkEnumerateDeviceExtensionProperties(gpu->obj, layer_name, &ext_count, NULL); 378 assert(!err); 379 380 if (ext_ptr) { 381 free(ext_ptr); 382 } 383 ext_ptr = malloc(ext_count * sizeof(VkExtensionProperties)); 384 err = vkEnumerateDeviceExtensionProperties(gpu->obj, layer_name, &ext_count, ext_ptr); 385 } while (err == VK_INCOMPLETE); 386 assert(!err); 387 388 *extension_count = ext_count; 389 *extension_properties = ext_ptr; 390} 391 392static void app_dev_init(struct app_dev *dev, struct app_gpu *gpu) 393{ 394 VkDeviceCreateInfo info = { 395 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, 396 .pNext = NULL, 397 .queueRecordCount = 0, 398 .pRequestedQueues = NULL, 399 .layerCount = 0, 400 .ppEnabledLayerNames = NULL, 401 .extensionCount = 0, 402 .ppEnabledExtensionNames = NULL, 403 }; 404 VkResult U_ASSERT_ONLY err; 405 // Extensions to enable 406 static const char *known_extensions[] = { 407 VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NAME, 408 }; 409 410 uint32_t count = 0; 411 412 /* Scan layers */ 413 VkLayerProperties *device_layer_properties = NULL; 414 struct layer_extension_list *device_layers = NULL; 415 416 do { 417 err = vkEnumerateDeviceLayerProperties(gpu->obj, &count, NULL); 418 assert(!err); 419 420 if (device_layer_properties) { 421 free(device_layer_properties); 422 } 423 device_layer_properties = malloc(sizeof(VkLayerProperties) * count); 424 assert(device_layer_properties); 425 426 if (device_layers) { 427 free(device_layers); 428 } 429 device_layers = malloc(sizeof(struct layer_extension_list) * count); 430 assert(device_layers); 431 432 err = vkEnumerateDeviceLayerProperties(gpu->obj, &count, device_layer_properties); 433 } while (err == VK_INCOMPLETE); 434 assert(!err); 435 436 gpu->device_layer_count = count; 437 gpu->device_layers = device_layers; 438 439 for (uint32_t i = 0; i < gpu->device_layer_count; i++) { 440 VkLayerProperties *src_info = &device_layer_properties[i]; 441 struct layer_extension_list *dst_info = &gpu->device_layers[i]; 442 memcpy(&dst_info->layer_properties, src_info, sizeof(VkLayerProperties)); 443 444 /* Save away layer extension info for report */ 445 app_get_physical_device_layer_extensions( 446 gpu, 447 src_info->layerName, 448 &dst_info->extension_count, 449 &dst_info->extension_properties); 450 } 451 free(device_layer_properties); 452 453 app_get_physical_device_layer_extensions( 454 gpu, 455 NULL, 456 &gpu->device_extension_count, 457 &gpu->device_extensions); 458 459 fflush(stdout); 460 461 uint32_t enabled_extension_count = 0; 462 uint32_t known_extension_count = ARRAY_SIZE(known_extensions); 463 464 for (uint32_t i = 0; i < known_extension_count; i++) { 465 VkBool32 extension_found = 0; 466 for (uint32_t j = 0; j < gpu->device_extension_count; j++) { 467 VkExtensionProperties *ext_prop = &gpu->device_extensions[j]; 468 if (!strcmp(known_extensions[i], ext_prop->extName)) { 469 470 extension_found = 1; 471 enabled_extension_count++; 472 } 473 } 474 if (!extension_found) { 475 printf("Cannot find extension: %s\n", known_extensions[i]); 476 ERR_EXIT(VK_ERROR_EXTENSION_NOT_PRESENT); 477 } 478 } 479 480 /* request all queues */ 481 info.queueRecordCount = gpu->queue_count; 482 info.pRequestedQueues = gpu->queue_reqs; 483 484 info.layerCount = 0; 485 info.ppEnabledLayerNames = NULL; 486 info.extensionCount = enabled_extension_count; 487 info.ppEnabledExtensionNames = (const char*const*) known_extensions; 488 dev->gpu = gpu; 489 err = vkCreateDevice(gpu->obj, &info, &dev->obj); 490 if (err) 491 ERR_EXIT(err); 492 493} 494 495static void app_dev_destroy(struct app_dev *dev) 496{ 497 vkDestroyDevice(dev->obj); 498} 499 500static void app_get_global_layer_extensions( 501 char *layer_name, 502 uint32_t *extension_count, 503 VkExtensionProperties **extension_properties) 504{ 505 VkResult err; 506 uint32_t ext_count = 0; 507 VkExtensionProperties *ext_ptr = NULL; 508 509 /* repeat get until VK_INCOMPLETE goes away */ 510 do { 511 err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, NULL); 512 assert(!err); 513 514 if (ext_ptr) { 515 free(ext_ptr); 516 } 517 ext_ptr = malloc(ext_count * sizeof(VkExtensionProperties)); 518 err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, ext_ptr); 519 } while (err == VK_INCOMPLETE); 520 assert(!err); 521 522 *extension_count = ext_count; 523 *extension_properties = ext_ptr; 524} 525 526static void app_create_instance(struct app_instance *inst) 527{ 528 const VkApplicationInfo app_info = { 529 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, 530 .pNext = NULL, 531 .pAppName = APP_SHORT_NAME, 532 .appVersion = 1, 533 .pEngineName = APP_SHORT_NAME, 534 .engineVersion = 1, 535 .apiVersion = VK_API_VERSION, 536 }; 537 VkInstanceCreateInfo inst_info = { 538 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 539 .pNext = NULL, 540 .pAppInfo = &app_info, 541 .pAllocCb = NULL, 542 .layerCount = 0, 543 .ppEnabledLayerNames = NULL, 544 .extensionCount = 0, 545 .ppEnabledExtensionNames = NULL, 546 }; 547 VkResult U_ASSERT_ONLY err; 548 // Global Extensions to enable 549 static char *known_extensions[] = { 550 "VK_EXT_KHR_swapchain", 551 }; 552 553 uint32_t global_extension_count = 0; 554 uint32_t count = 0; 555 556 /* Scan layers */ 557 VkLayerProperties *global_layer_properties = NULL; 558 struct layer_extension_list *global_layers = NULL; 559 560 do { 561 err = vkEnumerateInstanceLayerProperties(&count, NULL); 562 assert(!err); 563 564 if (global_layer_properties) { 565 free(global_layer_properties); 566 } 567 global_layer_properties = malloc(sizeof(VkLayerProperties) * count); 568 assert(global_layer_properties); 569 570 if (global_layers) { 571 free(global_layers); 572 } 573 global_layers = malloc(sizeof(struct layer_extension_list) * count); 574 assert(global_layers); 575 576 err = vkEnumerateInstanceLayerProperties(&count, global_layer_properties); 577 } while (err == VK_INCOMPLETE); 578 assert(!err); 579 580 inst->global_layer_count = count; 581 inst->global_layers = global_layers; 582 583 for (uint32_t i = 0; i < inst->global_layer_count; i++) { 584 VkLayerProperties *src_info = &global_layer_properties[i]; 585 struct layer_extension_list *dst_info = &inst->global_layers[i]; 586 memcpy(&dst_info->layer_properties, src_info, sizeof(VkLayerProperties)); 587 588 /* Save away layer extension info for report */ 589 app_get_global_layer_extensions( 590 src_info->layerName, 591 &dst_info->extension_count, 592 &dst_info->extension_properties); 593 } 594 free(global_layer_properties); 595 596 /* Collect global extensions */ 597 inst->global_extension_count = 0; 598 app_get_global_layer_extensions( 599 NULL, 600 &inst->global_extension_count, 601 &inst->global_extensions); 602 603 for (uint32_t i = 0; i < ARRAY_SIZE(known_extensions); i++) { 604 VkBool32 extension_found = 0; 605 for (uint32_t j = 0; j < inst->global_extension_count; j++) { 606 VkExtensionProperties *extension_prop = &inst->global_extensions[j]; 607 if (!strcmp(known_extensions[i], extension_prop->extName)) { 608 609 extension_found = 1; 610 global_extension_count++; 611 } 612 } 613 if (!extension_found) { 614 printf("Cannot find extension: %s\n", known_extensions[i]); 615 ERR_EXIT(VK_ERROR_EXTENSION_NOT_PRESENT); 616 } 617 } 618 619 inst_info.extensionCount = global_extension_count; 620 inst_info.ppEnabledExtensionNames = (const char * const *) known_extensions; 621 622 err = vkCreateInstance(&inst_info, &inst->instance); 623 if (err == VK_ERROR_INCOMPATIBLE_DRIVER) { 624 printf("Cannot create Vulkan instance.\n"); 625 ERR_EXIT(err); 626 } else if (err) { 627 ERR_EXIT(err); 628 } 629} 630 631static void app_destroy_instance(struct app_instance *inst) 632{ 633 free(inst->global_extensions); 634 vkDestroyInstance(inst->instance); 635} 636 637 638static void app_gpu_init(struct app_gpu *gpu, uint32_t id, VkPhysicalDevice obj) 639{ 640 VkResult err; 641 uint32_t i; 642 643 memset(gpu, 0, sizeof(*gpu)); 644 645 gpu->id = id; 646 gpu->obj = obj; 647 648 err = vkGetPhysicalDeviceProperties(gpu->obj, &gpu->props); 649 if (err) 650 ERR_EXIT(err); 651 652 /* get queue count */ 653 err = vkGetPhysicalDeviceQueueFamilyProperties(gpu->obj, &gpu->queue_count, NULL); 654 if (err) 655 ERR_EXIT(err); 656 657 gpu->queue_props = 658 malloc(sizeof(gpu->queue_props[0]) * gpu->queue_count); 659 660 if (!gpu->queue_props) 661 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); 662 err = vkGetPhysicalDeviceQueueFamilyProperties(gpu->obj, &gpu->queue_count, gpu->queue_props); 663 if (err) 664 ERR_EXIT(err); 665 666 /* set up queue requests */ 667 gpu->queue_reqs = malloc(sizeof(*gpu->queue_reqs) * gpu->queue_count); 668 if (!gpu->queue_reqs) 669 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); 670 for (i = 0; i < gpu->queue_count; i++) { 671 gpu->queue_reqs[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 672 gpu->queue_reqs[i].pNext = NULL; 673 gpu->queue_reqs[i].queueFamilyIndex = i; 674 gpu->queue_reqs[i].queueCount = gpu->queue_props[i].queueCount; 675 } 676 677 err = vkGetPhysicalDeviceMemoryProperties(gpu->obj, &gpu->memory_props); 678 if (err) 679 ERR_EXIT(err); 680 681 err = vkGetPhysicalDeviceFeatures(gpu->obj, &gpu->features); 682 if (err) 683 ERR_EXIT(err); 684 685 app_dev_init(&gpu->dev, gpu); 686 app_dev_init_formats(&gpu->dev); 687} 688 689static void app_gpu_destroy(struct app_gpu *gpu) 690{ 691 app_dev_destroy(&gpu->dev); 692 free(gpu->device_extensions); 693 free(gpu->queue_reqs); 694 free(gpu->queue_props); 695} 696 697static void app_dev_dump_format_props(const struct app_dev *dev, VkFormat fmt) 698{ 699 const VkFormatProperties *props = &dev->format_props[fmt]; 700 struct { 701 const char *name; 702 VkFlags flags; 703 } features[3]; 704 uint32_t i; 705 706 features[0].name = "linearTiling FormatFeatureFlags"; 707 features[0].flags = props->linearTilingFeatures; 708 features[1].name = "optimalTiling FormatFeatureFlags"; 709 features[1].flags = props->optimalTilingFeatures; 710 features[2].name = "bufferFeatures FormatFeatureFlags"; 711 features[2].flags = props->bufferFeatures; 712 713 printf("\nFORMAT_%s:", vk_format_string(fmt)); 714 for (i = 0; i < ARRAY_SIZE(features); i++) { 715 printf("\n\t%s:", features[i].name); 716 if (features[i].flags == 0) { 717 printf("\n\t\tNone"); 718 } else { 719 printf("%s%s%s%s%s%s%s%s%s%s%s%s", 720 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT" : ""), 721 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_BIT" : ""), 722 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT" : ""), 723 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT" : ""), 724 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT" : ""), 725 ((features[i].flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) ? "\n\t\tVK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT" : ""), 726 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_SOURCE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_SOURCE_BIT" : ""), 727 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_DESTINATION_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_DESTINATION_BIT" : ""), 728 ((features[i].flags & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT" : ""), 729 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT" : ""), 730 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT" : ""), 731 ((features[i].flags & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_VERTEX_BUFFER_BIT" : "")); 732 } 733 } 734 printf("\n"); 735} 736 737 738static void 739app_dev_dump(const struct app_dev *dev) 740{ 741 VkFormat fmt; 742 743 for (fmt = 0; fmt < VK_FORMAT_NUM; fmt++) { 744 app_dev_dump_format_props(dev, fmt); 745 } 746} 747 748#ifdef _WIN32 749#define PRINTF_SIZE_T_SPECIFIER "%Iu" 750#else 751#define PRINTF_SIZE_T_SPECIFIER "%zu" 752#endif 753 754static void app_gpu_dump_features(const struct app_gpu *gpu) 755{ 756 const VkPhysicalDeviceFeatures *features = &gpu->features; 757 758 printf("VkPhysicalDeviceFeatures:\n"); 759 printf("=========================\n"); 760 761 printf("\trobustBufferAccess = %u\n", features->robustBufferAccess ); 762 printf("\tfullDrawIndexUint32 = %u\n", features->fullDrawIndexUint32 ); 763 printf("\timageCubeArray = %u\n", features->imageCubeArray ); 764 printf("\tindependentBlend = %u\n", features->independentBlend ); 765 printf("\tgeometryShader = %u\n", features->geometryShader ); 766 printf("\ttessellationShader = %u\n", features->tessellationShader ); 767 printf("\tsampleRateShading = %u\n", features->sampleRateShading ); 768 printf("\tdualSourceBlend = %u\n", features->dualSourceBlend ); 769 printf("\tlogicOp = %u\n", features->logicOp ); 770 printf("\tmultiDrawIndirect = %u\n", features->multiDrawIndirect ); 771 printf("\tdepthClip = %u\n", features->depthClip ); 772 printf("\tdepthBiasClamp = %u\n", features->depthBiasClamp ); 773 printf("\tfillModeNonSolid = %u\n", features->fillModeNonSolid ); 774 printf("\tdepthBounds = %u\n", features->depthBounds ); 775 printf("\twideLines = %u\n", features->wideLines ); 776 printf("\tlargePoints = %u\n", features->largePoints ); 777 printf("\ttextureCompressionETC2 = %u\n", features->textureCompressionETC2 ); 778 printf("\ttextureCompressionASTC_LDR = %u\n", features->textureCompressionASTC_LDR ); 779 printf("\ttextureCompressionBC = %u\n", features->textureCompressionBC ); 780 printf("\tpipelineStatisticsQuery = %u\n", features->pipelineStatisticsQuery ); 781 printf("\tvertexSideEffects = %u\n", features->vertexSideEffects ); 782 printf("\ttessellationSideEffects = %u\n", features->tessellationSideEffects ); 783 printf("\tgeometrySideEffects = %u\n", features->geometrySideEffects ); 784 printf("\tfragmentSideEffects = %u\n", features->fragmentSideEffects ); 785 printf("\tshaderTessellationPointSize = %u\n", features->shaderTessellationPointSize ); 786 printf("\tshaderGeometryPointSize = %u\n", features->shaderGeometryPointSize ); 787 printf("\tshaderImageGatherExtended = %u\n", features->shaderImageGatherExtended ); 788 printf("\tshaderStorageImageExtendedFormats = %u\n", features->shaderStorageImageExtendedFormats ); 789 printf("\tshaderStorageImageMultisample = %u\n", features->shaderStorageImageMultisample ); 790 printf("\tshaderUniformBufferArrayDynamicIndexing = %u\n", features->shaderUniformBufferArrayDynamicIndexing); 791 printf("\tshaderSampledImageArrayDynamicIndexing = %u\n", features->shaderSampledImageArrayDynamicIndexing ); 792 printf("\tshaderStorageBufferArrayDynamicIndexing = %u\n", features->shaderStorageBufferArrayDynamicIndexing); 793 printf("\tshaderStorageImageArrayDynamicIndexing = %u\n", features->shaderStorageImageArrayDynamicIndexing ); 794 printf("\tshaderClipDistance = %u\n", features->shaderClipDistance ); 795 printf("\tshaderCullDistance = %u\n", features->shaderCullDistance ); 796 printf("\tshaderFloat64 = %u\n", features->shaderFloat64 ); 797 printf("\tshaderInt64 = %u\n", features->shaderInt64 ); 798 printf("\tshaderInt16 = %u\n", features->shaderInt16 ); 799 printf("\tshaderResourceResidency = %u\n", features->shaderResourceResidency ); 800 printf("\tshaderResourceMinLOD = %u\n", features->shaderResourceMinLOD ); 801 printf("\talphaToOne = %u\n", features->alphaToOne ); 802 printf("\tsparseBinding = %u\n", features->sparseBinding ); 803 printf("\tsparseResidencyBuffer = %u\n", features->sparseResidencyBuffer ); 804 printf("\tsparseResidencyImage2D = %u\n", features->sparseResidencyImage2D ); 805 printf("\tsparseResidencyImage3D = %u\n", features->sparseResidencyImage3D ); 806 printf("\tsparseResidency2Samples = %u\n", features->sparseResidency2Samples ); 807 printf("\tsparseResidency4Samples = %u\n", features->sparseResidency4Samples ); 808 printf("\tsparseResidency8Samples = %u\n", features->sparseResidency8Samples ); 809 printf("\tsparseResidency16Samples = %u\n", features->sparseResidency16Samples ); 810 printf("\tsparseResidencyAliased = %u\n", features->sparseResidencyAliased ); 811} 812 813static void app_dump_sparse_props(const VkPhysicalDeviceSparseProperties *sparseProps) 814{ 815 816 printf("\tVkPhysicalDeviceSparseProperties:\n"); 817 printf("\t---------------------------------\n"); 818 819 printf("\t\tresidencyStandard2DBlockShape = %u\n", sparseProps->residencyStandard2DBlockShape ); 820 printf("\t\tresidencyStandard2DMSBlockShape = %u\n", sparseProps->residencyStandard2DMSBlockShape ); 821 printf("\t\tresidencyStandard3DBlockShape = %u\n", sparseProps->residencyStandard3DBlockShape ); 822 printf("\t\tresidencyAlignedMipSize = %u\n", sparseProps->residencyAlignedMipSize ); 823 printf("\t\tresidencyNonResident = %u\n", sparseProps->residencyNonResident ); 824 printf("\t\tresidencyNonResidentStrict = %u\n", sparseProps->residencyNonResidentStrict ); 825} 826 827static void app_dump_limits(const VkPhysicalDeviceLimits *limits) 828{ 829 printf("\tVkPhysicalDeviceLimits:\n"); 830 printf("\t-----------------------\n"); 831 832 printf("\t\tmaxImageDimension1D = 0x%" PRIxLEAST32 "\n", limits->maxImageDimension1D ); 833 printf("\t\tmaxImageDimension2D = 0x%" PRIxLEAST32 "\n", limits->maxImageDimension2D ); 834 printf("\t\tmaxImageDimension3D = 0x%" PRIxLEAST32 "\n", limits->maxImageDimension3D ); 835 printf("\t\tmaxImageDimensionCube = 0x%" PRIxLEAST32 "\n", limits->maxImageDimensionCube ); 836 printf("\t\tmaxImageArrayLayers = 0x%" PRIxLEAST32 "\n", limits->maxImageArrayLayers ); 837 printf("\t\tmaxTexelBufferSize = 0x%" PRIxLEAST32 "\n", limits->maxTexelBufferSize ); 838 printf("\t\tmaxUniformBufferSize = 0x%" PRIxLEAST32 "\n", limits->maxUniformBufferSize ); 839 printf("\t\tmaxStorageBufferSize = 0x%" PRIxLEAST32 "\n", limits->maxStorageBufferSize ); 840 printf("\t\tmaxPushConstantsSize = 0x%" PRIxLEAST32 "\n", limits->maxPushConstantsSize ); 841 printf("\t\tmaxMemoryAllocationCount = 0x%" PRIxLEAST32 "\n", limits->maxMemoryAllocationCount ); 842 printf("\t\tbufferImageGranularity = 0x%" PRIxLEAST64 "\n", limits->bufferImageGranularity ); 843 printf("\t\tmaxBoundDescriptorSets = 0x%" PRIxLEAST32 "\n", limits->maxBoundDescriptorSets ); 844 printf("\t\tmaxDescriptorSets = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSets ); 845 printf("\t\tmaxPerStageDescriptorSamplers = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorSamplers ); 846 printf("\t\tmaxPerStageDescriptorUniformBuffers = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorUniformBuffers ); 847 printf("\t\tmaxPerStageDescriptorStorageBuffers = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorStorageBuffers ); 848 printf("\t\tmaxPerStageDescriptorSampledImages = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorSampledImages ); 849 printf("\t\tmaxPerStageDescriptorStorageImages = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorStorageImages ); 850 printf("\t\tmaxDescriptorSetSamplers = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetSamplers ); 851 printf("\t\tmaxDescriptorSetUniformBuffers = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetUniformBuffers ); 852 printf("\t\tmaxDescriptorSetStorageBuffers = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetStorageBuffers ); 853 printf("\t\tmaxDescriptorSetSampledImages = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetSampledImages ); 854 printf("\t\tmaxDescriptorSetStorageImages = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetStorageImages ); 855 printf("\t\tmaxVertexInputAttributes = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputAttributes ); 856 printf("\t\tmaxVertexInputAttributeOffset = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputAttributeOffset ); 857 printf("\t\tmaxVertexInputBindingStride = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputBindingStride ); 858 printf("\t\tmaxVertexOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxVertexOutputComponents ); 859 printf("\t\tmaxTessGenLevel = 0x%" PRIxLEAST32 "\n", limits->maxTessGenLevel ); 860 printf("\t\tmaxTessPatchSize = 0x%" PRIxLEAST32 "\n", limits->maxTessPatchSize ); 861 printf("\t\tmaxTessControlPerVertexInputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessControlPerVertexInputComponents ); 862 printf("\t\tmaxTessControlPerVertexOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessControlPerVertexOutputComponents); 863 printf("\t\tmaxTessControlPerPatchOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessControlPerPatchOutputComponents ); 864 printf("\t\tmaxTessControlTotalOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessControlTotalOutputComponents ); 865 printf("\t\tmaxTessEvaluationInputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessEvaluationInputComponents ); 866 printf("\t\tmaxTessEvaluationOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessEvaluationOutputComponents ); 867 printf("\t\tmaxGeometryShaderInvocations = 0x%" PRIxLEAST32 "\n", limits->maxGeometryShaderInvocations ); 868 printf("\t\tmaxGeometryInputComponents = 0x%" PRIxLEAST32 "\n", limits->maxGeometryInputComponents ); 869 printf("\t\tmaxGeometryOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxGeometryOutputComponents ); 870 printf("\t\tmaxGeometryOutputVertices = 0x%" PRIxLEAST32 "\n", limits->maxGeometryOutputVertices ); 871 printf("\t\tmaxGeometryTotalOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxGeometryTotalOutputComponents ); 872 printf("\t\tmaxFragmentInputComponents = 0x%" PRIxLEAST32 "\n", limits->maxFragmentInputComponents ); 873 printf("\t\tmaxFragmentOutputBuffers = 0x%" PRIxLEAST32 "\n", limits->maxFragmentOutputBuffers ); 874 printf("\t\tmaxFragmentDualSourceBuffers = 0x%" PRIxLEAST32 "\n", limits->maxFragmentDualSourceBuffers ); 875 printf("\t\tmaxFragmentCombinedOutputResources = 0x%" PRIxLEAST32 "\n", limits->maxFragmentCombinedOutputResources ); 876 printf("\t\tmaxComputeSharedMemorySize = 0x%" PRIxLEAST32 "\n", limits->maxComputeSharedMemorySize ); 877 printf("\t\tmaxComputeWorkGroupCount[0] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupCount[0] ); 878 printf("\t\tmaxComputeWorkGroupCount[1] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupCount[1] ); 879 printf("\t\tmaxComputeWorkGroupCount[2] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupCount[2] ); 880 printf("\t\tmaxComputeWorkGroupInvocations = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupInvocations ); 881 printf("\t\tmaxComputeWorkGroupSize[0] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupSize[0] ); 882 printf("\t\tmaxComputeWorkGroupSize[1] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupSize[1] ); 883 printf("\t\tmaxComputeWorkGroupSize[2] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupSize[2] ); 884 printf("\t\tsubPixelPrecisionBits = 0x%" PRIxLEAST32 "\n", limits->subPixelPrecisionBits ); 885 printf("\t\tsubTexelPrecisionBits = 0x%" PRIxLEAST32 "\n", limits->subTexelPrecisionBits ); 886 printf("\t\tmipmapPrecisionBits = 0x%" PRIxLEAST32 "\n", limits->mipmapPrecisionBits ); 887 printf("\t\tmaxDrawIndexedIndexValue = 0x%" PRIxLEAST32 "\n", limits->maxDrawIndexedIndexValue ); 888 printf("\t\tmaxDrawIndirectInstanceCount = 0x%" PRIxLEAST32 "\n", limits->maxDrawIndirectInstanceCount ); 889 printf("\t\tprimitiveRestartForPatches = 0x%" PRIxLEAST32 "\n", limits->primitiveRestartForPatches ); 890 printf("\t\tmaxSamplerLodBias = %f\n", limits->maxSamplerLodBias ); 891 printf("\t\tmaxSamplerAnisotropy = %f\n", limits->maxSamplerAnisotropy ); 892 printf("\t\tmaxViewports = 0x%" PRIxLEAST32 "\n", limits->maxViewports ); 893 printf("\t\tmaxViewportDimensions[0] = 0x%" PRIxLEAST32 "\n", limits->maxViewportDimensions[0] ); 894 printf("\t\tmaxViewportDimensions[1] = 0x%" PRIxLEAST32 "\n", limits->maxViewportDimensions[1] ); 895 printf("\t\tviewportBoundsRange[0] = %f\n", limits->viewportBoundsRange[0] ); 896 printf("\t\tviewportBoundsRange[1] = %f\n", limits->viewportBoundsRange[1] ); 897 printf("\t\tviewportSubPixelBits = 0x%" PRIxLEAST32 "\n", limits->viewportSubPixelBits ); 898 printf("\t\tminMemoryMapAlignment = 0x%" PRIxLEAST32 "\n", limits->minMemoryMapAlignment ); 899 printf("\t\tminTexelBufferOffsetAlignment = 0x%" PRIxLEAST32 "\n", limits->minTexelBufferOffsetAlignment ); 900 printf("\t\tminUniformBufferOffsetAlignment = 0x%" PRIxLEAST32 "\n", limits->minUniformBufferOffsetAlignment ); 901 printf("\t\tminStorageBufferOffsetAlignment = 0x%" PRIxLEAST32 "\n", limits->minStorageBufferOffsetAlignment ); 902 printf("\t\tminTexelOffset = 0x%" PRIxLEAST32 "\n", limits->minTexelOffset ); 903 printf("\t\tmaxTexelOffset = 0x%" PRIxLEAST32 "\n", limits->maxTexelOffset ); 904 printf("\t\tminTexelGatherOffset = 0x%" PRIxLEAST32 "\n", limits->minTexelGatherOffset ); 905 printf("\t\tmaxTexelGatherOffset = 0x%" PRIxLEAST32 "\n", limits->maxTexelGatherOffset ); 906 printf("\t\tminInterpolationOffset = %f\n", limits->minInterpolationOffset ); 907 printf("\t\tmaxInterpolationOffset = %f\n", limits->maxInterpolationOffset ); 908 printf("\t\tsubPixelInterpolationOffsetBits = 0x%" PRIxLEAST32 "\n", limits->subPixelInterpolationOffsetBits ); 909 printf("\t\tmaxFramebufferWidth = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferWidth ); 910 printf("\t\tmaxFramebufferHeight = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferHeight ); 911 printf("\t\tmaxFramebufferLayers = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferLayers ); 912 printf("\t\tmaxFramebufferColorSamples = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferColorSamples ); 913 printf("\t\tmaxFramebufferDepthSamples = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferDepthSamples ); 914 printf("\t\tmaxFramebufferStencilSamples = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferStencilSamples ); 915 printf("\t\tmaxColorAttachments = 0x%" PRIxLEAST32 "\n", limits->maxColorAttachments ); 916 printf("\t\tmaxSampledImageColorSamples = 0x%" PRIxLEAST32 "\n", limits->maxSampledImageColorSamples ); 917 printf("\t\tmaxSampledImageDepthSamples = 0x%" PRIxLEAST32 "\n", limits->maxSampledImageDepthSamples ); 918 printf("\t\tmaxSampledImageIntegerSamples = 0x%" PRIxLEAST32 "\n", limits->maxSampledImageIntegerSamples ); 919 printf("\t\tmaxStorageImageSamples = 0x%" PRIxLEAST32 "\n", limits->maxStorageImageSamples ); 920 printf("\t\tmaxSampleMaskWords = 0x%" PRIxLEAST32 "\n", limits->maxSampleMaskWords ); 921 printf("\t\ttimestampFrequency = 0x%" PRIxLEAST64 "\n", limits->timestampFrequency ); 922 printf("\t\tmaxClipDistances = 0x%" PRIxLEAST32 "\n", limits->maxClipDistances ); 923 printf("\t\tmaxCullDistances = 0x%" PRIxLEAST32 "\n", limits->maxCullDistances ); 924 printf("\t\tmaxCombinedClipAndCullDistances = 0x%" PRIxLEAST32 "\n", limits->maxCombinedClipAndCullDistances ); 925 printf("\t\tpointSizeRange[0] = %f\n", limits->pointSizeRange[0] ); 926 printf("\t\tpointSizeRange[1] = %f\n", limits->pointSizeRange[1] ); 927 printf("\t\tlineWidthRange[0] = %f\n", limits->lineWidthRange[0] ); 928 printf("\t\tlineWidthRange[1] = %f\n", limits->lineWidthRange[1] ); 929 printf("\t\tpointSizeGranularity = %f\n", limits->pointSizeGranularity ); 930 printf("\t\tlineWidthGranularity = %f\n", limits->lineWidthGranularity ); 931} 932 933static void app_gpu_dump_props(const struct app_gpu *gpu) 934{ 935 const VkPhysicalDeviceProperties *props = &gpu->props; 936 937 printf("VkPhysicalDeviceProperties:\n"); 938 printf("===========================\n"); 939 printf("\tapiVersion = %u\n", props->apiVersion); 940 printf("\tdriverVersion = %u\n", props->driverVersion); 941 printf("\tvendorId = 0x%04x\n", props->vendorId); 942 printf("\tdeviceId = 0x%04x\n", props->deviceId); 943 printf("\tdeviceType = %s\n", vk_physical_device_type_string(props->deviceType)); 944 printf("\tdeviceName = %s\n", props->deviceName); 945 946 app_dump_limits(&gpu->props.limits); 947 app_dump_sparse_props(&gpu->props.sparseProperties); 948 949 fflush(stdout); 950} 951 952static void app_dump_extensions( 953 const char *indent, 954 const char *layer_name, 955 const uint32_t extension_count, 956 const VkExtensionProperties *extension_properties) 957{ 958 uint32_t i; 959 if (layer_name && (strlen(layer_name) > 0)) { 960 printf("%s%s Extensions", indent, layer_name); 961 } else { 962 printf("Extensions"); 963 } 964 printf("\tcount = %d\n", extension_count); 965 for (i=0; i< extension_count; i++) { 966 VkExtensionProperties const *ext_prop = &extension_properties[i]; 967 968 if (i>0) 969 printf("\n"); // separator between extensions 970 971 printf("%s\t", indent); 972 printf("%-32s: extension revision %2d", 973 ext_prop->extName, ext_prop->specVersion); 974 } 975 printf("\n"); 976 fflush(stdout); 977} 978 979static void app_gpu_dump_queue_props(const struct app_gpu *gpu, uint32_t id) 980{ 981 const VkQueueFamilyProperties *props = &gpu->queue_props[id]; 982 983 printf("VkQueueFamilyProperties[%d]:\n", id); 984 printf("============================\n"); 985 printf("\tqueueFlags = %c%c%c%c\n", 986 (props->queueFlags & VK_QUEUE_GRAPHICS_BIT) ? 'G' : '.', 987 (props->queueFlags & VK_QUEUE_COMPUTE_BIT) ? 'C' : '.', 988 (props->queueFlags & VK_QUEUE_DMA_BIT) ? 'D' : '.', 989 (props->queueFlags & VK_QUEUE_EXTENDED_BIT) ? 'X' : '.'); 990 printf("\tqueueCount = %u\n", props->queueCount); 991 printf("\tsupportsTimestamps = %u\n", props->supportsTimestamps); 992 fflush(stdout); 993} 994 995static void app_gpu_dump_memory_props(const struct app_gpu *gpu) 996{ 997 const VkPhysicalDeviceMemoryProperties *props = &gpu->memory_props; 998 999 printf("VkPhysicalDeviceMemoryProperties:\n"); 1000 printf("=================================\n"); 1001 printf("\tmemoryTypeCount = %u\n", props->memoryTypeCount); 1002 for (uint32_t i = 0; i < props->memoryTypeCount; i++) { 1003 printf("\tmemoryTypes[%u] : \n", i); 1004 printf("\t\tpropertyFlags = %u\n", props->memoryTypes[i].propertyFlags); 1005 printf("\t\theapIndex = %u\n", props->memoryTypes[i].heapIndex); 1006 } 1007 printf("\tmemoryHeapCount = %u\n", props->memoryHeapCount); 1008 for (uint32_t i = 0; i < props->memoryHeapCount; i++) { 1009 printf("\tmemoryHeaps[%u] : \n", i); 1010 printf("\t\tsize = " PRINTF_SIZE_T_SPECIFIER "\n", props->memoryHeaps[i].size); 1011 } 1012 fflush(stdout); 1013} 1014 1015static void app_gpu_dump(const struct app_gpu *gpu) 1016{ 1017 uint32_t i; 1018 1019 printf("Device Extensions and layers:\n"); 1020 printf("=============================\n"); 1021 printf("GPU%u\n", gpu->id); 1022 app_gpu_dump_props(gpu); 1023 printf("\n"); 1024 app_dump_extensions("", "Device", gpu->device_extension_count, gpu->device_extensions); 1025 printf("\n"); 1026 printf("Layers\tcount = %d\n", gpu->device_layer_count); 1027 for (uint32_t i = 0; i < gpu->device_layer_count; i++) { 1028 uint32_t major, minor, patch; 1029 char spec_version[64], layer_version[64]; 1030 struct layer_extension_list const *layer_info = &gpu->device_layers[i]; 1031 1032 extract_version(layer_info->layer_properties.specVersion, &major, &minor, &patch); 1033 snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", major, minor, patch); 1034 extract_version(layer_info->layer_properties.implVersion, &major, &minor, &patch); 1035 snprintf(layer_version, sizeof(layer_version), "%d.%d.%d", major, minor, patch); 1036 printf("\t%s (%s) Vulkan version %s, layer version %s\n", 1037 layer_info->layer_properties.layerName, 1038 (char*) layer_info->layer_properties.description, 1039 spec_version, layer_version); 1040 1041 app_dump_extensions("\t", 1042 layer_info->layer_properties.layerName, 1043 layer_info->extension_count, 1044 layer_info->extension_properties); 1045 fflush(stdout); 1046 } 1047 printf("\n"); 1048 for (i = 0; i < gpu->queue_count; i++) { 1049 app_gpu_dump_queue_props(gpu, i); 1050 printf("\n"); 1051 } 1052 app_gpu_dump_memory_props(gpu); 1053 printf("\n"); 1054 app_gpu_dump_features(gpu); 1055 printf("\n"); 1056 app_dev_dump(&gpu->dev); 1057} 1058 1059int main(int argc, char **argv) 1060{ 1061 struct app_gpu gpus[MAX_GPUS]; 1062 VkPhysicalDevice objs[MAX_GPUS]; 1063 uint32_t gpu_count, i; 1064 VkResult err; 1065 struct app_instance inst; 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->implVersion, &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; 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; 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