vulkaninfo.c revision 763a749795bb4827efbbf19cbc87b959511496dd
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_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_NUM; 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->extName)) { 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, &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); 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 .pAppName = APP_SHORT_NAME, 526 .appVersion = 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 .pAppInfo = &app_info, 535 .pAllocCb = NULL, 536 .enabledLayerNameCount = 0, 537 .ppEnabledLayerNames = NULL, 538 .enabledExtensionNameCount = 0, 539 .ppEnabledExtensionNames = NULL, 540 }; 541 VkResult U_ASSERT_ONLY err; 542 // Global Extensions to enable 543 static char *known_extensions[] = { 544 "VK_EXT_KHR_swapchain", 545 }; 546 547 uint32_t global_extension_count = 0; 548 uint32_t count = 0; 549 550 /* Scan layers */ 551 VkLayerProperties *global_layer_properties = NULL; 552 struct layer_extension_list *global_layers = NULL; 553 554 do { 555 err = vkEnumerateInstanceLayerProperties(&count, NULL); 556 assert(!err); 557 558 if (global_layer_properties) { 559 free(global_layer_properties); 560 } 561 global_layer_properties = malloc(sizeof(VkLayerProperties) * count); 562 assert(global_layer_properties); 563 564 if (global_layers) { 565 free(global_layers); 566 } 567 global_layers = malloc(sizeof(struct layer_extension_list) * count); 568 assert(global_layers); 569 570 err = vkEnumerateInstanceLayerProperties(&count, global_layer_properties); 571 } while (err == VK_INCOMPLETE); 572 assert(!err); 573 574 inst->global_layer_count = count; 575 inst->global_layers = global_layers; 576 577 for (uint32_t i = 0; i < inst->global_layer_count; i++) { 578 VkLayerProperties *src_info = &global_layer_properties[i]; 579 struct layer_extension_list *dst_info = &inst->global_layers[i]; 580 memcpy(&dst_info->layer_properties, src_info, sizeof(VkLayerProperties)); 581 582 /* Save away layer extension info for report */ 583 app_get_global_layer_extensions( 584 src_info->layerName, 585 &dst_info->extension_count, 586 &dst_info->extension_properties); 587 } 588 free(global_layer_properties); 589 590 /* Collect global extensions */ 591 inst->global_extension_count = 0; 592 app_get_global_layer_extensions( 593 NULL, 594 &inst->global_extension_count, 595 &inst->global_extensions); 596 597 for (uint32_t i = 0; i < ARRAY_SIZE(known_extensions); i++) { 598 VkBool32 extension_found = 0; 599 for (uint32_t j = 0; j < inst->global_extension_count; j++) { 600 VkExtensionProperties *extension_prop = &inst->global_extensions[j]; 601 if (!strcmp(known_extensions[i], extension_prop->extName)) { 602 603 extension_found = 1; 604 global_extension_count++; 605 } 606 } 607 if (!extension_found) { 608 printf("Cannot find extension: %s\n", known_extensions[i]); 609 ERR_EXIT(VK_ERROR_EXTENSION_NOT_PRESENT); 610 } 611 } 612 613 inst_info.enabledExtensionNameCount = global_extension_count; 614 inst_info.ppEnabledExtensionNames = (const char * const *) known_extensions; 615 616 err = vkCreateInstance(&inst_info, &inst->instance); 617 if (err == VK_ERROR_INCOMPATIBLE_DRIVER) { 618 printf("Cannot create Vulkan instance.\n"); 619 ERR_EXIT(err); 620 } else if (err) { 621 ERR_EXIT(err); 622 } 623} 624 625static void app_destroy_instance(struct app_instance *inst) 626{ 627 free(inst->global_extensions); 628 vkDestroyInstance(inst->instance); 629} 630 631 632static void app_gpu_init(struct app_gpu *gpu, uint32_t id, VkPhysicalDevice obj) 633{ 634 uint32_t i; 635 636 memset(gpu, 0, sizeof(*gpu)); 637 638 gpu->id = id; 639 gpu->obj = obj; 640 641 vkGetPhysicalDeviceProperties(gpu->obj, &gpu->props); 642 643 /* get queue count */ 644 vkGetPhysicalDeviceQueueFamilyProperties(gpu->obj, &gpu->queue_count, NULL); 645 646 gpu->queue_props = 647 malloc(sizeof(gpu->queue_props[0]) * gpu->queue_count); 648 649 if (!gpu->queue_props) 650 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); 651 vkGetPhysicalDeviceQueueFamilyProperties(gpu->obj, &gpu->queue_count, gpu->queue_props); 652 653 /* set up queue requests */ 654 gpu->queue_reqs = malloc(sizeof(*gpu->queue_reqs) * gpu->queue_count); 655 if (!gpu->queue_reqs) 656 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); 657 for (i = 0; i < gpu->queue_count; i++) { 658 float *queue_priorities = malloc(gpu->queue_props[i].queueCount * sizeof(float)); 659 memset(queue_priorities, 0, gpu->queue_props[i].queueCount * sizeof(float)); 660 gpu->queue_reqs[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 661 gpu->queue_reqs[i].pNext = NULL; 662 gpu->queue_reqs[i].queueFamilyIndex = i; 663 gpu->queue_reqs[i].queuePriorityCount = gpu->queue_props[i].queueCount; 664 gpu->queue_reqs[i].pQueuePriorities = queue_priorities; 665 } 666 667 vkGetPhysicalDeviceMemoryProperties(gpu->obj, &gpu->memory_props); 668 669 vkGetPhysicalDeviceFeatures(gpu->obj, &gpu->features); 670 671 app_dev_init(&gpu->dev, gpu); 672 app_dev_init_formats(&gpu->dev); 673} 674 675static void app_gpu_destroy(struct app_gpu *gpu) 676{ 677 app_dev_destroy(&gpu->dev); 678 free(gpu->device_extensions); 679 free(gpu->queue_reqs); 680 for (uint32_t i = 0; i < gpu->queue_count; i++) { 681 free((void *) gpu->queue_reqs[i].pQueuePriorities); 682 } 683 free(gpu->queue_props); 684} 685 686static void app_dev_dump_format_props(const struct app_dev *dev, VkFormat fmt) 687{ 688 const VkFormatProperties *props = &dev->format_props[fmt]; 689 struct { 690 const char *name; 691 VkFlags flags; 692 } features[3]; 693 uint32_t i; 694 695 features[0].name = "linearTiling FormatFeatureFlags"; 696 features[0].flags = props->linearTilingFeatures; 697 features[1].name = "optimalTiling FormatFeatureFlags"; 698 features[1].flags = props->optimalTilingFeatures; 699 features[2].name = "bufferFeatures FormatFeatureFlags"; 700 features[2].flags = props->bufferFeatures; 701 702 printf("\nFORMAT_%s:", vk_format_string(fmt)); 703 for (i = 0; i < ARRAY_SIZE(features); i++) { 704 printf("\n\t%s:", features[i].name); 705 if (features[i].flags == 0) { 706 printf("\n\t\tNone"); 707 } else { 708 printf("%s%s%s%s%s%s%s%s%s%s%s%s", 709 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT" : ""), 710 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_BIT" : ""), 711 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT" : ""), 712 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT" : ""), 713 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT" : ""), 714 ((features[i].flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) ? "\n\t\tVK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT" : ""), 715 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_SOURCE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_SOURCE_BIT" : ""), 716 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_DESTINATION_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_DESTINATION_BIT" : ""), 717 ((features[i].flags & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT" : ""), 718 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT" : ""), 719 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT" : ""), 720 ((features[i].flags & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_VERTEX_BUFFER_BIT" : "")); 721 } 722 } 723 printf("\n"); 724} 725 726 727static void 728app_dev_dump(const struct app_dev *dev) 729{ 730 VkFormat fmt; 731 732 for (fmt = 0; fmt < VK_FORMAT_NUM; fmt++) { 733 app_dev_dump_format_props(dev, fmt); 734 } 735} 736 737#ifdef _WIN32 738#define PRINTF_SIZE_T_SPECIFIER "%Iu" 739#else 740#define PRINTF_SIZE_T_SPECIFIER "%zu" 741#endif 742 743static void app_gpu_dump_features(const struct app_gpu *gpu) 744{ 745 const VkPhysicalDeviceFeatures *features = &gpu->features; 746 747 printf("VkPhysicalDeviceFeatures:\n"); 748 printf("=========================\n"); 749 750 printf("\trobustBufferAccess = %u\n", features->robustBufferAccess ); 751 printf("\tfullDrawIndexUint32 = %u\n", features->fullDrawIndexUint32 ); 752 printf("\timageCubeArray = %u\n", features->imageCubeArray ); 753 printf("\tindependentBlend = %u\n", features->independentBlend ); 754 printf("\tgeometryShader = %u\n", features->geometryShader ); 755 printf("\ttessellationShader = %u\n", features->tessellationShader ); 756 printf("\tsampleRateShading = %u\n", features->sampleRateShading ); 757 printf("\tdualSourceBlend = %u\n", features->dualSourceBlend ); 758 printf("\tlogicOp = %u\n", features->logicOp ); 759 printf("\tmultiDrawIndirect = %u\n", features->multiDrawIndirect ); 760 printf("\tdepthClip = %u\n", features->depthClamp ); 761 printf("\tdepthBiasClamp = %u\n", features->depthBiasClamp ); 762 printf("\tfillModeNonSolid = %u\n", features->fillModeNonSolid ); 763 printf("\tdepthBounds = %u\n", features->depthBounds ); 764 printf("\twideLines = %u\n", features->wideLines ); 765 printf("\tstrictLines = %u\n", features->strictLines ); 766 printf("\tlargePoints = %u\n", features->largePoints ); 767 printf("\ttextureCompressionETC2 = %u\n", features->textureCompressionETC2 ); 768 printf("\ttextureCompressionASTC_LDR = %u\n", features->textureCompressionASTC_LDR ); 769 printf("\ttextureCompressionBC = %u\n", features->textureCompressionBC ); 770 printf("\tocclusionQueryNonConservative = %u\n", features->occlusionQueryNonConservative ); 771 printf("\tpipelineStatisticsQuery = %u\n", features->pipelineStatisticsQuery ); 772 printf("\tvertexSideEffects = %u\n", features->vertexSideEffects ); 773 printf("\ttessellationSideEffects = %u\n", features->tessellationSideEffects ); 774 printf("\tgeometrySideEffects = %u\n", features->geometrySideEffects ); 775 printf("\tfragmentSideEffects = %u\n", features->fragmentSideEffects ); 776 printf("\tshaderTessellationPointSize = %u\n", features->shaderTessellationPointSize ); 777 printf("\tshaderGeometryPointSize = %u\n", features->shaderGeometryPointSize ); 778 printf("\tshaderImageGatherExtended = %u\n", features->shaderImageGatherExtended ); 779 printf("\tshaderStorageImageExtendedFormats = %u\n", features->shaderStorageImageExtendedFormats ); 780 printf("\tshaderStorageImageMultisample = %u\n", features->shaderStorageImageMultisample ); 781 printf("\tshaderUniformBufferArrayDynamicIndexing = %u\n", features->shaderUniformBufferArrayDynamicIndexing); 782 printf("\tshaderSampledImageArrayDynamicIndexing = %u\n", features->shaderSampledImageArrayDynamicIndexing ); 783 printf("\tshaderStorageBufferArrayDynamicIndexing = %u\n", features->shaderStorageBufferArrayDynamicIndexing); 784 printf("\tshaderStorageImageArrayDynamicIndexing = %u\n", features->shaderStorageImageArrayDynamicIndexing ); 785 printf("\tshaderClipDistance = %u\n", features->shaderClipDistance ); 786 printf("\tshaderCullDistance = %u\n", features->shaderCullDistance ); 787 printf("\tshaderFloat64 = %u\n", features->shaderFloat64 ); 788 printf("\tshaderInt64 = %u\n", features->shaderInt64 ); 789 printf("\tshaderInt16 = %u\n", features->shaderInt16 ); 790 printf("\tshaderResourceResidency = %u\n", features->shaderResourceResidency ); 791 printf("\tshaderResourceMinLOD = %u\n", features->shaderResourceMinLOD ); 792 printf("\talphaToOne = %u\n", features->alphaToOne ); 793 printf("\tsparseBinding = %u\n", features->sparseBinding ); 794 printf("\tsparseResidencyBuffer = %u\n", features->sparseResidencyBuffer ); 795 printf("\tsparseResidencyImage2D = %u\n", features->sparseResidencyImage2D ); 796 printf("\tsparseResidencyImage3D = %u\n", features->sparseResidencyImage3D ); 797 printf("\tsparseResidency2Samples = %u\n", features->sparseResidency2Samples ); 798 printf("\tsparseResidency4Samples = %u\n", features->sparseResidency4Samples ); 799 printf("\tsparseResidency8Samples = %u\n", features->sparseResidency8Samples ); 800 printf("\tsparseResidency16Samples = %u\n", features->sparseResidency16Samples ); 801 printf("\tsparseResidencyAliased = %u\n", features->sparseResidencyAliased ); 802} 803 804static void app_dump_sparse_props(const VkPhysicalDeviceSparseProperties *sparseProps) 805{ 806 807 printf("\tVkPhysicalDeviceSparseProperties:\n"); 808 printf("\t---------------------------------\n"); 809 810 printf("\t\tresidencyStandard2DBlockShape = %u\n", sparseProps->residencyStandard2DBlockShape ); 811 printf("\t\tresidencyStandard2DMSBlockShape = %u\n", sparseProps->residencyStandard2DMSBlockShape ); 812 printf("\t\tresidencyStandard3DBlockShape = %u\n", sparseProps->residencyStandard3DBlockShape ); 813 printf("\t\tresidencyAlignedMipSize = %u\n", sparseProps->residencyAlignedMipSize ); 814 printf("\t\tresidencyNonResident = %u\n", sparseProps->residencyNonResident ); 815 printf("\t\tresidencyNonResidentStrict = %u\n", sparseProps->residencyNonResidentStrict ); 816} 817 818static void app_dump_limits(const VkPhysicalDeviceLimits *limits) 819{ 820 printf("\tVkPhysicalDeviceLimits:\n"); 821 printf("\t-----------------------\n"); 822 823 printf("\t\tmaxImageDimension1D = 0x%" PRIxLEAST32 "\n", limits->maxImageDimension1D ); 824 printf("\t\tmaxImageDimension2D = 0x%" PRIxLEAST32 "\n", limits->maxImageDimension2D ); 825 printf("\t\tmaxImageDimension3D = 0x%" PRIxLEAST32 "\n", limits->maxImageDimension3D ); 826 printf("\t\tmaxImageDimensionCube = 0x%" PRIxLEAST32 "\n", limits->maxImageDimensionCube ); 827 printf("\t\tmaxImageArrayLayers = 0x%" PRIxLEAST32 "\n", limits->maxImageArrayLayers ); 828 printf("\t\tsampleCounts = 0x%" PRIxLEAST32 "\n", limits->sampleCounts ); 829 printf("\t\tmaxTexelBufferSize = 0x%" PRIxLEAST32 "\n", limits->maxTexelBufferSize ); 830 printf("\t\tmaxUniformBufferRange = 0x%" PRIxLEAST32 "\n", limits->maxUniformBufferRange ); 831 printf("\t\tmaxStorageBufferRange = 0x%" PRIxLEAST32 "\n", limits->maxStorageBufferRange ); 832 printf("\t\tmaxPushConstantsSize = 0x%" PRIxLEAST32 "\n", limits->maxPushConstantsSize ); 833 printf("\t\tmaxMemoryAllocationCount = 0x%" PRIxLEAST32 "\n", limits->maxMemoryAllocationCount ); 834 printf("\t\tbufferImageGranularity = 0x%" PRIxLEAST64 "\n", limits->bufferImageGranularity ); 835 printf("\t\tsparseAddressSpaceSize = 0x%" PRIxLEAST64 "\n", limits->sparseAddressSpaceSize ); 836 printf("\t\tmaxBoundDescriptorSets = 0x%" PRIxLEAST32 "\n", limits->maxBoundDescriptorSets ); 837 printf("\t\tmaxPerStageDescriptorSamplers = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorSamplers ); 838 printf("\t\tmaxPerStageDescriptorUniformBuffers = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorUniformBuffers ); 839 printf("\t\tmaxPerStageDescriptorStorageBuffers = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorStorageBuffers ); 840 printf("\t\tmaxPerStageDescriptorSampledImages = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorSampledImages ); 841 printf("\t\tmaxPerStageDescriptorStorageImages = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorStorageImages ); 842 printf("\t\tmaxDescriptorSetSamplers = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetSamplers ); 843 printf("\t\tmaxDescriptorSetUniformBuffers = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetUniformBuffers ); 844 printf("\t\tmaxDescriptorSetUniformBuffersDynamic = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetUniformBuffersDynamic ); 845 printf("\t\tmaxDescriptorSetStorageBuffers = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetStorageBuffers ); 846 printf("\t\tmaxDescriptorSetStorageBuffersDynamic = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetStorageBuffersDynamic ); 847 printf("\t\tmaxDescriptorSetSampledImages = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetSampledImages ); 848 printf("\t\tmaxDescriptorSetStorageImages = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetStorageImages ); 849 printf("\t\tmaxVertexInputAttributes = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputAttributes ); 850 printf("\t\tmaxVertexInputBindings = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputBindings ); 851 printf("\t\tmaxVertexInputAttributeOffset = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputAttributeOffset ); 852 printf("\t\tmaxVertexInputBindingStride = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputBindingStride ); 853 printf("\t\tmaxVertexOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxVertexOutputComponents ); 854 printf("\t\tmaxTessellationGenLevel = 0x%" PRIxLEAST32 "\n", limits->maxTessellationGenLevel ); 855 printf("\t\tmaxTessellationPatchSize = 0x%" PRIxLEAST32 "\n", limits->maxTessellationPatchSize ); 856 printf("\t\tmaxTessellationControlPerVertexInputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessellationControlPerVertexInputComponents ); 857 printf("\t\tmaxTessellationControlPerVertexOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessellationControlPerVertexOutputComponents); 858 printf("\t\tmaxTessellationControlPerPatchOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessellationControlPerPatchOutputComponents ); 859 printf("\t\tmaxTessellationControlTotalOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessellationControlTotalOutputComponents ); 860 printf("\t\tmaxTessellationEvaluationInputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessellationEvaluationInputComponents ); 861 printf("\t\tmaxTessellationEvaluationOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessellationEvaluationOutputComponents ); 862 printf("\t\tmaxGeometryShaderInvocations = 0x%" PRIxLEAST32 "\n", limits->maxGeometryShaderInvocations ); 863 printf("\t\tmaxGeometryInputComponents = 0x%" PRIxLEAST32 "\n", limits->maxGeometryInputComponents ); 864 printf("\t\tmaxGeometryOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxGeometryOutputComponents ); 865 printf("\t\tmaxGeometryOutputVertices = 0x%" PRIxLEAST32 "\n", limits->maxGeometryOutputVertices ); 866 printf("\t\tmaxGeometryTotalOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxGeometryTotalOutputComponents ); 867 printf("\t\tmaxFragmentInputComponents = 0x%" PRIxLEAST32 "\n", limits->maxFragmentInputComponents ); 868 printf("\t\tmaxFragmentOutputAttachments = 0x%" PRIxLEAST32 "\n", limits->maxFragmentOutputAttachments ); 869 printf("\t\tmaxFragmentDualSourceAttachments = 0x%" PRIxLEAST32 "\n", limits->maxFragmentDualSourceAttachments ); 870 printf("\t\tmaxFragmentCombinedOutputResources = 0x%" PRIxLEAST32 "\n", limits->maxFragmentCombinedOutputResources ); 871 printf("\t\tmaxComputeSharedMemorySize = 0x%" PRIxLEAST32 "\n", limits->maxComputeSharedMemorySize ); 872 printf("\t\tmaxComputeWorkGroupCount[0] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupCount[0] ); 873 printf("\t\tmaxComputeWorkGroupCount[1] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupCount[1] ); 874 printf("\t\tmaxComputeWorkGroupCount[2] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupCount[2] ); 875 printf("\t\tmaxComputeWorkGroupInvocations = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupInvocations ); 876 printf("\t\tmaxComputeWorkGroupSize[0] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupSize[0] ); 877 printf("\t\tmaxComputeWorkGroupSize[1] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupSize[1] ); 878 printf("\t\tmaxComputeWorkGroupSize[2] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupSize[2] ); 879 printf("\t\tsubPixelPrecisionBits = 0x%" PRIxLEAST32 "\n", limits->subPixelPrecisionBits ); 880 printf("\t\tsubTexelPrecisionBits = 0x%" PRIxLEAST32 "\n", limits->subTexelPrecisionBits ); 881 printf("\t\tmipmapPrecisionBits = 0x%" PRIxLEAST32 "\n", limits->mipmapPrecisionBits ); 882 printf("\t\tmaxDrawIndexedIndexValue = 0x%" PRIxLEAST32 "\n", limits->maxDrawIndexedIndexValue ); 883 printf("\t\tmaxDrawIndirectInstanceCount = 0x%" PRIxLEAST32 "\n", limits->maxDrawIndirectInstanceCount ); 884 printf("\t\tmaxSamplerLodBias = %f\n", limits->maxSamplerLodBias ); 885 printf("\t\tmaxSamplerAnisotropy = %f\n", limits->maxSamplerAnisotropy ); 886 printf("\t\tmaxViewports = 0x%" PRIxLEAST32 "\n", limits->maxViewports ); 887 printf("\t\tmaxViewportDimensions[0] = 0x%" PRIxLEAST32 "\n", limits->maxViewportDimensions[0] ); 888 printf("\t\tmaxViewportDimensions[1] = 0x%" PRIxLEAST32 "\n", limits->maxViewportDimensions[1] ); 889 printf("\t\tviewportBoundsRange[0] = %f\n", limits->viewportBoundsRange[0] ); 890 printf("\t\tviewportBoundsRange[1] = %f\n", limits->viewportBoundsRange[1] ); 891 printf("\t\tviewportSubPixelBits = 0x%" PRIxLEAST32 "\n", limits->viewportSubPixelBits ); 892 printf("\t\tminMemoryMapAlignment = 0x%" PRIxLEAST32 "\n", limits->minMemoryMapAlignment ); 893 printf("\t\tminTexelBufferOffsetAlignment = 0x%" PRIxLEAST32 "\n", limits->minTexelBufferOffsetAlignment ); 894 printf("\t\tminUniformBufferOffsetAlignment = 0x%" PRIxLEAST32 "\n", limits->minUniformBufferOffsetAlignment ); 895 printf("\t\tminStorageBufferOffsetAlignment = 0x%" PRIxLEAST32 "\n", limits->minStorageBufferOffsetAlignment ); 896 printf("\t\tminTexelOffset = 0x%" PRIxLEAST32 "\n", limits->minTexelOffset ); 897 printf("\t\tmaxTexelOffset = 0x%" PRIxLEAST32 "\n", limits->maxTexelOffset ); 898 printf("\t\tminTexelGatherOffset = 0x%" PRIxLEAST32 "\n", limits->minTexelGatherOffset ); 899 printf("\t\tmaxTexelGatherOffset = 0x%" PRIxLEAST32 "\n", limits->maxTexelGatherOffset ); 900 printf("\t\tminInterpolationOffset = %f\n", limits->minInterpolationOffset ); 901 printf("\t\tmaxInterpolationOffset = %f\n", limits->maxInterpolationOffset ); 902 printf("\t\tsubPixelInterpolationOffsetBits = 0x%" PRIxLEAST32 "\n", limits->subPixelInterpolationOffsetBits ); 903 printf("\t\tmaxFramebufferWidth = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferWidth ); 904 printf("\t\tmaxFramebufferHeight = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferHeight ); 905 printf("\t\tmaxFramebufferLayers = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferLayers ); 906 printf("\t\tmaxFramebufferColorSamples = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferColorSamples ); 907 printf("\t\tmaxFramebufferDepthSamples = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferDepthSamples ); 908 printf("\t\tmaxFramebufferStencilSamples = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferStencilSamples ); 909 printf("\t\tmaxColorAttachments = 0x%" PRIxLEAST32 "\n", limits->maxColorAttachments ); 910 printf("\t\tmaxSampledImageColorSamples = 0x%" PRIxLEAST32 "\n", limits->maxSampledImageColorSamples ); 911 printf("\t\tmaxSampledImageDepthSamples = 0x%" PRIxLEAST32 "\n", limits->maxSampledImageDepthSamples ); 912 printf("\t\tmaxSampledImageIntegerSamples = 0x%" PRIxLEAST32 "\n", limits->maxSampledImageIntegerSamples ); 913 printf("\t\tmaxStorageImageSamples = 0x%" PRIxLEAST32 "\n", limits->maxStorageImageSamples ); 914 printf("\t\tmaxSampleMaskWords = 0x%" PRIxLEAST32 "\n", limits->maxSampleMaskWords ); 915 printf("\t\ttimestampPeriod = 0x%f\n", limits->timestampPeriod ); 916 printf("\t\tmaxClipDistances = 0x%" PRIxLEAST32 "\n", limits->maxClipDistances ); 917 printf("\t\tmaxCullDistances = 0x%" PRIxLEAST32 "\n", limits->maxCullDistances ); 918 printf("\t\tmaxCombinedClipAndCullDistances = 0x%" PRIxLEAST32 "\n", limits->maxCombinedClipAndCullDistances ); 919 printf("\t\tpointSizeRange[0] = %f\n", limits->pointSizeRange[0] ); 920 printf("\t\tpointSizeRange[1] = %f\n", limits->pointSizeRange[1] ); 921 printf("\t\tlineWidthRange[0] = %f\n", limits->lineWidthRange[0] ); 922 printf("\t\tlineWidthRange[1] = %f\n", limits->lineWidthRange[1] ); 923 printf("\t\tpointSizeGranularity = %f\n", limits->pointSizeGranularity ); 924 printf("\t\tlineWidthGranularity = %f\n", limits->lineWidthGranularity ); 925 printf("\t\trecommendedBufferCopyOffsetAlignment = 0x%" PRIxLEAST32 "\n", limits->recommendedBufferCopyOffsetAlignment ); 926 printf("\t\trecommendedBufferCopyRowPitchAlignment = 0x%" PRIxLEAST32 "\n", limits->recommendedBufferCopyRowPitchAlignment ); 927} 928 929static void app_gpu_dump_props(const struct app_gpu *gpu) 930{ 931 const VkPhysicalDeviceProperties *props = &gpu->props; 932 933 printf("VkPhysicalDeviceProperties:\n"); 934 printf("===========================\n"); 935 printf("\tapiVersion = %u\n", props->apiVersion); 936 printf("\tdriverVersion = %u\n", props->driverVersion); 937 printf("\tvendorId = 0x%04x\n", props->vendorId); 938 printf("\tdeviceId = 0x%04x\n", props->deviceId); 939 printf("\tdeviceType = %s\n", vk_physical_device_type_string(props->deviceType)); 940 printf("\tdeviceName = %s\n", props->deviceName); 941 942 app_dump_limits(&gpu->props.limits); 943 app_dump_sparse_props(&gpu->props.sparseProperties); 944 945 fflush(stdout); 946} 947 948static void app_dump_extensions( 949 const char *indent, 950 const char *layer_name, 951 const uint32_t extension_count, 952 const VkExtensionProperties *extension_properties) 953{ 954 uint32_t i; 955 if (layer_name && (strlen(layer_name) > 0)) { 956 printf("%s%s Extensions", indent, layer_name); 957 } else { 958 printf("Extensions"); 959 } 960 printf("\tcount = %d\n", extension_count); 961 for (i=0; i< extension_count; i++) { 962 VkExtensionProperties const *ext_prop = &extension_properties[i]; 963 964 if (i>0) 965 printf("\n"); // separator between extensions 966 967 printf("%s\t", indent); 968 printf("%-32s: extension revision %2d", 969 ext_prop->extName, ext_prop->specVersion); 970 } 971 printf("\n"); 972 fflush(stdout); 973} 974 975static void app_gpu_dump_queue_props(const struct app_gpu *gpu, uint32_t id) 976{ 977 const VkQueueFamilyProperties *props = &gpu->queue_props[id]; 978 979 printf("VkQueueFamilyProperties[%d]:\n", id); 980 printf("============================\n"); 981 printf("\tqueueFlags = %c%c%c\n", 982 (props->queueFlags & VK_QUEUE_GRAPHICS_BIT) ? 'G' : '.', 983 (props->queueFlags & VK_QUEUE_COMPUTE_BIT) ? 'C' : '.', 984 (props->queueFlags & VK_QUEUE_DMA_BIT) ? 'D' : '.'); 985 printf("\tqueueCount = %u\n", props->queueCount); 986 printf("\ttimestampValidBits = %u\n", props->timestampValidBits); 987 fflush(stdout); 988} 989 990static void app_gpu_dump_memory_props(const struct app_gpu *gpu) 991{ 992 const VkPhysicalDeviceMemoryProperties *props = &gpu->memory_props; 993 994 printf("VkPhysicalDeviceMemoryProperties:\n"); 995 printf("=================================\n"); 996 printf("\tmemoryTypeCount = %u\n", props->memoryTypeCount); 997 for (uint32_t i = 0; i < props->memoryTypeCount; i++) { 998 printf("\tmemoryTypes[%u] : \n", i); 999 printf("\t\tpropertyFlags = %u\n", props->memoryTypes[i].propertyFlags); 1000 printf("\t\theapIndex = %u\n", props->memoryTypes[i].heapIndex); 1001 } 1002 printf("\tmemoryHeapCount = %u\n", props->memoryHeapCount); 1003 for (uint32_t i = 0; i < props->memoryHeapCount; i++) { 1004 printf("\tmemoryHeaps[%u] : \n", i); 1005 printf("\t\tsize = " PRINTF_SIZE_T_SPECIFIER "\n", props->memoryHeaps[i].size); 1006 } 1007 fflush(stdout); 1008} 1009 1010static void app_gpu_dump(const struct app_gpu *gpu) 1011{ 1012 uint32_t i; 1013 1014 printf("Device Extensions and layers:\n"); 1015 printf("=============================\n"); 1016 printf("GPU%u\n", gpu->id); 1017 app_gpu_dump_props(gpu); 1018 printf("\n"); 1019 app_dump_extensions("", "Device", gpu->device_extension_count, gpu->device_extensions); 1020 printf("\n"); 1021 printf("Layers\tcount = %d\n", gpu->device_layer_count); 1022 for (uint32_t i = 0; i < gpu->device_layer_count; i++) { 1023 uint32_t major, minor, patch; 1024 char spec_version[64], layer_version[64]; 1025 struct layer_extension_list const *layer_info = &gpu->device_layers[i]; 1026 1027 extract_version(layer_info->layer_properties.specVersion, &major, &minor, &patch); 1028 snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", major, minor, patch); 1029 extract_version(layer_info->layer_properties.implVersion, &major, &minor, &patch); 1030 snprintf(layer_version, sizeof(layer_version), "%d.%d.%d", major, minor, patch); 1031 printf("\t%s (%s) Vulkan version %s, layer version %s\n", 1032 layer_info->layer_properties.layerName, 1033 (char*) layer_info->layer_properties.description, 1034 spec_version, layer_version); 1035 1036 app_dump_extensions("\t", 1037 layer_info->layer_properties.layerName, 1038 layer_info->extension_count, 1039 layer_info->extension_properties); 1040 fflush(stdout); 1041 } 1042 printf("\n"); 1043 for (i = 0; i < gpu->queue_count; i++) { 1044 app_gpu_dump_queue_props(gpu, i); 1045 printf("\n"); 1046 } 1047 app_gpu_dump_memory_props(gpu); 1048 printf("\n"); 1049 app_gpu_dump_features(gpu); 1050 printf("\n"); 1051 app_dev_dump(&gpu->dev); 1052} 1053 1054int main(int argc, char **argv) 1055{ 1056 unsigned int major, minor, patch; 1057 struct app_gpu gpus[MAX_GPUS]; 1058 VkPhysicalDevice objs[MAX_GPUS]; 1059 uint32_t gpu_count, i; 1060 VkResult err; 1061 struct app_instance inst; 1062 1063 major = VK_API_VERSION >> 22; 1064 minor = (VK_API_VERSION >> 12) & 0x4ff; 1065 patch = VK_API_VERSION & 0xfff; 1066 printf("===========\n"); 1067 printf("VULKAN INFO\n"); 1068 printf("===========\n\n"); 1069 printf("Vulkan API Version: %d %d %d\n\n", major, minor, patch); 1070 1071 app_create_instance(&inst); 1072 1073 printf("Instance Extensions and layers:\n"); 1074 printf("===============================\n"); 1075 app_dump_extensions("", "Instance", inst.global_extension_count, inst.global_extensions); 1076 1077 printf("Instance Layers\tcount = %d\n", inst.global_layer_count); 1078 for (uint32_t i = 0; i < inst.global_layer_count; i++) { 1079 uint32_t major, minor, patch; 1080 char spec_version[64], layer_version[64]; 1081 VkLayerProperties const *layer_prop = &inst.global_layers[i].layer_properties; 1082 1083 extract_version(layer_prop->specVersion, &major, &minor, &patch); 1084 snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", major, minor, patch); 1085 extract_version(layer_prop->implVersion, &major, &minor, &patch); 1086 snprintf(layer_version, sizeof(layer_version), "%d.%d.%d", major, minor, patch); 1087 printf("\t%s (%s) Vulkan version %s, layer version %s\n", 1088 layer_prop->layerName, (char*) layer_prop->description, spec_version, layer_version); 1089 1090 app_dump_extensions("\t", 1091 inst.global_layers[i].layer_properties.layerName, 1092 inst.global_layers[i].extension_count, 1093 inst.global_layers[i].extension_properties); 1094 } 1095 1096 err = vkEnumeratePhysicalDevices(inst.instance, &gpu_count, NULL); 1097 if (err) 1098 ERR_EXIT(err); 1099 if (gpu_count > MAX_GPUS) { 1100 printf("Too many GPUS found \n"); 1101 ERR_EXIT(-1); 1102 } 1103 err = vkEnumeratePhysicalDevices(inst.instance, &gpu_count, objs); 1104 if (err) 1105 ERR_EXIT(err); 1106 1107 for (i = 0; i < gpu_count; i++) { 1108 app_gpu_init(&gpus[i], i, objs[i]); 1109 app_gpu_dump(&gpus[i]); 1110 printf("\n\n"); 1111 } 1112 1113 for (i = 0; i < gpu_count; i++) 1114 app_gpu_destroy(&gpus[i]); 1115 1116 app_destroy_instance(&inst); 1117 1118 return 0; 1119} 1120 1121#ifdef _WIN32 1122 1123// Create a console window with a large scrollback size to which to send stdout. 1124// Returns true if console window was successfully created, false otherwise. 1125bool SetStdOutToNewConsole() 1126{ 1127 // don't do anything if we already have a console 1128 if (GetStdHandle(STD_OUTPUT_HANDLE)) 1129 return false; 1130 1131 // allocate a console for this app 1132 AllocConsole(); 1133 1134 // redirect unbuffered STDOUT to the console 1135 HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); 1136 int fileDescriptor = _open_osfhandle((intptr_t)consoleHandle, _O_TEXT); 1137 FILE *fp = _fdopen( fileDescriptor, "w" ); 1138 *stdout = *fp; 1139 setvbuf( stdout, NULL, _IONBF, 0 ); 1140 1141 // make the console window bigger 1142 CONSOLE_SCREEN_BUFFER_INFO csbi; 1143 SMALL_RECT r; 1144 COORD bufferSize; 1145 if (!GetConsoleScreenBufferInfo(consoleHandle, &csbi)) 1146 return false; 1147 bufferSize.X = csbi.dwSize.X+30; 1148 bufferSize.Y = 20000; 1149 if (!SetConsoleScreenBufferSize(consoleHandle, bufferSize)) 1150 return false; 1151 r.Left = r.Top = 0; 1152 r.Right = csbi.dwSize.X-1+30; 1153 r.Bottom = 50; 1154 if (!SetConsoleWindowInfo(consoleHandle, true, &r)) 1155 return false; 1156 1157 // change the console window title 1158 if (!SetConsoleTitle(TEXT(APP_SHORT_NAME))) 1159 return false; 1160 1161 return true; 1162} 1163 1164int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nCmdShow) 1165{ 1166 char *argv = pCmdLine; 1167 consoleCreated = SetStdOutToNewConsole(); 1168 main(1, &argv); 1169 fflush(stdout); 1170 if (consoleCreated) 1171 Sleep(INFINITE); 1172} 1173#endif 1174