vulkaninfo.c revision bbc18b5cfc57a7b8bfd78e80de90a483434f1a7f
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 30#include <vulkan.h> 31 32#define ERR(err) printf("%s:%d: failed with %s\n", \ 33 __FILE__, __LINE__, vk_result_string(err)); 34 35#define ERR_EXIT(err) do { ERR(err); exit(-1); } while (0) 36 37#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 38 39#define MAX_GPUS 8 40 41#define MAX_QUEUE_TYPES 5 42 43struct app_gpu; 44 45struct app_dev { 46 struct app_gpu *gpu; /* point back to the GPU */ 47 48 VkDevice obj; 49 50 51 VkFormatProperties format_props[VK_NUM_FMT]; 52}; 53 54struct app_gpu { 55 uint32_t id; 56 VkPhysicalGpu obj; 57 58 VkPhysicalGpuProperties props; 59 VkPhysicalGpuPerformance perf; 60 61 uint32_t queue_count; 62 VkPhysicalGpuQueueProperties *queue_props; 63 VkDeviceQueueCreateInfo *queue_reqs; 64 65 VkPhysicalGpuMemoryProperties memory_props; 66 67 uint32_t extension_count; 68 char **extensions; 69 70 struct app_dev dev; 71}; 72 73static const char *vk_result_string(VkResult err) 74{ 75 switch (err) { 76#define STR(r) case r: return #r 77 STR(VK_SUCCESS); 78 STR(VK_UNSUPPORTED); 79 STR(VK_NOT_READY); 80 STR(VK_TIMEOUT); 81 STR(VK_EVENT_SET); 82 STR(VK_EVENT_RESET); 83 STR(VK_ERROR_UNKNOWN); 84 STR(VK_ERROR_UNAVAILABLE); 85 STR(VK_ERROR_INITIALIZATION_FAILED); 86 STR(VK_ERROR_OUT_OF_MEMORY); 87 STR(VK_ERROR_OUT_OF_GPU_MEMORY); 88 STR(VK_ERROR_DEVICE_ALREADY_CREATED); 89 STR(VK_ERROR_DEVICE_LOST); 90 STR(VK_ERROR_INVALID_POINTER); 91 STR(VK_ERROR_INVALID_VALUE); 92 STR(VK_ERROR_INVALID_HANDLE); 93 STR(VK_ERROR_INVALID_ORDINAL); 94 STR(VK_ERROR_INVALID_MEMORY_SIZE); 95 STR(VK_ERROR_INVALID_EXTENSION); 96 STR(VK_ERROR_INVALID_FLAGS); 97 STR(VK_ERROR_INVALID_ALIGNMENT); 98 STR(VK_ERROR_INVALID_FORMAT); 99 STR(VK_ERROR_INVALID_IMAGE); 100 STR(VK_ERROR_INVALID_DESCRIPTOR_SET_DATA); 101 STR(VK_ERROR_INVALID_QUEUE_TYPE); 102 STR(VK_ERROR_INVALID_OBJECT_TYPE); 103 STR(VK_ERROR_UNSUPPORTED_SHADER_IL_VERSION); 104 STR(VK_ERROR_BAD_SHADER_CODE); 105 STR(VK_ERROR_BAD_PIPELINE_DATA); 106 STR(VK_ERROR_TOO_MANY_MEMORY_REFERENCES); 107 STR(VK_ERROR_NOT_MAPPABLE); 108 STR(VK_ERROR_MEMORY_MAP_FAILED); 109 STR(VK_ERROR_MEMORY_UNMAP_FAILED); 110 STR(VK_ERROR_INCOMPATIBLE_DEVICE); 111 STR(VK_ERROR_INCOMPATIBLE_DRIVER); 112 STR(VK_ERROR_INCOMPLETE_COMMAND_BUFFER); 113 STR(VK_ERROR_BUILDING_COMMAND_BUFFER); 114 STR(VK_ERROR_MEMORY_NOT_BOUND); 115 STR(VK_ERROR_INCOMPATIBLE_QUEUE); 116 STR(VK_ERROR_NOT_SHAREABLE); 117#undef STR 118 default: return "UNKNOWN_RESULT"; 119 } 120} 121 122static const char *vk_gpu_type_string(VkPhysicalGpuType type) 123{ 124 switch (type) { 125#define STR(r) case VK_GPU_TYPE_ ##r: return #r 126 STR(OTHER); 127 STR(INTEGRATED); 128 STR(DISCRETE); 129 STR(VIRTUAL); 130#undef STR 131 default: return "UNKNOWN_GPU"; 132 } 133} 134 135static const char *vk_format_string(VkFormat fmt) 136{ 137 switch (fmt) { 138#define STR(r) case VK_FMT_ ##r: return #r 139 STR(UNDEFINED); 140 STR(R4G4_UNORM); 141 STR(R4G4_USCALED); 142 STR(R4G4B4A4_UNORM); 143 STR(R4G4B4A4_USCALED); 144 STR(R5G6B5_UNORM); 145 STR(R5G6B5_USCALED); 146 STR(R5G5B5A1_UNORM); 147 STR(R5G5B5A1_USCALED); 148 STR(R8_UNORM); 149 STR(R8_SNORM); 150 STR(R8_USCALED); 151 STR(R8_SSCALED); 152 STR(R8_UINT); 153 STR(R8_SINT); 154 STR(R8_SRGB); 155 STR(R8G8_UNORM); 156 STR(R8G8_SNORM); 157 STR(R8G8_USCALED); 158 STR(R8G8_SSCALED); 159 STR(R8G8_UINT); 160 STR(R8G8_SINT); 161 STR(R8G8_SRGB); 162 STR(R8G8B8_UNORM); 163 STR(R8G8B8_SNORM); 164 STR(R8G8B8_USCALED); 165 STR(R8G8B8_SSCALED); 166 STR(R8G8B8_UINT); 167 STR(R8G8B8_SINT); 168 STR(R8G8B8_SRGB); 169 STR(R8G8B8A8_UNORM); 170 STR(R8G8B8A8_SNORM); 171 STR(R8G8B8A8_USCALED); 172 STR(R8G8B8A8_SSCALED); 173 STR(R8G8B8A8_UINT); 174 STR(R8G8B8A8_SINT); 175 STR(R8G8B8A8_SRGB); 176 STR(R10G10B10A2_UNORM); 177 STR(R10G10B10A2_SNORM); 178 STR(R10G10B10A2_USCALED); 179 STR(R10G10B10A2_SSCALED); 180 STR(R10G10B10A2_UINT); 181 STR(R10G10B10A2_SINT); 182 STR(R16_UNORM); 183 STR(R16_SNORM); 184 STR(R16_USCALED); 185 STR(R16_SSCALED); 186 STR(R16_UINT); 187 STR(R16_SINT); 188 STR(R16_SFLOAT); 189 STR(R16G16_UNORM); 190 STR(R16G16_SNORM); 191 STR(R16G16_USCALED); 192 STR(R16G16_SSCALED); 193 STR(R16G16_UINT); 194 STR(R16G16_SINT); 195 STR(R16G16_SFLOAT); 196 STR(R16G16B16_UNORM); 197 STR(R16G16B16_SNORM); 198 STR(R16G16B16_USCALED); 199 STR(R16G16B16_SSCALED); 200 STR(R16G16B16_UINT); 201 STR(R16G16B16_SINT); 202 STR(R16G16B16_SFLOAT); 203 STR(R16G16B16A16_UNORM); 204 STR(R16G16B16A16_SNORM); 205 STR(R16G16B16A16_USCALED); 206 STR(R16G16B16A16_SSCALED); 207 STR(R16G16B16A16_UINT); 208 STR(R16G16B16A16_SINT); 209 STR(R16G16B16A16_SFLOAT); 210 STR(R32_UINT); 211 STR(R32_SINT); 212 STR(R32_SFLOAT); 213 STR(R32G32_UINT); 214 STR(R32G32_SINT); 215 STR(R32G32_SFLOAT); 216 STR(R32G32B32_UINT); 217 STR(R32G32B32_SINT); 218 STR(R32G32B32_SFLOAT); 219 STR(R32G32B32A32_UINT); 220 STR(R32G32B32A32_SINT); 221 STR(R32G32B32A32_SFLOAT); 222 STR(R64_SFLOAT); 223 STR(R64G64_SFLOAT); 224 STR(R64G64B64_SFLOAT); 225 STR(R64G64B64A64_SFLOAT); 226 STR(R11G11B10_UFLOAT); 227 STR(R9G9B9E5_UFLOAT); 228 STR(D16_UNORM); 229 STR(D24_UNORM); 230 STR(D32_SFLOAT); 231 STR(S8_UINT); 232 STR(D16_UNORM_S8_UINT); 233 STR(D24_UNORM_S8_UINT); 234 STR(D32_SFLOAT_S8_UINT); 235 STR(BC1_RGB_UNORM); 236 STR(BC1_RGB_SRGB); 237 STR(BC2_UNORM); 238 STR(BC2_SRGB); 239 STR(BC3_UNORM); 240 STR(BC3_SRGB); 241 STR(BC4_UNORM); 242 STR(BC4_SNORM); 243 STR(BC5_UNORM); 244 STR(BC5_SNORM); 245 STR(BC6H_UFLOAT); 246 STR(BC6H_SFLOAT); 247 STR(BC7_UNORM); 248 STR(BC7_SRGB); 249 STR(ETC2_R8G8B8_UNORM); 250 STR(ETC2_R8G8B8A1_UNORM); 251 STR(ETC2_R8G8B8A8_UNORM); 252 STR(EAC_R11_UNORM); 253 STR(EAC_R11_SNORM); 254 STR(EAC_R11G11_UNORM); 255 STR(EAC_R11G11_SNORM); 256 STR(ASTC_4x4_UNORM); 257 STR(ASTC_4x4_SRGB); 258 STR(ASTC_5x4_UNORM); 259 STR(ASTC_5x4_SRGB); 260 STR(ASTC_5x5_UNORM); 261 STR(ASTC_5x5_SRGB); 262 STR(ASTC_6x5_UNORM); 263 STR(ASTC_6x5_SRGB); 264 STR(ASTC_6x6_UNORM); 265 STR(ASTC_6x6_SRGB); 266 STR(ASTC_8x5_UNORM); 267 STR(ASTC_8x5_SRGB); 268 STR(ASTC_8x6_UNORM); 269 STR(ASTC_8x6_SRGB); 270 STR(ASTC_8x8_UNORM); 271 STR(ASTC_8x8_SRGB); 272 STR(ASTC_10x5_UNORM); 273 STR(ASTC_10x5_SRGB); 274 STR(ASTC_10x6_UNORM); 275 STR(ASTC_10x6_SRGB); 276 STR(ASTC_10x8_UNORM); 277 STR(ASTC_10x8_SRGB); 278 STR(ASTC_10x10_UNORM); 279 STR(ASTC_10x10_SRGB); 280 STR(ASTC_12x10_UNORM); 281 STR(ASTC_12x10_SRGB); 282 STR(ASTC_12x12_UNORM); 283 STR(ASTC_12x12_SRGB); 284 STR(B5G6R5_UNORM); 285 STR(B5G6R5_USCALED); 286 STR(B8G8R8_UNORM); 287 STR(B8G8R8_SNORM); 288 STR(B8G8R8_USCALED); 289 STR(B8G8R8_SSCALED); 290 STR(B8G8R8_UINT); 291 STR(B8G8R8_SINT); 292 STR(B8G8R8_SRGB); 293 STR(B8G8R8A8_UNORM); 294 STR(B8G8R8A8_SNORM); 295 STR(B8G8R8A8_USCALED); 296 STR(B8G8R8A8_SSCALED); 297 STR(B8G8R8A8_UINT); 298 STR(B8G8R8A8_SINT); 299 STR(B8G8R8A8_SRGB); 300 STR(B10G10R10A2_UNORM); 301 STR(B10G10R10A2_SNORM); 302 STR(B10G10R10A2_USCALED); 303 STR(B10G10R10A2_SSCALED); 304 STR(B10G10R10A2_UINT); 305 STR(B10G10R10A2_SINT); 306#undef STR 307 default: return "UNKNOWN_FORMAT"; 308 } 309} 310 311static void app_dev_init_formats(struct app_dev *dev) 312{ 313 VkFormat f; 314 315 for (f = 0; f < VK_NUM_FMT; f++) { 316 const VkFormat fmt = f; 317 VkResult err; 318 size_t size = sizeof(dev->format_props[f]); 319 320 err = vkGetFormatInfo(dev->obj, fmt, 321 VK_INFO_TYPE_FORMAT_PROPERTIES, 322 &size, &dev->format_props[f]); 323 if (err) { 324 memset(&dev->format_props[f], 0, 325 sizeof(dev->format_props[f])); 326 } 327 else if (size != sizeof(dev->format_props[f])) { 328 ERR_EXIT(VK_ERROR_UNKNOWN); 329 } 330 } 331} 332 333static void app_dev_init(struct app_dev *dev, struct app_gpu *gpu) 334{ 335 VkDeviceCreateInfo info = { 336 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, 337 .pNext = NULL, 338 .queueRecordCount = 0, 339 .pRequestedQueues = NULL, 340 .extensionCount = 0, 341 .ppEnabledExtensionNames = NULL, 342 .flags = VK_DEVICE_CREATE_VALIDATION_BIT, 343 }; 344 VkResult err; 345 346 /* request all queues */ 347 info.queueRecordCount = gpu->queue_count; 348 info.pRequestedQueues = gpu->queue_reqs; 349 350 /* enable all extensions */ 351 info.extensionCount = gpu->extension_count; 352 info.ppEnabledExtensionNames = (const char*const*) gpu->extensions; 353 dev->gpu = gpu; 354 err = vkCreateDevice(gpu->obj, &info, &dev->obj); 355 if (err) 356 ERR_EXIT(err); 357 358} 359 360static void app_dev_destroy(struct app_dev *dev) 361{ 362 vkDestroyDevice(dev->obj); 363} 364 365static void app_gpu_init_extensions(struct app_gpu *gpu) 366{ 367 //VkResult err; 368 uint32_t i; 369 // TODO : Should query count w/ GetGlobalExtensionInfo, 370 // Then dynamically set extensions based on returned count 371 372 static char *known_extensions[] = { 373 "VK_WSI_X11", 374 }; 375 376 for (i = 0; i < ARRAY_SIZE(known_extensions); i++) { 377/* 378 err = vkGetExtensionSupport(gpu->obj, known_extensions[i]); 379 if (!err) 380*/ 381 gpu->extension_count++; 382 } 383 384 gpu->extensions = 385 malloc(sizeof(gpu->extensions[0]) * gpu->extension_count); 386 if (!gpu->extensions) 387 ERR_EXIT(VK_ERROR_OUT_OF_MEMORY); 388 389 gpu->extension_count = 0; 390 for (i = 0; i < ARRAY_SIZE(known_extensions); i++) { 391/* 392 err = vkGetExtensionSupport(gpu->obj, known_extensions[i]); 393 if (!err) 394*/ 395 gpu->extensions[gpu->extension_count++] = known_extensions[i]; 396 } 397} 398 399static void app_gpu_init(struct app_gpu *gpu, uint32_t id, VkPhysicalGpu obj) 400{ 401 size_t size; 402 VkResult err; 403 uint32_t i; 404 405 memset(gpu, 0, sizeof(*gpu)); 406 407 gpu->id = id; 408 gpu->obj = obj; 409 size = sizeof(gpu->props); 410 err = vkGetGpuInfo(gpu->obj, 411 VK_INFO_TYPE_PHYSICAL_GPU_PROPERTIES, 412 &size, &gpu->props); 413 if (err || size != sizeof(gpu->props)) 414 ERR_EXIT(err); 415 416 size = sizeof(gpu->perf); 417 err = vkGetGpuInfo(gpu->obj, 418 VK_INFO_TYPE_PHYSICAL_GPU_PERFORMANCE, 419 &size, &gpu->perf); 420 if (err || size != sizeof(gpu->perf)) 421 ERR_EXIT(err); 422 423 /* get queue count */ 424 err = vkGetGpuInfo(gpu->obj, 425 VK_INFO_TYPE_PHYSICAL_GPU_QUEUE_PROPERTIES, 426 &size, NULL); 427 if (err || size % sizeof(gpu->queue_props[0])) 428 ERR_EXIT(err); 429 gpu->queue_count = (uint32_t) (size / sizeof(gpu->queue_props[0])); 430 431 gpu->queue_props = 432 malloc(sizeof(gpu->queue_props[0]) * gpu->queue_count); 433 size = sizeof(gpu->queue_props[0]) * gpu->queue_count; 434 if (!gpu->queue_props) 435 ERR_EXIT(VK_ERROR_OUT_OF_MEMORY); 436 err = vkGetGpuInfo(gpu->obj, 437 VK_INFO_TYPE_PHYSICAL_GPU_QUEUE_PROPERTIES, 438 &size, gpu->queue_props); 439 if (err || size != sizeof(gpu->queue_props[0]) * gpu->queue_count) 440 ERR_EXIT(err); 441 442 /* set up queue requests */ 443 size = sizeof(*gpu->queue_reqs) * gpu->queue_count; 444 gpu->queue_reqs = malloc(sizeof(*gpu->queue_reqs) * gpu->queue_count); 445 if (!gpu->queue_reqs) 446 ERR_EXIT(VK_ERROR_OUT_OF_MEMORY); 447 for (i = 0; i < gpu->queue_count; i++) { 448 gpu->queue_reqs[i].queueNodeIndex = i; 449 gpu->queue_reqs[i].queueCount = gpu->queue_props[i].queueCount; 450 } 451 452 size = sizeof(gpu->memory_props); 453 err = vkGetGpuInfo(gpu->obj, 454 VK_INFO_TYPE_PHYSICAL_GPU_MEMORY_PROPERTIES, 455 &size, &gpu->memory_props); 456 if (err || size != sizeof(gpu->memory_props)) 457 ERR_EXIT(err); 458 459 app_gpu_init_extensions(gpu); 460 app_dev_init(&gpu->dev, gpu); 461 app_dev_init_formats(&gpu->dev); 462} 463 464static void app_gpu_destroy(struct app_gpu *gpu) 465{ 466 app_dev_destroy(&gpu->dev); 467 free(gpu->extensions); 468 free(gpu->queue_reqs); 469 free(gpu->queue_props); 470} 471 472static void app_dev_dump_format_props(const struct app_dev *dev, VkFormat fmt) 473{ 474 const VkFormatProperties *props = &dev->format_props[fmt]; 475 struct { 476 const char *name; 477 VkFlags flags; 478 } tilings[2]; 479 uint32_t i; 480 481 if (!props->linearTilingFeatures && !props->optimalTilingFeatures) 482 return; 483 484 tilings[0].name = "linear"; 485 tilings[0].flags = props->linearTilingFeatures; 486 tilings[1].name = "optimal"; 487 tilings[1].flags = props->optimalTilingFeatures; 488 489 printf("FORMAT_%s\n", vk_format_string(fmt)); 490 for (i = 0; i < ARRAY_SIZE(tilings); i++) { 491 if (!tilings[i].flags) 492 continue; 493 494 printf("\t%s tiling image =%s%s%s\n", tilings[i].name, 495 (tilings[i].flags & VK_FORMAT_SAMPLED_IMAGE_BIT) ? " sampled" : "", 496 (tilings[i].flags & VK_FORMAT_STORAGE_IMAGE_BIT) ? " storage" : "", 497 (tilings[i].flags & VK_FORMAT_STORAGE_IMAGE_ATOMIC_BIT) ? " atomic" : ""); 498 printf("\t%s tiling texel =%s%s%s\n", tilings[i].name, 499 (tilings[i].flags & VK_FORMAT_UNIFORM_TEXEL_BUFFER_BIT) ? " TBO" : "", 500 (tilings[i].flags & VK_FORMAT_STORAGE_TEXEL_BUFFER_BIT) ? " IBO" : "", 501 (tilings[i].flags & VK_FORMAT_STORAGE_TEXEL_BUFFER_ATOMIC_BIT) ? " atomic" : ""); 502 printf("\t%s tiling attachment =%s%s%s\n", tilings[i].name, 503 (tilings[i].flags & VK_FORMAT_COLOR_ATTACHMENT_BIT) ? " color" : "", 504 (tilings[i].flags & VK_FORMAT_COLOR_ATTACHMENT_BLEND_BIT) ? " blend" : "", 505 (tilings[i].flags & VK_FORMAT_DEPTH_STENCIL_ATTACHMENT_BIT) ? " depth/stencil" : ""); 506 printf("\t%s tiling vertex = %u\n", tilings[i].name, 507 (bool) (tilings[i].flags & VK_FORMAT_VERTEX_BUFFER_BIT)); 508 printf("\t%s tiling conversion = %u\n", tilings[i].name, 509 (bool) (tilings[i].flags & VK_FORMAT_CONVERSION_BIT)); 510 } 511} 512 513 514static void 515app_dev_dump(const struct app_dev *dev) 516{ 517 VkFormat fmt; 518 519 for (fmt = 0; fmt < VK_NUM_FMT; fmt++) { 520 app_dev_dump_format_props(dev, fmt); 521 } 522} 523 524static void app_gpu_dump_multi_compat(const struct app_gpu *gpu, const struct app_gpu *other, 525 const VkGpuCompatibilityInfo *info) 526{ 527 printf("VkGpuCompatibilityInfo[GPU%d]\n", other->id); 528 529#define TEST(info, b) printf(#b " = %u\n", (bool) (info->compatibilityFlags & VK_GPU_COMPAT_ ##b## _BIT)) 530 TEST(info, ASIC_FEATURES); 531 TEST(info, IQ_MATCH); 532 TEST(info, PEER_TRANSFER); 533 TEST(info, SHARED_MEMORY); 534 TEST(info, SHARED_SYNC); 535 TEST(info, SHARED_GPU0_DISPLAY); 536 TEST(info, SHARED_GPU1_DISPLAY); 537#undef TEST 538} 539 540static void app_gpu_multi_compat(struct app_gpu *gpus, uint32_t gpu_count) 541{ 542 VkResult err; 543 uint32_t i, j; 544 545 for (i = 0; i < gpu_count; i++) { 546 for (j = 0; j < gpu_count; j++) { 547 VkGpuCompatibilityInfo info; 548 549 if (i == j) 550 continue; 551 552 err = vkGetMultiGpuCompatibility(gpus[i].obj, 553 gpus[j].obj, &info); 554 if (err) 555 ERR_EXIT(err); 556 557 app_gpu_dump_multi_compat(&gpus[i], &gpus[j], &info); 558 } 559 } 560} 561 562static void app_gpu_dump_props(const struct app_gpu *gpu) 563{ 564 const VkPhysicalGpuProperties *props = &gpu->props; 565 566 printf("VkPhysicalGpuProperties\n"); 567 printf("\tapiVersion = %u\n", props->apiVersion); 568 printf("\tdriverVersion = %u\n", props->driverVersion); 569 printf("\tvendorId = 0x%04x\n", props->vendorId); 570 printf("\tdeviceId = 0x%04x\n", props->deviceId); 571 printf("\tgpuType = %s\n", vk_gpu_type_string(props->gpuType)); 572 printf("\tgpuName = %s\n", props->gpuName); 573 printf("\tmaxInlineMemoryUpdateSize = %zu\n", props->maxInlineMemoryUpdateSize); 574 printf("\tmaxBoundDescriptorSets = %u\n", props->maxBoundDescriptorSets); 575 printf("\tmaxThreadGroupSize = %u\n", props->maxThreadGroupSize); 576 printf("\ttimestampFrequency = %lu\n", props->timestampFrequency); 577 printf("\tmultiColorAttachmentClears = %u\n", props->multiColorAttachmentClears); 578} 579 580static void app_gpu_dump_perf(const struct app_gpu *gpu) 581{ 582 const VkPhysicalGpuPerformance *perf = &gpu->perf; 583 584 printf("VkPhysicalGpuPerformance\n"); 585 printf("\tmaxGpuClock = %f\n", perf->maxGpuClock); 586 printf("\taluPerClock = %f\n", perf->aluPerClock); 587 printf("\ttexPerClock = %f\n", perf->texPerClock); 588 printf("\tprimsPerClock = %f\n", perf->primsPerClock); 589 printf("\tpixelsPerClock = %f\n", perf->pixelsPerClock); 590} 591 592static void app_gpu_dump_extensions(const struct app_gpu *gpu) 593{ 594 uint32_t i; 595 printf("Extensions"); 596 printf("\tcount = %d\n", gpu->extension_count); 597 printf("\t"); 598 for (i=0; i< gpu->extension_count; i++) { 599 if (i>0) 600 printf(", "); // separator between extension names 601 printf("%s", gpu->extensions[i]); 602 } 603 printf("\n"); 604} 605 606static void app_gpu_dump_queue_props(const struct app_gpu *gpu, uint32_t id) 607{ 608 const VkPhysicalGpuQueueProperties *props = &gpu->queue_props[id]; 609 610 printf("VkPhysicalGpuQueueProperties[%d]\n", id); 611 printf("\tqueueFlags = %c%c%c%c\n", 612 (props->queueFlags & VK_QUEUE_GRAPHICS_BIT) ? 'G' : '.', 613 (props->queueFlags & VK_QUEUE_COMPUTE_BIT) ? 'C' : '.', 614 (props->queueFlags & VK_QUEUE_DMA_BIT) ? 'D' : '.', 615 (props->queueFlags & VK_QUEUE_EXTENDED_BIT) ? 'X' : '.'); 616 printf("\tqueueCount = %u\n", props->queueCount); 617 printf("\tmaxAtomicCounters = %u\n", props->maxAtomicCounters); 618 printf("\tsupportsTimestamps = %u\n", props->supportsTimestamps); 619 printf("\tmaxMemReferences = %u\n", props->maxMemReferences); 620} 621 622static void app_gpu_dump_memory_props(const struct app_gpu *gpu) 623{ 624 const VkPhysicalGpuMemoryProperties *props = &gpu->memory_props; 625 626 printf("VkPhysicalGpuMemoryProperties\n"); 627 printf("\tsupportsMigration = %u\n", props->supportsMigration); 628 printf("\tsupportsPinning = %u\n", props->supportsPinning); 629} 630 631static void app_gpu_dump(const struct app_gpu *gpu) 632{ 633 uint32_t i; 634 635 printf("GPU%u\n", gpu->id); 636 app_gpu_dump_props(gpu); 637 printf("\n"); 638 app_gpu_dump_extensions(gpu); 639 printf("\n"); 640 app_gpu_dump_perf(gpu); 641 printf("\n"); 642 for (i = 0; i < gpu->queue_count; i++) { 643 app_gpu_dump_queue_props(gpu, i); 644 printf("\n"); 645 } 646 app_gpu_dump_memory_props(gpu); 647 printf("\n"); 648 app_dev_dump(&gpu->dev); 649} 650 651int main(int argc, char **argv) 652{ 653 static const VkApplicationInfo app_info = { 654 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, 655 .pNext = NULL, 656 .pAppName = "vkinfo", 657 .appVersion = 1, 658 .pEngineName = "vkinfo", 659 .engineVersion = 1, 660 .apiVersion = VK_API_VERSION, 661 }; 662 static const VkInstanceCreateInfo inst_info = { 663 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 664 .pNext = NULL, 665 .pAppInfo = &app_info, 666 .pAllocCb = NULL, 667 .extensionCount = 0, 668 .ppEnabledExtensionNames = NULL, 669 }; 670 struct app_gpu gpus[MAX_GPUS]; 671 VkPhysicalGpu objs[MAX_GPUS]; 672 VkInstance inst; 673 uint32_t gpu_count, i; 674 VkResult err; 675 676 err = vkCreateInstance(&inst_info, &inst); 677 if (err == VK_ERROR_INCOMPATIBLE_DRIVER) { 678 printf("Cannot find a compatible Vulkan installable client driver " 679 "(ICD).\nExiting ...\n"); 680 fflush(stdout); 681 exit(1); 682 } else if (err) { 683 684 ERR_EXIT(err); 685 } 686 err = vkEnumerateGpus(inst, MAX_GPUS, &gpu_count, objs); 687 if (err) 688 ERR_EXIT(err); 689 690 for (i = 0; i < gpu_count; i++) { 691 app_gpu_init(&gpus[i], i, objs[i]); 692 app_gpu_dump(&gpus[i]); 693 printf("\n\n"); 694 } 695 696 app_gpu_multi_compat(gpus, gpu_count); 697 698 for (i = 0; i < gpu_count; i++) 699 app_gpu_destroy(&gpus[i]); 700 701 vkDestroyInstance(inst); 702 703 return 0; 704} 705