vulkaninfo.c revision b21a51a4aae758d8b8f622eb7ca363bb7896cb00
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 .layerCount = 0, 394 .ppEnabledLayerNames = NULL, 395 .extensionCount = 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.layerCount = 0; 479 info.ppEnabledLayerNames = NULL; 480 info.extensionCount = 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 .layerCount = 0, 537 .ppEnabledLayerNames = NULL, 538 .extensionCount = 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.extensionCount = 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].queueCount = 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\tprimitiveRestartForPatches = 0x%" PRIxLEAST32 "\n", limits->primitiveRestartForPatches ); 885 printf("\t\tmaxSamplerLodBias = %f\n", limits->maxSamplerLodBias ); 886 printf("\t\tmaxSamplerAnisotropy = %f\n", limits->maxSamplerAnisotropy ); 887 printf("\t\tmaxViewports = 0x%" PRIxLEAST32 "\n", limits->maxViewports ); 888 printf("\t\tmaxViewportDimensions[0] = 0x%" PRIxLEAST32 "\n", limits->maxViewportDimensions[0] ); 889 printf("\t\tmaxViewportDimensions[1] = 0x%" PRIxLEAST32 "\n", limits->maxViewportDimensions[1] ); 890 printf("\t\tviewportBoundsRange[0] = %f\n", limits->viewportBoundsRange[0] ); 891 printf("\t\tviewportBoundsRange[1] = %f\n", limits->viewportBoundsRange[1] ); 892 printf("\t\tviewportSubPixelBits = 0x%" PRIxLEAST32 "\n", limits->viewportSubPixelBits ); 893 printf("\t\tminMemoryMapAlignment = 0x%" PRIxLEAST32 "\n", limits->minMemoryMapAlignment ); 894 printf("\t\tminTexelBufferOffsetAlignment = 0x%" PRIxLEAST32 "\n", limits->minTexelBufferOffsetAlignment ); 895 printf("\t\tminUniformBufferOffsetAlignment = 0x%" PRIxLEAST32 "\n", limits->minUniformBufferOffsetAlignment ); 896 printf("\t\tminStorageBufferOffsetAlignment = 0x%" PRIxLEAST32 "\n", limits->minStorageBufferOffsetAlignment ); 897 printf("\t\tminTexelOffset = 0x%" PRIxLEAST32 "\n", limits->minTexelOffset ); 898 printf("\t\tmaxTexelOffset = 0x%" PRIxLEAST32 "\n", limits->maxTexelOffset ); 899 printf("\t\tminTexelGatherOffset = 0x%" PRIxLEAST32 "\n", limits->minTexelGatherOffset ); 900 printf("\t\tmaxTexelGatherOffset = 0x%" PRIxLEAST32 "\n", limits->maxTexelGatherOffset ); 901 printf("\t\tminInterpolationOffset = %f\n", limits->minInterpolationOffset ); 902 printf("\t\tmaxInterpolationOffset = %f\n", limits->maxInterpolationOffset ); 903 printf("\t\tsubPixelInterpolationOffsetBits = 0x%" PRIxLEAST32 "\n", limits->subPixelInterpolationOffsetBits ); 904 printf("\t\tmaxFramebufferWidth = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferWidth ); 905 printf("\t\tmaxFramebufferHeight = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferHeight ); 906 printf("\t\tmaxFramebufferLayers = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferLayers ); 907 printf("\t\tmaxFramebufferColorSamples = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferColorSamples ); 908 printf("\t\tmaxFramebufferDepthSamples = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferDepthSamples ); 909 printf("\t\tmaxFramebufferStencilSamples = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferStencilSamples ); 910 printf("\t\tmaxColorAttachments = 0x%" PRIxLEAST32 "\n", limits->maxColorAttachments ); 911 printf("\t\tmaxSampledImageColorSamples = 0x%" PRIxLEAST32 "\n", limits->maxSampledImageColorSamples ); 912 printf("\t\tmaxSampledImageDepthSamples = 0x%" PRIxLEAST32 "\n", limits->maxSampledImageDepthSamples ); 913 printf("\t\tmaxSampledImageIntegerSamples = 0x%" PRIxLEAST32 "\n", limits->maxSampledImageIntegerSamples ); 914 printf("\t\tmaxStorageImageSamples = 0x%" PRIxLEAST32 "\n", limits->maxStorageImageSamples ); 915 printf("\t\tmaxSampleMaskWords = 0x%" PRIxLEAST32 "\n", limits->maxSampleMaskWords ); 916 printf("\t\ttimestampPeriod = 0x%f\n", limits->timestampPeriod ); 917 printf("\t\tmaxClipDistances = 0x%" PRIxLEAST32 "\n", limits->maxClipDistances ); 918 printf("\t\tmaxCullDistances = 0x%" PRIxLEAST32 "\n", limits->maxCullDistances ); 919 printf("\t\tmaxCombinedClipAndCullDistances = 0x%" PRIxLEAST32 "\n", limits->maxCombinedClipAndCullDistances ); 920 printf("\t\tpointSizeRange[0] = %f\n", limits->pointSizeRange[0] ); 921 printf("\t\tpointSizeRange[1] = %f\n", limits->pointSizeRange[1] ); 922 printf("\t\tlineWidthRange[0] = %f\n", limits->lineWidthRange[0] ); 923 printf("\t\tlineWidthRange[1] = %f\n", limits->lineWidthRange[1] ); 924 printf("\t\tpointSizeGranularity = %f\n", limits->pointSizeGranularity ); 925 printf("\t\tlineWidthGranularity = %f\n", limits->lineWidthGranularity ); 926 printf("\t\trecommendedBufferCopyOffsetAlignment = 0x%" PRIxLEAST32 "\n", limits->recommendedBufferCopyOffsetAlignment ); 927 printf("\t\trecommendedBufferCopyRowPitchAlignment = 0x%" PRIxLEAST32 "\n", limits->recommendedBufferCopyRowPitchAlignment ); 928} 929 930static void app_gpu_dump_props(const struct app_gpu *gpu) 931{ 932 const VkPhysicalDeviceProperties *props = &gpu->props; 933 934 printf("VkPhysicalDeviceProperties:\n"); 935 printf("===========================\n"); 936 printf("\tapiVersion = %u\n", props->apiVersion); 937 printf("\tdriverVersion = %u\n", props->driverVersion); 938 printf("\tvendorId = 0x%04x\n", props->vendorId); 939 printf("\tdeviceId = 0x%04x\n", props->deviceId); 940 printf("\tdeviceType = %s\n", vk_physical_device_type_string(props->deviceType)); 941 printf("\tdeviceName = %s\n", props->deviceName); 942 943 app_dump_limits(&gpu->props.limits); 944 app_dump_sparse_props(&gpu->props.sparseProperties); 945 946 fflush(stdout); 947} 948 949static void app_dump_extensions( 950 const char *indent, 951 const char *layer_name, 952 const uint32_t extension_count, 953 const VkExtensionProperties *extension_properties) 954{ 955 uint32_t i; 956 if (layer_name && (strlen(layer_name) > 0)) { 957 printf("%s%s Extensions", indent, layer_name); 958 } else { 959 printf("Extensions"); 960 } 961 printf("\tcount = %d\n", extension_count); 962 for (i=0; i< extension_count; i++) { 963 VkExtensionProperties const *ext_prop = &extension_properties[i]; 964 965 if (i>0) 966 printf("\n"); // separator between extensions 967 968 printf("%s\t", indent); 969 printf("%-32s: extension revision %2d", 970 ext_prop->extName, ext_prop->specVersion); 971 } 972 printf("\n"); 973 fflush(stdout); 974} 975 976static void app_gpu_dump_queue_props(const struct app_gpu *gpu, uint32_t id) 977{ 978 const VkQueueFamilyProperties *props = &gpu->queue_props[id]; 979 980 printf("VkQueueFamilyProperties[%d]:\n", id); 981 printf("============================\n"); 982 printf("\tqueueFlags = %c%c%c\n", 983 (props->queueFlags & VK_QUEUE_GRAPHICS_BIT) ? 'G' : '.', 984 (props->queueFlags & VK_QUEUE_COMPUTE_BIT) ? 'C' : '.', 985 (props->queueFlags & VK_QUEUE_DMA_BIT) ? 'D' : '.'); 986 printf("\tqueueCount = %u\n", props->queueCount); 987 printf("\ttimestampValidBits = %u\n", props->timestampValidBits); 988 fflush(stdout); 989} 990 991static void app_gpu_dump_memory_props(const struct app_gpu *gpu) 992{ 993 const VkPhysicalDeviceMemoryProperties *props = &gpu->memory_props; 994 995 printf("VkPhysicalDeviceMemoryProperties:\n"); 996 printf("=================================\n"); 997 printf("\tmemoryTypeCount = %u\n", props->memoryTypeCount); 998 for (uint32_t i = 0; i < props->memoryTypeCount; i++) { 999 printf("\tmemoryTypes[%u] : \n", i); 1000 printf("\t\tpropertyFlags = %u\n", props->memoryTypes[i].propertyFlags); 1001 printf("\t\theapIndex = %u\n", props->memoryTypes[i].heapIndex); 1002 } 1003 printf("\tmemoryHeapCount = %u\n", props->memoryHeapCount); 1004 for (uint32_t i = 0; i < props->memoryHeapCount; i++) { 1005 printf("\tmemoryHeaps[%u] : \n", i); 1006 printf("\t\tsize = " PRINTF_SIZE_T_SPECIFIER "\n", props->memoryHeaps[i].size); 1007 } 1008 fflush(stdout); 1009} 1010 1011static void app_gpu_dump(const struct app_gpu *gpu) 1012{ 1013 uint32_t i; 1014 1015 printf("Device Extensions and layers:\n"); 1016 printf("=============================\n"); 1017 printf("GPU%u\n", gpu->id); 1018 app_gpu_dump_props(gpu); 1019 printf("\n"); 1020 app_dump_extensions("", "Device", gpu->device_extension_count, gpu->device_extensions); 1021 printf("\n"); 1022 printf("Layers\tcount = %d\n", gpu->device_layer_count); 1023 for (uint32_t i = 0; i < gpu->device_layer_count; i++) { 1024 uint32_t major, minor, patch; 1025 char spec_version[64], layer_version[64]; 1026 struct layer_extension_list const *layer_info = &gpu->device_layers[i]; 1027 1028 extract_version(layer_info->layer_properties.specVersion, &major, &minor, &patch); 1029 snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", major, minor, patch); 1030 extract_version(layer_info->layer_properties.implVersion, &major, &minor, &patch); 1031 snprintf(layer_version, sizeof(layer_version), "%d.%d.%d", major, minor, patch); 1032 printf("\t%s (%s) Vulkan version %s, layer version %s\n", 1033 layer_info->layer_properties.layerName, 1034 (char*) layer_info->layer_properties.description, 1035 spec_version, layer_version); 1036 1037 app_dump_extensions("\t", 1038 layer_info->layer_properties.layerName, 1039 layer_info->extension_count, 1040 layer_info->extension_properties); 1041 fflush(stdout); 1042 } 1043 printf("\n"); 1044 for (i = 0; i < gpu->queue_count; i++) { 1045 app_gpu_dump_queue_props(gpu, i); 1046 printf("\n"); 1047 } 1048 app_gpu_dump_memory_props(gpu); 1049 printf("\n"); 1050 app_gpu_dump_features(gpu); 1051 printf("\n"); 1052 app_dev_dump(&gpu->dev); 1053} 1054 1055int main(int argc, char **argv) 1056{ 1057 unsigned int major, minor, patch; 1058 struct app_gpu gpus[MAX_GPUS]; 1059 VkPhysicalDevice objs[MAX_GPUS]; 1060 uint32_t gpu_count, i; 1061 VkResult err; 1062 struct app_instance inst; 1063 1064 major = VK_API_VERSION >> 22; 1065 minor = (VK_API_VERSION >> 12) & 0x4ff; 1066 patch = VK_API_VERSION & 0xfff; 1067 printf("===========\n"); 1068 printf("VULKAN INFO\n"); 1069 printf("===========\n\n"); 1070 printf("Vulkan API Version: %d %d %d\n\n", major, minor, patch); 1071 1072 app_create_instance(&inst); 1073 1074 printf("Instance Extensions and layers:\n"); 1075 printf("===============================\n"); 1076 app_dump_extensions("", "Instance", inst.global_extension_count, inst.global_extensions); 1077 1078 printf("Instance Layers\tcount = %d\n", inst.global_layer_count); 1079 for (uint32_t i = 0; i < inst.global_layer_count; i++) { 1080 uint32_t major, minor, patch; 1081 char spec_version[64], layer_version[64]; 1082 VkLayerProperties const *layer_prop = &inst.global_layers[i].layer_properties; 1083 1084 extract_version(layer_prop->specVersion, &major, &minor, &patch); 1085 snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", major, minor, patch); 1086 extract_version(layer_prop->implVersion, &major, &minor, &patch); 1087 snprintf(layer_version, sizeof(layer_version), "%d.%d.%d", major, minor, patch); 1088 printf("\t%s (%s) Vulkan version %s, layer version %s\n", 1089 layer_prop->layerName, (char*) layer_prop->description, spec_version, layer_version); 1090 1091 app_dump_extensions("\t", 1092 inst.global_layers[i].layer_properties.layerName, 1093 inst.global_layers[i].extension_count, 1094 inst.global_layers[i].extension_properties); 1095 } 1096 1097 err = vkEnumeratePhysicalDevices(inst.instance, &gpu_count, NULL); 1098 if (err) 1099 ERR_EXIT(err); 1100 if (gpu_count > MAX_GPUS) { 1101 printf("Too many GPUS found \n"); 1102 ERR_EXIT(-1); 1103 } 1104 err = vkEnumeratePhysicalDevices(inst.instance, &gpu_count, objs); 1105 if (err) 1106 ERR_EXIT(err); 1107 1108 for (i = 0; i < gpu_count; i++) { 1109 app_gpu_init(&gpus[i], i, objs[i]); 1110 app_gpu_dump(&gpus[i]); 1111 printf("\n\n"); 1112 } 1113 1114 for (i = 0; i < gpu_count; i++) 1115 app_gpu_destroy(&gpus[i]); 1116 1117 app_destroy_instance(&inst); 1118 1119 return 0; 1120} 1121 1122#ifdef _WIN32 1123 1124// Create a console window with a large scrollback size to which to send stdout. 1125// Returns true if console window was successfully created, false otherwise. 1126bool SetStdOutToNewConsole() 1127{ 1128 // don't do anything if we already have a console 1129 if (GetStdHandle(STD_OUTPUT_HANDLE)) 1130 return false; 1131 1132 // allocate a console for this app 1133 AllocConsole(); 1134 1135 // redirect unbuffered STDOUT to the console 1136 HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); 1137 int fileDescriptor = _open_osfhandle((intptr_t)consoleHandle, _O_TEXT); 1138 FILE *fp = _fdopen( fileDescriptor, "w" ); 1139 *stdout = *fp; 1140 setvbuf( stdout, NULL, _IONBF, 0 ); 1141 1142 // make the console window bigger 1143 CONSOLE_SCREEN_BUFFER_INFO csbi; 1144 SMALL_RECT r; 1145 COORD bufferSize; 1146 if (!GetConsoleScreenBufferInfo(consoleHandle, &csbi)) 1147 return false; 1148 bufferSize.X = csbi.dwSize.X+30; 1149 bufferSize.Y = 20000; 1150 if (!SetConsoleScreenBufferSize(consoleHandle, bufferSize)) 1151 return false; 1152 r.Left = r.Top = 0; 1153 r.Right = csbi.dwSize.X-1+30; 1154 r.Bottom = 50; 1155 if (!SetConsoleWindowInfo(consoleHandle, true, &r)) 1156 return false; 1157 1158 // change the console window title 1159 if (!SetConsoleTitle(TEXT(APP_SHORT_NAME))) 1160 return false; 1161 1162 return true; 1163} 1164 1165int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nCmdShow) 1166{ 1167 char *argv = pCmdLine; 1168 consoleCreated = SetStdOutToNewConsole(); 1169 main(1, &argv); 1170 fflush(stdout); 1171 if (consoleCreated) 1172 Sleep(INFINITE); 1173} 1174#endif 1175