vulkaninfo.c revision fef7f0877d971c6e3467591da1128c8909fa2ced
1/* 2 * 3 * Copyright (C) 2015 Valve Corporation 4 * Copyright (C) 2015 Google 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 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com> 25 * Author: David Pinedo <david@lunarg.com> 26 * Author: Mark Lobodzinski <mark@lunarg.com> 27 */ 28#include <stdlib.h> 29#include <stdio.h> 30#include <stdbool.h> 31#include <string.h> 32#include <assert.h> 33#include <inttypes.h> 34 35#ifdef _WIN32 36#include <fcntl.h> 37#include <io.h> 38#endif // _WIN32 39 40 41#include <vulkan/vulkan.h> 42#include <vulkan/vk_ext_debug_report.h> 43 44#define ERR(err) printf("%s:%d: failed with %s\n", \ 45 __FILE__, __LINE__, vk_result_string(err)); 46 47#ifdef _WIN32 48 49#define snprintf _snprintf 50 51bool consoleCreated = false; 52 53#define WAIT_FOR_CONSOLE_DESTROY \ 54 do { \ 55 if (consoleCreated) \ 56 Sleep(INFINITE); \ 57 } while (0) 58#else 59 #define WAIT_FOR_CONSOLE_DESTROY 60#endif 61 62 63#define ERR_EXIT(err) \ 64 do { \ 65 ERR(err); \ 66 fflush(stdout); \ 67 WAIT_FOR_CONSOLE_DESTROY; \ 68 exit(-1); \ 69 } while (0) 70 71#if defined(NDEBUG) && defined(__GNUC__) 72#define U_ASSERT_ONLY __attribute__((unused)) 73#else 74#define U_ASSERT_ONLY 75#endif 76 77#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 78 79#define MAX_GPUS 8 80 81#define MAX_QUEUE_TYPES 5 82#define APP_SHORT_NAME "vulkaninfo" 83 84struct app_gpu; 85 86struct app_dev { 87 struct app_gpu *gpu; /* point back to the GPU */ 88 89 VkDevice obj; 90 91 92 VkFormatProperties format_props[VK_FORMAT_RANGE_SIZE]; 93}; 94 95struct layer_extension_list { 96 VkLayerProperties layer_properties; 97 uint32_t extension_count; 98 VkExtensionProperties *extension_properties; 99}; 100 101struct app_instance { 102 VkInstance instance; 103 uint32_t global_layer_count; 104 struct layer_extension_list *global_layers; 105 uint32_t global_extension_count; 106 VkExtensionProperties *global_extensions; 107}; 108 109struct app_gpu { 110 uint32_t id; 111 VkPhysicalDevice obj; 112 113 VkPhysicalDeviceProperties props; 114 115 uint32_t queue_count; 116 VkQueueFamilyProperties *queue_props; 117 VkDeviceQueueCreateInfo *queue_reqs; 118 119 VkPhysicalDeviceMemoryProperties memory_props; 120 VkPhysicalDeviceFeatures features; 121 VkPhysicalDevice limits; 122 123 uint32_t device_layer_count; 124 struct layer_extension_list *device_layers; 125 126 uint32_t device_extension_count; 127 VkExtensionProperties *device_extensions; 128 129 struct app_dev dev; 130}; 131 132VkBool32 dbg_callback( 133 VkFlags msgFlags, 134 VkDebugReportObjectTypeEXT objType, 135 uint64_t srcObject, 136 size_t location, 137 int32_t msgCode, 138 const char* pLayerPrefix, 139 const char* pMsg, 140 const void* pUserData) 141{ 142 char *message = (char *) malloc(strlen(pMsg)+100); 143 144 assert (message); 145 146 if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { 147 sprintf(message,"ERROR: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg); 148 } else if (msgFlags & VK_DEBUG_REPORT_WARN_BIT_EXT) { 149 sprintf(message,"WARNING: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg); 150 } else if (msgFlags & VK_DEBUG_REPORT_INFO_BIT_EXT) { 151 sprintf(message,"INFO: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg); 152 } else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) { 153 sprintf(message,"DEBUG: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg); 154 } 155 156#ifdef _WIN32 157 MessageBox(NULL, message, "Alert", MB_OK); 158#else 159 printf("%s\n",message); 160 fflush(stdout); 161#endif 162 free(message); 163 164 /* 165 * false indicates that layer should not bail-out of an 166 * API call that had validation failures. This may mean that the 167 * app dies inside the driver due to invalid parameter(s). 168 * That's what would happen without validation layers, so we'll 169 * keep that behavior here. 170 */ 171 return false; 172} 173 174static const char *vk_result_string(VkResult err) 175{ 176 switch (err) { 177#define STR(r) case r: return #r 178 STR(VK_SUCCESS); 179 STR(VK_NOT_READY); 180 STR(VK_TIMEOUT); 181 STR(VK_EVENT_SET); 182 STR(VK_EVENT_RESET); 183 STR(VK_ERROR_INITIALIZATION_FAILED); 184 STR(VK_ERROR_OUT_OF_HOST_MEMORY); 185 STR(VK_ERROR_OUT_OF_DEVICE_MEMORY); 186 STR(VK_ERROR_DEVICE_LOST); 187 STR(VK_ERROR_LAYER_NOT_PRESENT); 188 STR(VK_ERROR_EXTENSION_NOT_PRESENT); 189 STR(VK_ERROR_MEMORY_MAP_FAILED); 190 STR(VK_ERROR_INCOMPATIBLE_DRIVER); 191#undef STR 192 default: return "UNKNOWN_RESULT"; 193 } 194} 195 196static const char *vk_physical_device_type_string(VkPhysicalDeviceType type) 197{ 198 switch (type) { 199#define STR(r) case VK_PHYSICAL_DEVICE_TYPE_ ##r: return #r 200 STR(OTHER); 201 STR(INTEGRATED_GPU); 202 STR(DISCRETE_GPU); 203 STR(VIRTUAL_GPU); 204#undef STR 205 default: return "UNKNOWN_DEVICE"; 206 } 207} 208 209static const char *vk_format_string(VkFormat fmt) 210{ 211 switch (fmt) { 212#define STR(r) case VK_FORMAT_ ##r: return #r 213 STR(UNDEFINED); 214 STR(R4G4_UNORM_PACK8); 215 STR(R4G4B4A4_UNORM_PACK16); 216 STR(B4G4R4A4_UNORM_PACK16); 217 STR(R5G6B5_UNORM_PACK16); 218 STR(B5G6R5_UNORM_PACK16); 219 STR(R5G5B5A1_UNORM_PACK16); 220 STR(B5G5R5A1_UNORM_PACK16); 221 STR(A1R5G5B5_UNORM_PACK16); 222 STR(R8_UNORM); 223 STR(R8_SNORM); 224 STR(R8_USCALED); 225 STR(R8_SSCALED); 226 STR(R8_UINT); 227 STR(R8_SINT); 228 STR(R8_SRGB); 229 STR(R8G8_UNORM); 230 STR(R8G8_SNORM); 231 STR(R8G8_USCALED); 232 STR(R8G8_SSCALED); 233 STR(R8G8_UINT); 234 STR(R8G8_SINT); 235 STR(R8G8_SRGB); 236 STR(R8G8B8_UNORM); 237 STR(R8G8B8_SNORM); 238 STR(R8G8B8_USCALED); 239 STR(R8G8B8_SSCALED); 240 STR(R8G8B8_UINT); 241 STR(R8G8B8_SINT); 242 STR(R8G8B8_SRGB); 243 STR(B8G8R8_UNORM); 244 STR(B8G8R8_SNORM); 245 STR(B8G8R8_USCALED); 246 STR(B8G8R8_SSCALED); 247 STR(B8G8R8_UINT); 248 STR(B8G8R8_SINT); 249 STR(B8G8R8_SRGB); 250 STR(R8G8B8A8_UNORM); 251 STR(R8G8B8A8_SNORM); 252 STR(R8G8B8A8_USCALED); 253 STR(R8G8B8A8_SSCALED); 254 STR(R8G8B8A8_UINT); 255 STR(R8G8B8A8_SINT); 256 STR(R8G8B8A8_SRGB); 257 STR(B8G8R8A8_UNORM); 258 STR(B8G8R8A8_SNORM); 259 STR(B8G8R8A8_USCALED); 260 STR(B8G8R8A8_SSCALED); 261 STR(B8G8R8A8_UINT); 262 STR(B8G8R8A8_SINT); 263 STR(B8G8R8A8_SRGB); 264 STR(A8B8G8R8_UNORM_PACK32); 265 STR(A8B8G8R8_SNORM_PACK32); 266 STR(A8B8G8R8_USCALED_PACK32); 267 STR(A8B8G8R8_SSCALED_PACK32); 268 STR(A8B8G8R8_UINT_PACK32); 269 STR(A8B8G8R8_SINT_PACK32); 270 STR(A8B8G8R8_SRGB_PACK32); 271 STR(A2R10G10B10_UNORM_PACK32); 272 STR(A2R10G10B10_SNORM_PACK32); 273 STR(A2R10G10B10_USCALED_PACK32); 274 STR(A2R10G10B10_SSCALED_PACK32); 275 STR(A2R10G10B10_UINT_PACK32); 276 STR(A2R10G10B10_SINT_PACK32); 277 STR(A2B10G10R10_UNORM_PACK32); 278 STR(A2B10G10R10_SNORM_PACK32); 279 STR(A2B10G10R10_USCALED_PACK32); 280 STR(A2B10G10R10_SSCALED_PACK32); 281 STR(A2B10G10R10_UINT_PACK32); 282 STR(A2B10G10R10_SINT_PACK32); 283 STR(R16_UNORM); 284 STR(R16_SNORM); 285 STR(R16_USCALED); 286 STR(R16_SSCALED); 287 STR(R16_UINT); 288 STR(R16_SINT); 289 STR(R16_SFLOAT); 290 STR(R16G16_UNORM); 291 STR(R16G16_SNORM); 292 STR(R16G16_USCALED); 293 STR(R16G16_SSCALED); 294 STR(R16G16_UINT); 295 STR(R16G16_SINT); 296 STR(R16G16_SFLOAT); 297 STR(R16G16B16_UNORM); 298 STR(R16G16B16_SNORM); 299 STR(R16G16B16_USCALED); 300 STR(R16G16B16_SSCALED); 301 STR(R16G16B16_UINT); 302 STR(R16G16B16_SINT); 303 STR(R16G16B16_SFLOAT); 304 STR(R16G16B16A16_UNORM); 305 STR(R16G16B16A16_SNORM); 306 STR(R16G16B16A16_USCALED); 307 STR(R16G16B16A16_SSCALED); 308 STR(R16G16B16A16_UINT); 309 STR(R16G16B16A16_SINT); 310 STR(R16G16B16A16_SFLOAT); 311 STR(R32_UINT); 312 STR(R32_SINT); 313 STR(R32_SFLOAT); 314 STR(R32G32_UINT); 315 STR(R32G32_SINT); 316 STR(R32G32_SFLOAT); 317 STR(R32G32B32_UINT); 318 STR(R32G32B32_SINT); 319 STR(R32G32B32_SFLOAT); 320 STR(R32G32B32A32_UINT); 321 STR(R32G32B32A32_SINT); 322 STR(R32G32B32A32_SFLOAT); 323 STR(R64_UINT); 324 STR(R64_SINT); 325 STR(R64_SFLOAT); 326 STR(R64G64_UINT); 327 STR(R64G64_SINT); 328 STR(R64G64_SFLOAT); 329 STR(R64G64B64_UINT); 330 STR(R64G64B64_SINT); 331 STR(R64G64B64_SFLOAT); 332 STR(R64G64B64A64_UINT); 333 STR(R64G64B64A64_SINT); 334 STR(R64G64B64A64_SFLOAT); 335 STR(B10G11R11_UFLOAT_PACK32); 336 STR(E5B9G9R9_UFLOAT_PACK32); 337 STR(D16_UNORM); 338 STR(X8_D24_UNORM_PACK32); 339 STR(D32_SFLOAT); 340 STR(S8_UINT); 341 STR(D16_UNORM_S8_UINT); 342 STR(D24_UNORM_S8_UINT); 343 STR(D32_SFLOAT_S8_UINT); 344 STR(BC1_RGB_UNORM_BLOCK); 345 STR(BC1_RGB_SRGB_BLOCK); 346 STR(BC2_UNORM_BLOCK); 347 STR(BC2_SRGB_BLOCK); 348 STR(BC3_UNORM_BLOCK); 349 STR(BC3_SRGB_BLOCK); 350 STR(BC4_UNORM_BLOCK); 351 STR(BC4_SNORM_BLOCK); 352 STR(BC5_UNORM_BLOCK); 353 STR(BC5_SNORM_BLOCK); 354 STR(BC6H_UFLOAT_BLOCK); 355 STR(BC6H_SFLOAT_BLOCK); 356 STR(BC7_UNORM_BLOCK); 357 STR(BC7_SRGB_BLOCK); 358 STR(ETC2_R8G8B8_UNORM_BLOCK); 359 STR(ETC2_R8G8B8A1_UNORM_BLOCK); 360 STR(ETC2_R8G8B8A8_UNORM_BLOCK); 361 STR(EAC_R11_UNORM_BLOCK); 362 STR(EAC_R11_SNORM_BLOCK); 363 STR(EAC_R11G11_UNORM_BLOCK); 364 STR(EAC_R11G11_SNORM_BLOCK); 365 STR(ASTC_4x4_UNORM_BLOCK); 366 STR(ASTC_4x4_SRGB_BLOCK); 367 STR(ASTC_5x4_UNORM_BLOCK); 368 STR(ASTC_5x4_SRGB_BLOCK); 369 STR(ASTC_5x5_UNORM_BLOCK); 370 STR(ASTC_5x5_SRGB_BLOCK); 371 STR(ASTC_6x5_UNORM_BLOCK); 372 STR(ASTC_6x5_SRGB_BLOCK); 373 STR(ASTC_6x6_UNORM_BLOCK); 374 STR(ASTC_6x6_SRGB_BLOCK); 375 STR(ASTC_8x5_UNORM_BLOCK); 376 STR(ASTC_8x5_SRGB_BLOCK); 377 STR(ASTC_8x6_UNORM_BLOCK); 378 STR(ASTC_8x6_SRGB_BLOCK); 379 STR(ASTC_8x8_UNORM_BLOCK); 380 STR(ASTC_8x8_SRGB_BLOCK); 381 STR(ASTC_10x5_UNORM_BLOCK); 382 STR(ASTC_10x5_SRGB_BLOCK); 383 STR(ASTC_10x6_UNORM_BLOCK); 384 STR(ASTC_10x6_SRGB_BLOCK); 385 STR(ASTC_10x8_UNORM_BLOCK); 386 STR(ASTC_10x8_SRGB_BLOCK); 387 STR(ASTC_10x10_UNORM_BLOCK); 388 STR(ASTC_10x10_SRGB_BLOCK); 389 STR(ASTC_12x10_UNORM_BLOCK); 390 STR(ASTC_12x10_SRGB_BLOCK); 391 STR(ASTC_12x12_UNORM_BLOCK); 392 STR(ASTC_12x12_SRGB_BLOCK); 393#undef STR 394 default: return "UNKNOWN_FORMAT"; 395 } 396} 397 398static void app_dev_init_formats(struct app_dev *dev) 399{ 400 VkFormat f; 401 402 for (f = 0; f < VK_FORMAT_RANGE_SIZE; f++) { 403 const VkFormat fmt = f; 404 405 vkGetPhysicalDeviceFormatProperties(dev->gpu->obj, fmt, &dev->format_props[f]); 406 } 407} 408 409static void extract_version(uint32_t version, uint32_t *major, uint32_t *minor, uint32_t *patch) 410{ 411 *major = version >> 22; 412 *minor = (version >> 12) & 0x3ff; 413 *patch = version & 0xfff; 414} 415 416static void app_get_physical_device_layer_extensions( 417 struct app_gpu *gpu, 418 char *layer_name, 419 uint32_t *extension_count, 420 VkExtensionProperties **extension_properties) 421{ 422 VkResult err; 423 uint32_t ext_count = 0; 424 VkExtensionProperties *ext_ptr = NULL; 425 426 /* repeat get until VK_INCOMPLETE goes away */ 427 do { 428 err = vkEnumerateDeviceExtensionProperties(gpu->obj, layer_name, &ext_count, NULL); 429 assert(!err); 430 431 if (ext_ptr) { 432 free(ext_ptr); 433 } 434 ext_ptr = malloc(ext_count * sizeof(VkExtensionProperties)); 435 err = vkEnumerateDeviceExtensionProperties(gpu->obj, layer_name, &ext_count, ext_ptr); 436 } while (err == VK_INCOMPLETE); 437 assert(!err); 438 439 *extension_count = ext_count; 440 *extension_properties = ext_ptr; 441} 442 443static void app_dev_init(struct app_dev *dev, struct app_gpu *gpu) 444{ 445 VkDeviceCreateInfo info = { 446 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, 447 .pNext = NULL, 448 .queueCreateInfoCount = 0, 449 .pQueueCreateInfos = NULL, 450 .enabledLayerNameCount = 0, 451 .ppEnabledLayerNames = NULL, 452 .enabledExtensionNameCount = 0, 453 .ppEnabledExtensionNames = NULL, 454 }; 455 VkResult U_ASSERT_ONLY err; 456 // Extensions to enable 457 static const char *known_extensions[] = { 458 VK_KHR_SWAPCHAIN_EXTENSION_NAME, 459 }; 460 461 uint32_t count = 0; 462 463 /* Scan layers */ 464 VkLayerProperties *device_layer_properties = NULL; 465 struct layer_extension_list *device_layers = NULL; 466 467 do { 468 err = vkEnumerateDeviceLayerProperties(gpu->obj, &count, NULL); 469 assert(!err); 470 471 if (device_layer_properties) { 472 free(device_layer_properties); 473 } 474 device_layer_properties = malloc(sizeof(VkLayerProperties) * count); 475 assert(device_layer_properties); 476 477 if (device_layers) { 478 free(device_layers); 479 } 480 device_layers = malloc(sizeof(struct layer_extension_list) * count); 481 assert(device_layers); 482 483 err = vkEnumerateDeviceLayerProperties(gpu->obj, &count, device_layer_properties); 484 } while (err == VK_INCOMPLETE); 485 assert(!err); 486 487 gpu->device_layer_count = count; 488 gpu->device_layers = device_layers; 489 490 for (uint32_t i = 0; i < gpu->device_layer_count; i++) { 491 VkLayerProperties *src_info = &device_layer_properties[i]; 492 struct layer_extension_list *dst_info = &gpu->device_layers[i]; 493 memcpy(&dst_info->layer_properties, src_info, sizeof(VkLayerProperties)); 494 495 /* Save away layer extension info for report */ 496 app_get_physical_device_layer_extensions( 497 gpu, 498 src_info->layerName, 499 &dst_info->extension_count, 500 &dst_info->extension_properties); 501 } 502 free(device_layer_properties); 503 504 app_get_physical_device_layer_extensions( 505 gpu, 506 NULL, 507 &gpu->device_extension_count, 508 &gpu->device_extensions); 509 510 fflush(stdout); 511 512 uint32_t enabled_extension_count = 0; 513 uint32_t known_extension_count = ARRAY_SIZE(known_extensions); 514 515 for (uint32_t i = 0; i < known_extension_count; i++) { 516 VkBool32 extension_found = 0; 517 for (uint32_t j = 0; j < gpu->device_extension_count; j++) { 518 VkExtensionProperties *ext_prop = &gpu->device_extensions[j]; 519 if (!strcmp(known_extensions[i], ext_prop->extensionName)) { 520 521 extension_found = 1; 522 enabled_extension_count++; 523 } 524 } 525 if (!extension_found) { 526 printf("Cannot find extension: %s\n", known_extensions[i]); 527 ERR_EXIT(VK_ERROR_EXTENSION_NOT_PRESENT); 528 } 529 } 530 531 /* request all queues */ 532 info.queueCreateInfoCount = gpu->queue_count; 533 info.pQueueCreateInfos = gpu->queue_reqs; 534 535 info.enabledLayerNameCount = 0; 536 info.ppEnabledLayerNames = NULL; 537 info.enabledExtensionNameCount = enabled_extension_count; 538 info.ppEnabledExtensionNames = (const char*const*) known_extensions; 539 dev->gpu = gpu; 540 err = vkCreateDevice(gpu->obj, &info, NULL, &dev->obj); 541 if (err) 542 ERR_EXIT(err); 543 544} 545 546static void app_dev_destroy(struct app_dev *dev) 547{ 548 vkDestroyDevice(dev->obj, NULL); 549} 550 551static void app_get_global_layer_extensions( 552 char *layer_name, 553 uint32_t *extension_count, 554 VkExtensionProperties **extension_properties) 555{ 556 VkResult err; 557 uint32_t ext_count = 0; 558 VkExtensionProperties *ext_ptr = NULL; 559 560 /* repeat get until VK_INCOMPLETE goes away */ 561 do { 562 err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, NULL); 563 assert(!err); 564 565 if (ext_ptr) { 566 free(ext_ptr); 567 } 568 ext_ptr = malloc(ext_count * sizeof(VkExtensionProperties)); 569 err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, ext_ptr); 570 } while (err == VK_INCOMPLETE); 571 assert(!err); 572 573 *extension_count = ext_count; 574 *extension_properties = ext_ptr; 575} 576 577static void app_create_instance(struct app_instance *inst) 578{ 579 const VkApplicationInfo app_info = { 580 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, 581 .pNext = NULL, 582 .pApplicationName = APP_SHORT_NAME, 583 .applicationVersion = 1, 584 .pEngineName = APP_SHORT_NAME, 585 .engineVersion = 1, 586 .apiVersion = VK_API_VERSION, 587 }; 588 VkInstanceCreateInfo inst_info = { 589 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 590 .pNext = NULL, 591 .pApplicationInfo = &app_info, 592 .enabledLayerNameCount = 0, 593 .ppEnabledLayerNames = NULL, 594 .enabledExtensionNameCount = 0, 595 .ppEnabledExtensionNames = NULL, 596 }; 597 VkResult U_ASSERT_ONLY err; 598 // Global Extensions to enable 599 static char *known_extensions[] = { 600 VK_KHR_SURFACE_EXTENSION_NAME, 601#ifdef VK_USE_PLATFORM_ANDROID_KHR 602 VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, 603#endif 604#ifdef VK_USE_PLATFORM_MIR_KHR 605 VK_KHR_MIR_SURFACE_EXTENSION_NAME, 606#endif 607#ifdef VK_USE_PLATFORM_WAYLAND_KHR 608 VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, 609#endif 610#ifdef VK_USE_PLATFORM_WIN32_KHR 611 VK_KHR_WIN32_SURFACE_EXTENSION_NAME, 612#endif 613#ifdef VK_USE_PLATFORM_XCB_KHR 614 VK_KHR_XCB_SURFACE_EXTENSION_NAME, 615#endif 616#ifdef VK_USE_PLATFORM_XLIB_KHR 617 VK_KHR_XLIB_SURFACE_EXTENSION_NAME, 618#endif 619 }; 620 621 uint32_t global_extension_count = 0; 622 uint32_t count = 0; 623 624 /* Scan layers */ 625 VkLayerProperties *global_layer_properties = NULL; 626 struct layer_extension_list *global_layers = NULL; 627 628 do { 629 err = vkEnumerateInstanceLayerProperties(&count, NULL); 630 assert(!err); 631 632 if (global_layer_properties) { 633 free(global_layer_properties); 634 } 635 global_layer_properties = malloc(sizeof(VkLayerProperties) * count); 636 assert(global_layer_properties); 637 638 if (global_layers) { 639 free(global_layers); 640 } 641 global_layers = malloc(sizeof(struct layer_extension_list) * count); 642 assert(global_layers); 643 644 err = vkEnumerateInstanceLayerProperties(&count, global_layer_properties); 645 } while (err == VK_INCOMPLETE); 646 assert(!err); 647 648 inst->global_layer_count = count; 649 inst->global_layers = global_layers; 650 651 for (uint32_t i = 0; i < inst->global_layer_count; i++) { 652 VkLayerProperties *src_info = &global_layer_properties[i]; 653 struct layer_extension_list *dst_info = &inst->global_layers[i]; 654 memcpy(&dst_info->layer_properties, src_info, sizeof(VkLayerProperties)); 655 656 /* Save away layer extension info for report */ 657 app_get_global_layer_extensions( 658 src_info->layerName, 659 &dst_info->extension_count, 660 &dst_info->extension_properties); 661 } 662 free(global_layer_properties); 663 664 /* Collect global extensions */ 665 inst->global_extension_count = 0; 666 app_get_global_layer_extensions( 667 NULL, 668 &inst->global_extension_count, 669 &inst->global_extensions); 670 671 for (uint32_t i = 0; i < ARRAY_SIZE(known_extensions); i++) { 672 VkBool32 extension_found = 0; 673 for (uint32_t j = 0; j < inst->global_extension_count; j++) { 674 VkExtensionProperties *extension_prop = &inst->global_extensions[j]; 675 if (!strcmp(known_extensions[i], extension_prop->extensionName)) { 676 677 extension_found = 1; 678 global_extension_count++; 679 } 680 } 681 if (!extension_found) { 682 printf("Cannot find extension: %s\n", known_extensions[i]); 683 ERR_EXIT(VK_ERROR_EXTENSION_NOT_PRESENT); 684 } 685 } 686 687 inst_info.enabledExtensionNameCount = global_extension_count; 688 inst_info.ppEnabledExtensionNames = (const char * const *) known_extensions; 689 690 VkDebugReportCallbackCreateInfoEXT dbg_info; 691 memset(&dbg_info, 0, sizeof(dbg_info)); 692 dbg_info.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; 693 dbg_info.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARN_BIT_EXT | VK_DEBUG_REPORT_INFO_BIT_EXT; 694 dbg_info.pfnCallback = dbg_callback; 695 inst_info.pNext = &dbg_info; 696 697 err = vkCreateInstance(&inst_info, NULL, &inst->instance); 698 if (err == VK_ERROR_INCOMPATIBLE_DRIVER) { 699 printf("Cannot create Vulkan instance.\n"); 700 ERR_EXIT(err); 701 } else if (err) { 702 ERR_EXIT(err); 703 } 704} 705 706static void app_destroy_instance(struct app_instance *inst) 707{ 708 free(inst->global_extensions); 709 vkDestroyInstance(inst->instance, NULL); 710} 711 712 713static void app_gpu_init(struct app_gpu *gpu, uint32_t id, VkPhysicalDevice obj) 714{ 715 uint32_t i; 716 717 memset(gpu, 0, sizeof(*gpu)); 718 719 gpu->id = id; 720 gpu->obj = obj; 721 722 vkGetPhysicalDeviceProperties(gpu->obj, &gpu->props); 723 724 /* get queue count */ 725 vkGetPhysicalDeviceQueueFamilyProperties(gpu->obj, &gpu->queue_count, NULL); 726 727 gpu->queue_props = 728 malloc(sizeof(gpu->queue_props[0]) * gpu->queue_count); 729 730 if (!gpu->queue_props) 731 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); 732 vkGetPhysicalDeviceQueueFamilyProperties(gpu->obj, &gpu->queue_count, gpu->queue_props); 733 734 /* set up queue requests */ 735 gpu->queue_reqs = malloc(sizeof(*gpu->queue_reqs) * gpu->queue_count); 736 if (!gpu->queue_reqs) 737 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); 738 for (i = 0; i < gpu->queue_count; i++) { 739 float *queue_priorities = malloc(gpu->queue_props[i].queueCount * sizeof(float)); 740 memset(queue_priorities, 0, gpu->queue_props[i].queueCount * sizeof(float)); 741 gpu->queue_reqs[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 742 gpu->queue_reqs[i].pNext = NULL; 743 gpu->queue_reqs[i].queueFamilyIndex = i; 744 gpu->queue_reqs[i].queueCount = gpu->queue_props[i].queueCount; 745 gpu->queue_reqs[i].pQueuePriorities = queue_priorities; 746 } 747 748 vkGetPhysicalDeviceMemoryProperties(gpu->obj, &gpu->memory_props); 749 750 vkGetPhysicalDeviceFeatures(gpu->obj, &gpu->features); 751 752 app_dev_init(&gpu->dev, gpu); 753 app_dev_init_formats(&gpu->dev); 754} 755 756static void app_gpu_destroy(struct app_gpu *gpu) 757{ 758 app_dev_destroy(&gpu->dev); 759 free(gpu->device_extensions); 760 761 for (uint32_t i = 0; i < gpu->queue_count; i++) { 762 free((void *) gpu->queue_reqs[i].pQueuePriorities); 763 } 764 free(gpu->queue_reqs); 765 free(gpu->queue_props); 766} 767 768static void app_dev_dump_format_props(const struct app_dev *dev, VkFormat fmt) 769{ 770 const VkFormatProperties *props = &dev->format_props[fmt]; 771 struct { 772 const char *name; 773 VkFlags flags; 774 } features[3]; 775 uint32_t i; 776 777 features[0].name = "linearTiling FormatFeatureFlags"; 778 features[0].flags = props->linearTilingFeatures; 779 features[1].name = "optimalTiling FormatFeatureFlags"; 780 features[1].flags = props->optimalTilingFeatures; 781 features[2].name = "bufferFeatures FormatFeatureFlags"; 782 features[2].flags = props->bufferFeatures; 783 784 printf("\nFORMAT_%s:", vk_format_string(fmt)); 785 for (i = 0; i < ARRAY_SIZE(features); i++) { 786 printf("\n\t%s:", features[i].name); 787 if (features[i].flags == 0) { 788 printf("\n\t\tNone"); 789 } else { 790 printf("%s%s%s%s%s%s%s%s%s%s%s%s", 791 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT" : ""), 792 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_BIT" : ""), 793 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT" : ""), 794 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT" : ""), 795 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT" : ""), 796 ((features[i].flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) ? "\n\t\tVK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT" : ""), 797 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_SRC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_SRC_BIT" : ""), 798 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_DST_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_DST_BIT" : ""), 799 ((features[i].flags & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT" : ""), 800 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT" : ""), 801 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT" : ""), 802 ((features[i].flags & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_VERTEX_BUFFER_BIT" : "")); 803 } 804 } 805 printf("\n"); 806} 807 808 809static void 810app_dev_dump(const struct app_dev *dev) 811{ 812 VkFormat fmt; 813 814 for (fmt = 0; fmt < VK_FORMAT_RANGE_SIZE; fmt++) { 815 app_dev_dump_format_props(dev, fmt); 816 } 817} 818 819#ifdef _WIN32 820#define PRINTF_SIZE_T_SPECIFIER "%Iu" 821#else 822#define PRINTF_SIZE_T_SPECIFIER "%zu" 823#endif 824 825static void app_gpu_dump_features(const struct app_gpu *gpu) 826{ 827 const VkPhysicalDeviceFeatures *features = &gpu->features; 828 829 printf("VkPhysicalDeviceFeatures:\n"); 830 printf("=========================\n"); 831 832 printf("\trobustBufferAccess = %u\n", features->robustBufferAccess ); 833 printf("\tfullDrawIndexUint32 = %u\n", features->fullDrawIndexUint32 ); 834 printf("\timageCubeArray = %u\n", features->imageCubeArray ); 835 printf("\tindependentBlend = %u\n", features->independentBlend ); 836 printf("\tgeometryShader = %u\n", features->geometryShader ); 837 printf("\ttessellationShader = %u\n", features->tessellationShader ); 838 printf("\tsampleRateShading = %u\n", features->sampleRateShading ); 839 printf("\tdualSrcBlend = %u\n", features->dualSrcBlend ); 840 printf("\tlogicOp = %u\n", features->logicOp ); 841 printf("\tmultiDrawIndirect = %u\n", features->multiDrawIndirect ); 842 printf("\tdepthClamp = %u\n", features->depthClamp ); 843 printf("\tdepthBiasClamp = %u\n", features->depthBiasClamp ); 844 printf("\tfillModeNonSolid = %u\n", features->fillModeNonSolid ); 845 printf("\tdepthBounds = %u\n", features->depthBounds ); 846 printf("\twideLines = %u\n", features->wideLines ); 847 printf("\tlargePoints = %u\n", features->largePoints ); 848 printf("\ttextureCompressionETC2 = %u\n", features->textureCompressionETC2 ); 849 printf("\ttextureCompressionASTC_LDR = %u\n", features->textureCompressionASTC_LDR ); 850 printf("\ttextureCompressionBC = %u\n", features->textureCompressionBC ); 851 printf("\tocclusionQueryPrecise = %u\n", features->occlusionQueryPrecise ); 852 printf("\tpipelineStatisticsQuery = %u\n", features->pipelineStatisticsQuery ); 853 printf("\tvertexSideEffects = %u\n", features->vertexPipelineStoresAndAtomics ); 854 printf("\ttessellationSideEffects = %u\n", features->fragmentStoresAndAtomics ); 855 printf("\tgeometrySideEffects = %u\n", features->shaderTessellationAndGeometryPointSize ); 856 printf("\tshaderImageGatherExtended = %u\n", features->shaderImageGatherExtended ); 857 printf("\tshaderStorageImageExtendedFormats = %u\n", features->shaderStorageImageExtendedFormats ); 858 printf("\tshaderStorageImageMultisample = %u\n", features->shaderStorageImageMultisample ); 859 printf("\tshaderStorageImageReadWithoutFormat = %u\n", features->shaderStorageImageReadWithoutFormat ); 860 printf("\tshaderStorageImageWriteWithoutFormat = %u\n", features->shaderStorageImageWriteWithoutFormat ); 861 printf("\tshaderUniformBufferArrayDynamicIndexing = %u\n", features->shaderUniformBufferArrayDynamicIndexing); 862 printf("\tshaderSampledImageArrayDynamicIndexing = %u\n", features->shaderSampledImageArrayDynamicIndexing ); 863 printf("\tshaderStorageBufferArrayDynamicIndexing = %u\n", features->shaderStorageBufferArrayDynamicIndexing); 864 printf("\tshaderStorageImageArrayDynamicIndexing = %u\n", features->shaderStorageImageArrayDynamicIndexing ); 865 printf("\tshaderClipDistance = %u\n", features->shaderClipDistance ); 866 printf("\tshaderCullDistance = %u\n", features->shaderCullDistance ); 867 printf("\tshaderFloat64 = %u\n", features->shaderFloat64 ); 868 printf("\tshaderInt64 = %u\n", features->shaderInt64 ); 869 printf("\tshaderInt16 = %u\n", features->shaderInt16 ); 870 printf("\tshaderResourceResidency = %u\n", features->shaderResourceResidency ); 871 printf("\tshaderResourceMinLod = %u\n", features->shaderResourceMinLod ); 872 printf("\talphaToOne = %u\n", features->alphaToOne ); 873 printf("\tsparseBinding = %u\n", features->sparseBinding ); 874 printf("\tsparseResidencyBuffer = %u\n", features->sparseResidencyBuffer ); 875 printf("\tsparseResidencyImage2D = %u\n", features->sparseResidencyImage2D ); 876 printf("\tsparseResidencyImage3D = %u\n", features->sparseResidencyImage3D ); 877 printf("\tsparseResidency2Samples = %u\n", features->sparseResidency2Samples ); 878 printf("\tsparseResidency4Samples = %u\n", features->sparseResidency4Samples ); 879 printf("\tsparseResidency8Samples = %u\n", features->sparseResidency8Samples ); 880 printf("\tsparseResidency16Samples = %u\n", features->sparseResidency16Samples ); 881 printf("\tsparseResidencyAliased = %u\n", features->sparseResidencyAliased ); 882 printf("\tvariableMultisampleRate = %u\n", features->variableMultisampleRate ); 883 printf("\tiheritedQueries = %u\n", features->inheritedQueries ); 884} 885 886static void app_dump_sparse_props(const VkPhysicalDeviceSparseProperties *sparseProps) 887{ 888 889 printf("\tVkPhysicalDeviceSparseProperties:\n"); 890 printf("\t---------------------------------\n"); 891 892 printf("\t\tresidencyStandard2DBlockShape = %u\n", sparseProps->residencyStandard2DBlockShape ); 893 printf("\t\tresidencyStandard2DMultisampleBlockShape = %u\n", sparseProps->residencyStandard2DMultisampleBlockShape); 894 printf("\t\tresidencyStandard3DBlockShape = %u\n", sparseProps->residencyStandard3DBlockShape ); 895 printf("\t\tresidencyAlignedMipSize = %u\n", sparseProps->residencyAlignedMipSize ); 896 printf("\t\tresidencyNonResidentStrict = %u\n", sparseProps->residencyNonResidentStrict ); 897} 898 899static void app_dump_limits(const VkPhysicalDeviceLimits *limits) 900{ 901 printf("\tVkPhysicalDeviceLimits:\n"); 902 printf("\t-----------------------\n"); 903 904 printf("\t\tmaxImageDimension1D = 0x%" PRIxLEAST32 "\n", limits->maxImageDimension1D ); 905 printf("\t\tmaxImageDimension2D = 0x%" PRIxLEAST32 "\n", limits->maxImageDimension2D ); 906 printf("\t\tmaxImageDimension3D = 0x%" PRIxLEAST32 "\n", limits->maxImageDimension3D ); 907 printf("\t\tmaxImageDimensionCube = 0x%" PRIxLEAST32 "\n", limits->maxImageDimensionCube ); 908 printf("\t\tmaxImageArrayLayers = 0x%" PRIxLEAST32 "\n", limits->maxImageArrayLayers ); 909 printf("\t\tmaxTexelBufferElements = 0x%" PRIxLEAST32 "\n", limits->maxTexelBufferElements ); 910 printf("\t\tmaxUniformBufferRange = 0x%" PRIxLEAST32 "\n", limits->maxUniformBufferRange ); 911 printf("\t\tmaxStorageBufferRange = 0x%" PRIxLEAST32 "\n", limits->maxStorageBufferRange ); 912 printf("\t\tmaxPushConstantsSize = 0x%" PRIxLEAST32 "\n", limits->maxPushConstantsSize ); 913 printf("\t\tmaxMemoryAllocationCount = 0x%" PRIxLEAST32 "\n", limits->maxMemoryAllocationCount ); 914 printf("\t\tmaxSamplerAllocationCount = 0x%" PRIxLEAST32 "\n", limits->maxSamplerAllocationCount ); 915 printf("\t\tbufferImageGranularity = 0x%" PRIxLEAST64 "\n", limits->bufferImageGranularity ); 916 printf("\t\tsparseAddressSpaceSize = 0x%" PRIxLEAST64 "\n", limits->sparseAddressSpaceSize ); 917 printf("\t\tmaxBoundDescriptorSets = 0x%" PRIxLEAST32 "\n", limits->maxBoundDescriptorSets ); 918 printf("\t\tmaxPerStageDescriptorSamplers = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorSamplers ); 919 printf("\t\tmaxPerStageDescriptorUniformBuffers = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorUniformBuffers ); 920 printf("\t\tmaxPerStageDescriptorStorageBuffers = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorStorageBuffers ); 921 printf("\t\tmaxPerStageDescriptorSampledImages = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorSampledImages ); 922 printf("\t\tmaxPerStageDescriptorStorageImages = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorStorageImages ); 923 printf("\t\tmaxPerStageDescriptorInputAttachments = 0x%" PRIxLEAST32 "\n", limits->maxPerStageDescriptorInputAttachments ); 924 printf("\t\tmaxPerStageResources = 0x%" PRIxLEAST32 "\n", limits->maxPerStageResources ); 925 printf("\t\tmaxDescriptorSetSamplers = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetSamplers ); 926 printf("\t\tmaxDescriptorSetUniformBuffers = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetUniformBuffers ); 927 printf("\t\tmaxDescriptorSetUniformBuffersDynamic = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetUniformBuffersDynamic ); 928 printf("\t\tmaxDescriptorSetStorageBuffers = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetStorageBuffers ); 929 printf("\t\tmaxDescriptorSetStorageBuffersDynamic = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetStorageBuffersDynamic ); 930 printf("\t\tmaxDescriptorSetSampledImages = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetSampledImages ); 931 printf("\t\tmaxDescriptorSetStorageImages = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetStorageImages ); 932 printf("\t\tmaxDescriptorSetInputAttachments = 0x%" PRIxLEAST32 "\n", limits->maxDescriptorSetInputAttachments ); 933 printf("\t\tmaxVertexInputAttributes = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputAttributes ); 934 printf("\t\tmaxVertexInputBindings = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputBindings ); 935 printf("\t\tmaxVertexInputAttributeOffset = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputAttributeOffset ); 936 printf("\t\tmaxVertexInputBindingStride = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputBindingStride ); 937 printf("\t\tmaxVertexOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxVertexOutputComponents ); 938 printf("\t\tmaxTessellationGenerationLevel = 0x%" PRIxLEAST32 "\n", limits->maxTessellationGenerationLevel ); 939 printf("\t\tmaxTessellationPatchSize = 0x%" PRIxLEAST32 "\n", limits->maxTessellationPatchSize ); 940 printf("\t\tmaxTessellationControlPerVertexInputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessellationControlPerVertexInputComponents ); 941 printf("\t\tmaxTessellationControlPerVertexOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessellationControlPerVertexOutputComponents); 942 printf("\t\tmaxTessellationControlPerPatchOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessellationControlPerPatchOutputComponents ); 943 printf("\t\tmaxTessellationControlTotalOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessellationControlTotalOutputComponents ); 944 printf("\t\tmaxTessellationEvaluationInputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessellationEvaluationInputComponents ); 945 printf("\t\tmaxTessellationEvaluationOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxTessellationEvaluationOutputComponents ); 946 printf("\t\tmaxGeometryShaderInvocations = 0x%" PRIxLEAST32 "\n", limits->maxGeometryShaderInvocations ); 947 printf("\t\tmaxGeometryInputComponents = 0x%" PRIxLEAST32 "\n", limits->maxGeometryInputComponents ); 948 printf("\t\tmaxGeometryOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxGeometryOutputComponents ); 949 printf("\t\tmaxGeometryOutputVertices = 0x%" PRIxLEAST32 "\n", limits->maxGeometryOutputVertices ); 950 printf("\t\tmaxGeometryTotalOutputComponents = 0x%" PRIxLEAST32 "\n", limits->maxGeometryTotalOutputComponents ); 951 printf("\t\tmaxFragmentInputComponents = 0x%" PRIxLEAST32 "\n", limits->maxFragmentInputComponents ); 952 printf("\t\tmaxFragmentOutputAttachments = 0x%" PRIxLEAST32 "\n", limits->maxFragmentOutputAttachments ); 953 printf("\t\tmaxFragmentDualSrcAttachments = 0x%" PRIxLEAST32 "\n", limits->maxFragmentDualSrcAttachments ); 954 printf("\t\tmaxFragmentCombinedOutputResources = 0x%" PRIxLEAST32 "\n", limits->maxFragmentCombinedOutputResources ); 955 printf("\t\tmaxComputeSharedMemorySize = 0x%" PRIxLEAST32 "\n", limits->maxComputeSharedMemorySize ); 956 printf("\t\tmaxComputeWorkGroupCount[0] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupCount[0] ); 957 printf("\t\tmaxComputeWorkGroupCount[1] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupCount[1] ); 958 printf("\t\tmaxComputeWorkGroupCount[2] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupCount[2] ); 959 printf("\t\tmaxComputeWorkGroupInvocations = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupInvocations ); 960 printf("\t\tmaxComputeWorkGroupSize[0] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupSize[0] ); 961 printf("\t\tmaxComputeWorkGroupSize[1] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupSize[1] ); 962 printf("\t\tmaxComputeWorkGroupSize[2] = 0x%" PRIxLEAST32 "\n", limits->maxComputeWorkGroupSize[2] ); 963 printf("\t\tsubPixelPrecisionBits = 0x%" PRIxLEAST32 "\n", limits->subPixelPrecisionBits ); 964 printf("\t\tsubTexelPrecisionBits = 0x%" PRIxLEAST32 "\n", limits->subTexelPrecisionBits ); 965 printf("\t\tmipmapPrecisionBits = 0x%" PRIxLEAST32 "\n", limits->mipmapPrecisionBits ); 966 printf("\t\tmaxDrawIndexedIndexValue = 0x%" PRIxLEAST32 "\n", limits->maxDrawIndexedIndexValue ); 967 printf("\t\tmaxDrawIndirectCount = 0x%" PRIxLEAST32 "\n", limits->maxDrawIndirectCount ); 968 printf("\t\tmaxSamplerLodBias = %f\n", limits->maxSamplerLodBias ); 969 printf("\t\tmaxSamplerAnisotropy = %f\n", limits->maxSamplerAnisotropy ); 970 printf("\t\tmaxViewports = 0x%" PRIxLEAST32 "\n", limits->maxViewports ); 971 printf("\t\tmaxViewportDimensions[0] = 0x%" PRIxLEAST32 "\n", limits->maxViewportDimensions[0] ); 972 printf("\t\tmaxViewportDimensions[1] = 0x%" PRIxLEAST32 "\n", limits->maxViewportDimensions[1] ); 973 printf("\t\tviewportBoundsRange[0] = %f\n", limits->viewportBoundsRange[0] ); 974 printf("\t\tviewportBoundsRange[1] = %f\n", limits->viewportBoundsRange[1] ); 975 printf("\t\tviewportSubPixelBits = 0x%" PRIxLEAST32 "\n", limits->viewportSubPixelBits ); 976 printf("\t\tminMemoryMapAlignment = " PRINTF_SIZE_T_SPECIFIER "\n", limits->minMemoryMapAlignment ); 977 printf("\t\tminTexelBufferOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->minTexelBufferOffsetAlignment ); 978 printf("\t\tminUniformBufferOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->minUniformBufferOffsetAlignment ); 979 printf("\t\tminStorageBufferOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->minStorageBufferOffsetAlignment ); 980 printf("\t\tminTexelOffset = 0x%" PRIxLEAST32 "\n", limits->minTexelOffset ); 981 printf("\t\tmaxTexelOffset = 0x%" PRIxLEAST32 "\n", limits->maxTexelOffset ); 982 printf("\t\tminTexelGatherOffset = 0x%" PRIxLEAST32 "\n", limits->minTexelGatherOffset ); 983 printf("\t\tmaxTexelGatherOffset = 0x%" PRIxLEAST32 "\n", limits->maxTexelGatherOffset ); 984 printf("\t\tminInterpolationOffset = %f\n", limits->minInterpolationOffset ); 985 printf("\t\tmaxInterpolationOffset = %f\n", limits->maxInterpolationOffset ); 986 printf("\t\tsubPixelInterpolationOffsetBits = 0x%" PRIxLEAST32 "\n", limits->subPixelInterpolationOffsetBits ); 987 printf("\t\tmaxFramebufferWidth = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferWidth ); 988 printf("\t\tmaxFramebufferHeight = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferHeight ); 989 printf("\t\tmaxFramebufferLayers = 0x%" PRIxLEAST32 "\n", limits->maxFramebufferLayers ); 990 printf("\t\tframebufferColorSampleCounts = 0x%" PRIxLEAST32 "\n", limits->framebufferColorSampleCounts ); 991 printf("\t\tframebufferDepthSampleCounts = 0x%" PRIxLEAST32 "\n", limits->framebufferDepthSampleCounts ); 992 printf("\t\tframebufferStencilSampleCounts = 0x%" PRIxLEAST32 "\n", limits->framebufferStencilSampleCounts ); 993 printf("\t\tmaxColorAttachments = 0x%" PRIxLEAST32 "\n", limits->maxColorAttachments ); 994 printf("\t\tsampledImageColorSampleCounts = 0x%" PRIxLEAST32 "\n", limits->sampledImageColorSampleCounts ); 995 printf("\t\tsampledImageDepthSampleCounts = 0x%" PRIxLEAST32 "\n", limits->sampledImageDepthSampleCounts ); 996 printf("\t\tsampledImageStencilSampleCounts = 0x%" PRIxLEAST32 "\n", limits->sampledImageStencilSampleCounts ); 997 printf("\t\tsampledImageIntegerSampleCounts = 0x%" PRIxLEAST32 "\n", limits->sampledImageIntegerSampleCounts ); 998 printf("\t\tstorageImageSampleCounts = 0x%" PRIxLEAST32 "\n", limits->storageImageSampleCounts ); 999 printf("\t\tmaxSampleMaskWords = 0x%" PRIxLEAST32 "\n", limits->maxSampleMaskWords ); 1000 printf("\t\ttimestampComputeAndGraphics = %u\n", limits->timestampComputeAndGraphics ); 1001 printf("\t\ttimestampPeriod = 0x%f\n", limits->timestampPeriod ); 1002 printf("\t\tmaxClipDistances = 0x%" PRIxLEAST32 "\n", limits->maxClipDistances ); 1003 printf("\t\tmaxCullDistances = 0x%" PRIxLEAST32 "\n", limits->maxCullDistances ); 1004 printf("\t\tmaxCombinedClipAndCullDistances = 0x%" PRIxLEAST32 "\n", limits->maxCombinedClipAndCullDistances ); 1005 printf("\t\tpointSizeRange[0] = %f\n", limits->pointSizeRange[0] ); 1006 printf("\t\tpointSizeRange[1] = %f\n", limits->pointSizeRange[1] ); 1007 printf("\t\tlineWidthRange[0] = %f\n", limits->lineWidthRange[0] ); 1008 printf("\t\tlineWidthRange[1] = %f\n", limits->lineWidthRange[1] ); 1009 printf("\t\tpointSizeGranularity = %f\n", limits->pointSizeGranularity ); 1010 printf("\t\tlineWidthGranularity = %f\n", limits->lineWidthGranularity ); 1011 printf("\t\tstrictLines = %u\n", limits->strictLines ); 1012 printf("\t\tstandardSampleLocations = %u\n", limits->standardSampleLocations ); 1013 printf("\t\toptimalBufferCopyOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->optimalBufferCopyOffsetAlignment ); 1014 printf("\t\toptimalBufferCopyRowPitchAlignment = 0x%" PRIxLEAST64 "\n", limits->optimalBufferCopyRowPitchAlignment ); 1015 printf("\t\tnonCoherentAtomSize = 0x%" PRIxLEAST64 "\n", limits->nonCoherentAtomSize ); 1016} 1017 1018static void app_gpu_dump_props(const struct app_gpu *gpu) 1019{ 1020 const VkPhysicalDeviceProperties *props = &gpu->props; 1021 1022 printf("VkPhysicalDeviceProperties:\n"); 1023 printf("===========================\n"); 1024 printf("\tapiVersion = %u\n", props->apiVersion); 1025 printf("\tdriverVersion = %u\n", props->driverVersion); 1026 printf("\tvendorID = 0x%04x\n", props->vendorID); 1027 printf("\tdeviceID = 0x%04x\n", props->deviceID); 1028 printf("\tdeviceType = %s\n", vk_physical_device_type_string(props->deviceType)); 1029 printf("\tdeviceName = %s\n", props->deviceName); 1030 1031 app_dump_limits(&gpu->props.limits); 1032 app_dump_sparse_props(&gpu->props.sparseProperties); 1033 1034 fflush(stdout); 1035} 1036 1037static void app_dump_extensions( 1038 const char *indent, 1039 const char *layer_name, 1040 const uint32_t extension_count, 1041 const VkExtensionProperties *extension_properties) 1042{ 1043 uint32_t i; 1044 if (layer_name && (strlen(layer_name) > 0)) { 1045 printf("%s%s Extensions", indent, layer_name); 1046 } else { 1047 printf("Extensions"); 1048 } 1049 printf("\tcount = %d\n", extension_count); 1050 for (i=0; i< extension_count; i++) { 1051 VkExtensionProperties const *ext_prop = &extension_properties[i]; 1052 1053 printf("%s\t", indent); 1054 printf("%-32s: extension revision %2d\n", 1055 ext_prop->extensionName, ext_prop->specVersion); 1056 } 1057 printf("\n"); 1058 fflush(stdout); 1059} 1060 1061static void app_gpu_dump_queue_props(const struct app_gpu *gpu, uint32_t id) 1062{ 1063 const VkQueueFamilyProperties *props = &gpu->queue_props[id]; 1064 1065 printf("VkQueueFamilyProperties[%d]:\n", id); 1066 printf("============================\n"); 1067 printf("\tqueueFlags = %c%c%c\n", 1068 (props->queueFlags & VK_QUEUE_GRAPHICS_BIT) ? 'G' : '.', 1069 (props->queueFlags & VK_QUEUE_COMPUTE_BIT) ? 'C' : '.', 1070 (props->queueFlags & VK_QUEUE_TRANSFER_BIT) ? 'D' : '.'); 1071 printf("\tqueueCount = %u\n", props->queueCount); 1072 printf("\ttimestampValidBits = %u\n", props->timestampValidBits); 1073 printf("\tminImageTransferGranularity = (%d, %d, %d)\n", 1074 props->minImageTransferGranularity.width, 1075 props->minImageTransferGranularity.height, 1076 props->minImageTransferGranularity.depth); 1077 fflush(stdout); 1078} 1079 1080static void app_gpu_dump_memory_props(const struct app_gpu *gpu) 1081{ 1082 const VkPhysicalDeviceMemoryProperties *props = &gpu->memory_props; 1083 1084 printf("VkPhysicalDeviceMemoryProperties:\n"); 1085 printf("=================================\n"); 1086 printf("\tmemoryTypeCount = %u\n", props->memoryTypeCount); 1087 for (uint32_t i = 0; i < props->memoryTypeCount; i++) { 1088 printf("\tmemoryTypes[%u] : \n", i); 1089 printf("\t\tpropertyFlags = %u\n", props->memoryTypes[i].propertyFlags); 1090 printf("\t\theapIndex = %u\n", props->memoryTypes[i].heapIndex); 1091 } 1092 printf("\tmemoryHeapCount = %u\n", props->memoryHeapCount); 1093 for (uint32_t i = 0; i < props->memoryHeapCount; i++) { 1094 printf("\tmemoryHeaps[%u] : \n", i); 1095 printf("\t\tsize = " PRINTF_SIZE_T_SPECIFIER "\n", props->memoryHeaps[i].size); 1096 } 1097 fflush(stdout); 1098} 1099 1100static void app_gpu_dump(const struct app_gpu *gpu) 1101{ 1102 uint32_t i; 1103 1104 printf("Device Extensions and layers:\n"); 1105 printf("=============================\n"); 1106 printf("GPU%u\n", gpu->id); 1107 app_gpu_dump_props(gpu); 1108 printf("\n"); 1109 app_dump_extensions("", "Device", gpu->device_extension_count, gpu->device_extensions); 1110 printf("\n"); 1111 printf("Layers\tcount = %d\n", gpu->device_layer_count); 1112 for (uint32_t i = 0; i < gpu->device_layer_count; i++) { 1113 uint32_t major, minor, patch; 1114 char spec_version[64], layer_version[64]; 1115 struct layer_extension_list const *layer_info = &gpu->device_layers[i]; 1116 1117 extract_version(layer_info->layer_properties.specVersion, &major, &minor, &patch); 1118 snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", major, minor, patch); 1119 snprintf(layer_version, sizeof(layer_version), "%d", layer_info->layer_properties.implementationVersion); 1120 printf("\t%s (%s) Vulkan version %s, layer version %s\n", 1121 layer_info->layer_properties.layerName, 1122 (char*) layer_info->layer_properties.description, 1123 spec_version, layer_version); 1124 1125 app_dump_extensions("\t", 1126 layer_info->layer_properties.layerName, 1127 layer_info->extension_count, 1128 layer_info->extension_properties); 1129 fflush(stdout); 1130 } 1131 printf("\n"); 1132 for (i = 0; i < gpu->queue_count; i++) { 1133 app_gpu_dump_queue_props(gpu, i); 1134 printf("\n"); 1135 } 1136 app_gpu_dump_memory_props(gpu); 1137 printf("\n"); 1138 app_gpu_dump_features(gpu); 1139 printf("\n"); 1140 app_dev_dump(&gpu->dev); 1141} 1142 1143int main(int argc, char **argv) 1144{ 1145 unsigned int major, minor, patch; 1146 struct app_gpu gpus[MAX_GPUS]; 1147 VkPhysicalDevice objs[MAX_GPUS]; 1148 uint32_t gpu_count, i; 1149 VkResult err; 1150 struct app_instance inst; 1151 1152 major = VK_API_VERSION >> 22; 1153 minor = (VK_API_VERSION >> 12) & 0x4ff; 1154 patch = VK_API_VERSION & 0xfff; 1155 printf("===========\n"); 1156 printf("VULKAN INFO\n"); 1157 printf("===========\n\n"); 1158 printf("Vulkan API Version: %d %d %d\n\n", major, minor, patch); 1159 1160 app_create_instance(&inst); 1161 1162 printf("Instance Extensions and layers:\n"); 1163 printf("===============================\n"); 1164 app_dump_extensions("", "Instance", inst.global_extension_count, inst.global_extensions); 1165 1166 printf("Instance Layers\tcount = %d\n", inst.global_layer_count); 1167 for (uint32_t i = 0; i < inst.global_layer_count; i++) { 1168 uint32_t major, minor, patch; 1169 char spec_version[64], layer_version[64]; 1170 VkLayerProperties const *layer_prop = &inst.global_layers[i].layer_properties; 1171 1172 extract_version(layer_prop->specVersion, &major, &minor, &patch); 1173 snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", major, minor, patch); 1174 snprintf(layer_version, sizeof(layer_version), "%d", layer_prop->implementationVersion); 1175 printf("\t%s (%s) Vulkan version %s, layer version %s\n", 1176 layer_prop->layerName, (char*) layer_prop->description, spec_version, layer_version); 1177 1178 app_dump_extensions("\t", 1179 inst.global_layers[i].layer_properties.layerName, 1180 inst.global_layers[i].extension_count, 1181 inst.global_layers[i].extension_properties); 1182 } 1183 1184 err = vkEnumeratePhysicalDevices(inst.instance, &gpu_count, NULL); 1185 if (err) 1186 ERR_EXIT(err); 1187 if (gpu_count > MAX_GPUS) { 1188 printf("Too many GPUS found \n"); 1189 ERR_EXIT(-1); 1190 } 1191 err = vkEnumeratePhysicalDevices(inst.instance, &gpu_count, objs); 1192 if (err) 1193 ERR_EXIT(err); 1194 1195 for (i = 0; i < gpu_count; i++) { 1196 app_gpu_init(&gpus[i], i, objs[i]); 1197 app_gpu_dump(&gpus[i]); 1198 printf("\n\n"); 1199 } 1200 1201 for (i = 0; i < gpu_count; i++) 1202 app_gpu_destroy(&gpus[i]); 1203 1204 app_destroy_instance(&inst); 1205 1206 return 0; 1207} 1208 1209#ifdef _WIN32 1210 1211// Create a console window with a large scrollback size to which to send stdout. 1212// Returns true if console window was successfully created, false otherwise. 1213bool SetStdOutToNewConsole() 1214{ 1215 // don't do anything if we already have a console 1216 if (GetStdHandle(STD_OUTPUT_HANDLE)) 1217 return false; 1218 1219 // allocate a console for this app 1220 AllocConsole(); 1221 1222 // redirect unbuffered STDOUT to the console 1223 HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); 1224 int fileDescriptor = _open_osfhandle((intptr_t)consoleHandle, _O_TEXT); 1225 FILE *fp = _fdopen( fileDescriptor, "w" ); 1226 *stdout = *fp; 1227 setvbuf( stdout, NULL, _IONBF, 0 ); 1228 1229 // make the console window bigger 1230 CONSOLE_SCREEN_BUFFER_INFO csbi; 1231 SMALL_RECT r; 1232 COORD bufferSize; 1233 if (!GetConsoleScreenBufferInfo(consoleHandle, &csbi)) 1234 return false; 1235 bufferSize.X = csbi.dwSize.X+30; 1236 bufferSize.Y = 20000; 1237 if (!SetConsoleScreenBufferSize(consoleHandle, bufferSize)) 1238 return false; 1239 r.Left = r.Top = 0; 1240 r.Right = csbi.dwSize.X-1+30; 1241 r.Bottom = 50; 1242 if (!SetConsoleWindowInfo(consoleHandle, true, &r)) 1243 return false; 1244 1245 // change the console window title 1246 if (!SetConsoleTitle(TEXT(APP_SHORT_NAME))) 1247 return false; 1248 1249 return true; 1250} 1251 1252int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nCmdShow) 1253{ 1254 char *argv = pCmdLine; 1255 consoleCreated = SetStdOutToNewConsole(); 1256 main(1, &argv); 1257 fflush(stdout); 1258 if (consoleCreated) 1259 Sleep(INFINITE); 1260} 1261#endif 1262