vulkaninfo.c revision d4e49b7247597ede0971205cde2553312680f34c
1/* 2 * Copyright (c) 2015-2016 The Khronos Group Inc. 3 * Copyright (c) 2015-2016 Valve Corporation 4 * Copyright (c) 2015-2016 LunarG, Inc. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com> 19 * Author: David Pinedo <david@lunarg.com> 20 * Author: Mark Lobodzinski <mark@lunarg.com> 21 * Author: Rene Lindsay <rene@lunarg.com> 22 * Author: Jeremy Kniager <jeremyk@lunarg.com> 23 */ 24 25#ifdef __GNUC__ 26#ifndef _POSIX_C_SOURCE 27#define _POSIX_C_SOURCE 200809L 28#endif 29#else 30#define strndup(p, n) strdup(p) 31#endif 32 33#include <assert.h> 34#include <inttypes.h> 35#include <stdbool.h> 36#include <stdio.h> 37#include <stdlib.h> 38#include <string.h> 39 40#ifdef _WIN32 41#include <fcntl.h> 42#include <io.h> 43#endif // _WIN32 44 45#if defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR) 46#include <X11/Xutil.h> 47#endif 48 49#if defined(VK_USE_PLATFORM_MIR_KHR) 50#warning "Vulkaninfo does not have code for Mir at this time" 51#endif 52 53#include <vulkan/vulkan.h> 54 55#define ERR(err) printf("%s:%d: failed with %s\n", __FILE__, __LINE__, VkResultString(err)); 56 57#ifdef _WIN32 58 59#define snprintf _snprintf 60#define strdup _strdup 61 62// Returns nonzero if the console is used only for this process. Will return 63// zero if another process (such as cmd.exe) is also attached. 64static int ConsoleIsExclusive(void) { 65 DWORD pids[2]; 66 DWORD num_pids = GetConsoleProcessList(pids, ARRAYSIZE(pids)); 67 return num_pids <= 1; 68} 69 70#define WAIT_FOR_CONSOLE_DESTROY \ 71 do { \ 72 if (ConsoleIsExclusive()) Sleep(INFINITE); \ 73 } while (0) 74#else 75#define WAIT_FOR_CONSOLE_DESTROY 76#endif 77 78#define ERR_EXIT(err) \ 79 do { \ 80 ERR(err); \ 81 fflush(stdout); \ 82 WAIT_FOR_CONSOLE_DESTROY; \ 83 exit(-1); \ 84 } while (0) 85 86#if defined(NDEBUG) && defined(__GNUC__) 87#define U_ASSERT_ONLY __attribute__((unused)) 88#else 89#define U_ASSERT_ONLY 90#endif 91 92#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 93 94#define MAX_QUEUE_TYPES 5 95#define APP_SHORT_NAME "vulkaninfo" 96 97struct VkStructureHeader { 98 VkStructureType sType; 99 void *pNext; 100}; 101 102struct AppGpu; 103 104struct AppDev { 105 struct AppGpu *gpu; /* point back to the GPU */ 106 107 VkDevice obj; 108 109 VkFormatProperties format_props[VK_FORMAT_RANGE_SIZE]; 110 VkFormatProperties2KHR format_props2[VK_FORMAT_RANGE_SIZE]; 111}; 112 113struct LayerExtensionList { 114 VkLayerProperties layer_properties; 115 uint32_t extension_count; 116 VkExtensionProperties *extension_properties; 117}; 118 119struct AppInstance { 120 VkInstance instance; 121 uint32_t global_layer_count; 122 struct LayerExtensionList *global_layers; 123 uint32_t global_extension_count; 124 VkExtensionProperties *global_extensions; // Instance Extensions 125 126 const char **inst_extensions; 127 uint32_t inst_extensions_count; 128 129 PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR; 130 PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR; 131 PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR; 132 PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR; 133 PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR; 134 PFN_vkGetPhysicalDeviceFormatProperties2KHR vkGetPhysicalDeviceFormatProperties2KHR; 135 PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR vkGetPhysicalDeviceQueueFamilyProperties2KHR; 136 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR; 137 PFN_vkGetPhysicalDeviceMemoryProperties2KHR vkGetPhysicalDeviceMemoryProperties2KHR; 138 PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR vkGetPhysicalDeviceSurfaceCapabilities2KHR; 139 PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT vkGetPhysicalDeviceSurfaceCapabilities2EXT; 140 141 VkSurfaceCapabilitiesKHR surface_capabilities; 142 VkSurfaceCapabilities2KHR surface_capabilities2; 143 VkSharedPresentSurfaceCapabilitiesKHR shared_surface_capabilities; 144 VkSurfaceCapabilities2EXT surface_capabilities2_ext; 145 146 VkSurfaceKHR surface; 147 int width, height; 148 149#ifdef VK_USE_PLATFORM_WIN32_KHR 150 HINSTANCE h_instance; // Windows Instance 151 HWND h_wnd; // window handle 152#elif VK_USE_PLATFORM_XCB_KHR 153 xcb_connection_t *xcb_connection; 154 xcb_screen_t *xcb_screen; 155 xcb_window_t xcb_window; 156#elif VK_USE_PLATFORM_XLIB_KHR 157 Display *xlib_display; 158 Window xlib_window; 159#elif VK_USE_PLATFORM_ANDROID_KHR // TODO 160 ANativeWindow *window; 161#endif 162}; 163 164struct AppGpu { 165 uint32_t id; 166 VkPhysicalDevice obj; 167 168 VkPhysicalDeviceProperties props; 169 VkPhysicalDeviceProperties2KHR props2; 170 171 uint32_t queue_count; 172 VkQueueFamilyProperties *queue_props; 173 VkQueueFamilyProperties2KHR *queue_props2; 174 VkDeviceQueueCreateInfo *queue_reqs; 175 176 struct AppInstance *inst; 177 178 VkPhysicalDeviceMemoryProperties memory_props; 179 VkPhysicalDeviceMemoryProperties2KHR memory_props2; 180 181 VkPhysicalDeviceFeatures features; 182 VkPhysicalDeviceFeatures2KHR features2; 183 VkPhysicalDevice limits; 184 185 uint32_t device_extension_count; 186 VkExtensionProperties *device_extensions; 187 188 struct AppDev dev; 189}; 190 191static VKAPI_ATTR VkBool32 VKAPI_CALL DbgCallback(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, 192 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg, 193 void *pUserData) { 194 char *message = (char *)malloc(strlen(pMsg) + 100); 195 196 assert(message); 197 198 if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { 199 sprintf(message, "ERROR: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg); 200 } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { 201 sprintf(message, "WARNING: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg); 202 } else if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) { 203 sprintf(message, "INFO: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg); 204 } else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) { 205 sprintf(message, "DEBUG: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg); 206 } 207 208 printf("%s\n", message); 209 fflush(stdout); 210 free(message); 211 212 /* 213 * false indicates that layer should not bail-out of an 214 * API call that had validation failures. This may mean that the 215 * app dies inside the driver due to invalid parameter(s). 216 * That's what would happen without validation layers, so we'll 217 * keep that behavior here. 218 */ 219 return false; 220} 221 222static const char *VkResultString(VkResult err) { 223 switch (err) { 224#define STR(r) \ 225 case r: \ 226 return #r 227 STR(VK_SUCCESS); 228 STR(VK_NOT_READY); 229 STR(VK_TIMEOUT); 230 STR(VK_EVENT_SET); 231 STR(VK_EVENT_RESET); 232 STR(VK_ERROR_INITIALIZATION_FAILED); 233 STR(VK_ERROR_OUT_OF_HOST_MEMORY); 234 STR(VK_ERROR_OUT_OF_DEVICE_MEMORY); 235 STR(VK_ERROR_DEVICE_LOST); 236 STR(VK_ERROR_LAYER_NOT_PRESENT); 237 STR(VK_ERROR_EXTENSION_NOT_PRESENT); 238 STR(VK_ERROR_MEMORY_MAP_FAILED); 239 STR(VK_ERROR_INCOMPATIBLE_DRIVER); 240#undef STR 241 default: 242 return "UNKNOWN_RESULT"; 243 } 244} 245 246static const char *VkPhysicalDeviceTypeString(VkPhysicalDeviceType type) { 247 switch (type) { 248#define STR(r) \ 249 case VK_PHYSICAL_DEVICE_TYPE_##r: \ 250 return #r 251 STR(OTHER); 252 STR(INTEGRATED_GPU); 253 STR(DISCRETE_GPU); 254 STR(VIRTUAL_GPU); 255 STR(CPU); 256#undef STR 257 default: 258 return "UNKNOWN_DEVICE"; 259 } 260} 261 262static const char *VkFormatString(VkFormat fmt) { 263 switch (fmt) { 264#define STR(r) \ 265 case VK_FORMAT_##r: \ 266 return #r 267 STR(UNDEFINED); 268 STR(R4G4_UNORM_PACK8); 269 STR(R4G4B4A4_UNORM_PACK16); 270 STR(B4G4R4A4_UNORM_PACK16); 271 STR(R5G6B5_UNORM_PACK16); 272 STR(B5G6R5_UNORM_PACK16); 273 STR(R5G5B5A1_UNORM_PACK16); 274 STR(B5G5R5A1_UNORM_PACK16); 275 STR(A1R5G5B5_UNORM_PACK16); 276 STR(R8_UNORM); 277 STR(R8_SNORM); 278 STR(R8_USCALED); 279 STR(R8_SSCALED); 280 STR(R8_UINT); 281 STR(R8_SINT); 282 STR(R8_SRGB); 283 STR(R8G8_UNORM); 284 STR(R8G8_SNORM); 285 STR(R8G8_USCALED); 286 STR(R8G8_SSCALED); 287 STR(R8G8_UINT); 288 STR(R8G8_SINT); 289 STR(R8G8_SRGB); 290 STR(R8G8B8_UNORM); 291 STR(R8G8B8_SNORM); 292 STR(R8G8B8_USCALED); 293 STR(R8G8B8_SSCALED); 294 STR(R8G8B8_UINT); 295 STR(R8G8B8_SINT); 296 STR(R8G8B8_SRGB); 297 STR(B8G8R8_UNORM); 298 STR(B8G8R8_SNORM); 299 STR(B8G8R8_USCALED); 300 STR(B8G8R8_SSCALED); 301 STR(B8G8R8_UINT); 302 STR(B8G8R8_SINT); 303 STR(B8G8R8_SRGB); 304 STR(R8G8B8A8_UNORM); 305 STR(R8G8B8A8_SNORM); 306 STR(R8G8B8A8_USCALED); 307 STR(R8G8B8A8_SSCALED); 308 STR(R8G8B8A8_UINT); 309 STR(R8G8B8A8_SINT); 310 STR(R8G8B8A8_SRGB); 311 STR(B8G8R8A8_UNORM); 312 STR(B8G8R8A8_SNORM); 313 STR(B8G8R8A8_USCALED); 314 STR(B8G8R8A8_SSCALED); 315 STR(B8G8R8A8_UINT); 316 STR(B8G8R8A8_SINT); 317 STR(B8G8R8A8_SRGB); 318 STR(A8B8G8R8_UNORM_PACK32); 319 STR(A8B8G8R8_SNORM_PACK32); 320 STR(A8B8G8R8_USCALED_PACK32); 321 STR(A8B8G8R8_SSCALED_PACK32); 322 STR(A8B8G8R8_UINT_PACK32); 323 STR(A8B8G8R8_SINT_PACK32); 324 STR(A8B8G8R8_SRGB_PACK32); 325 STR(A2R10G10B10_UNORM_PACK32); 326 STR(A2R10G10B10_SNORM_PACK32); 327 STR(A2R10G10B10_USCALED_PACK32); 328 STR(A2R10G10B10_SSCALED_PACK32); 329 STR(A2R10G10B10_UINT_PACK32); 330 STR(A2R10G10B10_SINT_PACK32); 331 STR(A2B10G10R10_UNORM_PACK32); 332 STR(A2B10G10R10_SNORM_PACK32); 333 STR(A2B10G10R10_USCALED_PACK32); 334 STR(A2B10G10R10_SSCALED_PACK32); 335 STR(A2B10G10R10_UINT_PACK32); 336 STR(A2B10G10R10_SINT_PACK32); 337 STR(R16_UNORM); 338 STR(R16_SNORM); 339 STR(R16_USCALED); 340 STR(R16_SSCALED); 341 STR(R16_UINT); 342 STR(R16_SINT); 343 STR(R16_SFLOAT); 344 STR(R16G16_UNORM); 345 STR(R16G16_SNORM); 346 STR(R16G16_USCALED); 347 STR(R16G16_SSCALED); 348 STR(R16G16_UINT); 349 STR(R16G16_SINT); 350 STR(R16G16_SFLOAT); 351 STR(R16G16B16_UNORM); 352 STR(R16G16B16_SNORM); 353 STR(R16G16B16_USCALED); 354 STR(R16G16B16_SSCALED); 355 STR(R16G16B16_UINT); 356 STR(R16G16B16_SINT); 357 STR(R16G16B16_SFLOAT); 358 STR(R16G16B16A16_UNORM); 359 STR(R16G16B16A16_SNORM); 360 STR(R16G16B16A16_USCALED); 361 STR(R16G16B16A16_SSCALED); 362 STR(R16G16B16A16_UINT); 363 STR(R16G16B16A16_SINT); 364 STR(R16G16B16A16_SFLOAT); 365 STR(R32_UINT); 366 STR(R32_SINT); 367 STR(R32_SFLOAT); 368 STR(R32G32_UINT); 369 STR(R32G32_SINT); 370 STR(R32G32_SFLOAT); 371 STR(R32G32B32_UINT); 372 STR(R32G32B32_SINT); 373 STR(R32G32B32_SFLOAT); 374 STR(R32G32B32A32_UINT); 375 STR(R32G32B32A32_SINT); 376 STR(R32G32B32A32_SFLOAT); 377 STR(R64_UINT); 378 STR(R64_SINT); 379 STR(R64_SFLOAT); 380 STR(R64G64_UINT); 381 STR(R64G64_SINT); 382 STR(R64G64_SFLOAT); 383 STR(R64G64B64_UINT); 384 STR(R64G64B64_SINT); 385 STR(R64G64B64_SFLOAT); 386 STR(R64G64B64A64_UINT); 387 STR(R64G64B64A64_SINT); 388 STR(R64G64B64A64_SFLOAT); 389 STR(B10G11R11_UFLOAT_PACK32); 390 STR(E5B9G9R9_UFLOAT_PACK32); 391 STR(D16_UNORM); 392 STR(X8_D24_UNORM_PACK32); 393 STR(D32_SFLOAT); 394 STR(S8_UINT); 395 STR(D16_UNORM_S8_UINT); 396 STR(D24_UNORM_S8_UINT); 397 STR(D32_SFLOAT_S8_UINT); 398 STR(BC1_RGB_UNORM_BLOCK); 399 STR(BC1_RGB_SRGB_BLOCK); 400 STR(BC2_UNORM_BLOCK); 401 STR(BC2_SRGB_BLOCK); 402 STR(BC3_UNORM_BLOCK); 403 STR(BC3_SRGB_BLOCK); 404 STR(BC4_UNORM_BLOCK); 405 STR(BC4_SNORM_BLOCK); 406 STR(BC5_UNORM_BLOCK); 407 STR(BC5_SNORM_BLOCK); 408 STR(BC6H_UFLOAT_BLOCK); 409 STR(BC6H_SFLOAT_BLOCK); 410 STR(BC7_UNORM_BLOCK); 411 STR(BC7_SRGB_BLOCK); 412 STR(ETC2_R8G8B8_UNORM_BLOCK); 413 STR(ETC2_R8G8B8A1_UNORM_BLOCK); 414 STR(ETC2_R8G8B8A8_UNORM_BLOCK); 415 STR(EAC_R11_UNORM_BLOCK); 416 STR(EAC_R11_SNORM_BLOCK); 417 STR(EAC_R11G11_UNORM_BLOCK); 418 STR(EAC_R11G11_SNORM_BLOCK); 419 STR(ASTC_4x4_UNORM_BLOCK); 420 STR(ASTC_4x4_SRGB_BLOCK); 421 STR(ASTC_5x4_UNORM_BLOCK); 422 STR(ASTC_5x4_SRGB_BLOCK); 423 STR(ASTC_5x5_UNORM_BLOCK); 424 STR(ASTC_5x5_SRGB_BLOCK); 425 STR(ASTC_6x5_UNORM_BLOCK); 426 STR(ASTC_6x5_SRGB_BLOCK); 427 STR(ASTC_6x6_UNORM_BLOCK); 428 STR(ASTC_6x6_SRGB_BLOCK); 429 STR(ASTC_8x5_UNORM_BLOCK); 430 STR(ASTC_8x5_SRGB_BLOCK); 431 STR(ASTC_8x6_UNORM_BLOCK); 432 STR(ASTC_8x6_SRGB_BLOCK); 433 STR(ASTC_8x8_UNORM_BLOCK); 434 STR(ASTC_8x8_SRGB_BLOCK); 435 STR(ASTC_10x5_UNORM_BLOCK); 436 STR(ASTC_10x5_SRGB_BLOCK); 437 STR(ASTC_10x6_UNORM_BLOCK); 438 STR(ASTC_10x6_SRGB_BLOCK); 439 STR(ASTC_10x8_UNORM_BLOCK); 440 STR(ASTC_10x8_SRGB_BLOCK); 441 STR(ASTC_10x10_UNORM_BLOCK); 442 STR(ASTC_10x10_SRGB_BLOCK); 443 STR(ASTC_12x10_UNORM_BLOCK); 444 STR(ASTC_12x10_SRGB_BLOCK); 445 STR(ASTC_12x12_UNORM_BLOCK); 446 STR(ASTC_12x12_SRGB_BLOCK); 447#undef STR 448 default: 449 return "UNKNOWN_FORMAT"; 450 } 451} 452#if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) 453static const char *VkPresentModeString(VkPresentModeKHR mode) { 454 switch (mode) { 455#define STR(r) \ 456 case VK_PRESENT_MODE_##r: \ 457 return #r 458 STR(IMMEDIATE_KHR); 459 STR(MAILBOX_KHR); 460 STR(FIFO_KHR); 461 STR(FIFO_RELAXED_KHR); 462#undef STR 463 default: 464 return "UNKNOWN_FORMAT"; 465 } 466} 467#endif 468 469static bool CheckExtensionEnabled(const char *extension_to_check, const char **extension_list, uint32_t extension_count) { 470 for (uint32_t i = 0; i < extension_count; i++) { 471 if (!strcmp(extension_to_check, extension_list[i])) return true; 472 } 473 return false; 474} 475 476static void AppDevInitFormats(struct AppDev *dev) { 477 VkFormat f; 478 for (f = 0; f < VK_FORMAT_RANGE_SIZE; f++) { 479 const VkFormat fmt = f; 480 vkGetPhysicalDeviceFormatProperties(dev->gpu->obj, fmt, &dev->format_props[f]); 481 482 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, dev->gpu->inst->inst_extensions, 483 dev->gpu->inst->inst_extensions_count)) { 484 dev->format_props2[f].sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR; 485 dev->format_props2[f].pNext = NULL; 486 dev->gpu->inst->vkGetPhysicalDeviceFormatProperties2KHR(dev->gpu->obj, fmt, &dev->format_props2[f]); 487 } 488 } 489} 490 491static void ExtractVersion(uint32_t version, uint32_t *major, uint32_t *minor, uint32_t *patch) { 492 *major = version >> 22; 493 *minor = (version >> 12) & 0x3ff; 494 *patch = version & 0xfff; 495} 496 497static void AppGetPhysicalDeviceLayerExtensions(struct AppGpu *gpu, char *layer_name, uint32_t *extension_count, 498 VkExtensionProperties **extension_properties) { 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 = vkEnumerateDeviceExtensionProperties(gpu->obj, 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 = vkEnumerateDeviceExtensionProperties(gpu->obj, 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 AppDevInit(struct AppDev *dev, struct AppGpu *gpu) { 521 VkDeviceCreateInfo info = { 522 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, 523 .pNext = NULL, 524 .flags = 0, 525 .queueCreateInfoCount = 0, 526 .pQueueCreateInfos = NULL, 527 .enabledLayerCount = 0, 528 .ppEnabledLayerNames = NULL, 529 .enabledExtensionCount = 0, 530 .ppEnabledExtensionNames = NULL, 531 }; 532 VkResult U_ASSERT_ONLY err; 533 534 // Device extensions 535 AppGetPhysicalDeviceLayerExtensions(gpu, NULL, &gpu->device_extension_count, &gpu->device_extensions); 536 537 fflush(stdout); 538 539 /* request all queues */ 540 info.queueCreateInfoCount = gpu->queue_count; 541 info.pQueueCreateInfos = gpu->queue_reqs; 542 543 info.enabledLayerCount = 0; 544 info.ppEnabledLayerNames = NULL; 545 info.enabledExtensionCount = 0; 546 info.ppEnabledExtensionNames = NULL; 547 dev->gpu = gpu; 548 err = vkCreateDevice(gpu->obj, &info, NULL, &dev->obj); 549 if (err) ERR_EXIT(err); 550} 551 552static void AppDevDestroy(struct AppDev *dev) { 553 vkDeviceWaitIdle(dev->obj); 554 vkDestroyDevice(dev->obj, NULL); 555} 556 557static void AppGetGlobalLayerExtensions(char *layer_name, uint32_t *extension_count, VkExtensionProperties **extension_properties) { 558 VkResult err; 559 uint32_t ext_count = 0; 560 VkExtensionProperties *ext_ptr = NULL; 561 562 /* repeat get until VK_INCOMPLETE goes away */ 563 do { 564 // gets the extension count if the last parameter is NULL 565 err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, NULL); 566 assert(!err); 567 568 if (ext_ptr) { 569 free(ext_ptr); 570 } 571 ext_ptr = malloc(ext_count * sizeof(VkExtensionProperties)); 572 // gets the extension properties if the last parameter is not NULL 573 err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, ext_ptr); 574 } while (err == VK_INCOMPLETE); 575 assert(!err); 576 *extension_count = ext_count; 577 *extension_properties = ext_ptr; 578} 579 580/* Gets a list of layer and instance extensions */ 581static void AppGetInstanceExtensions(struct AppInstance *inst) { 582 VkResult U_ASSERT_ONLY err; 583 584 uint32_t count = 0; 585 586 /* Scan layers */ 587 VkLayerProperties *global_layer_properties = NULL; 588 struct LayerExtensionList *global_layers = NULL; 589 590 do { 591 err = vkEnumerateInstanceLayerProperties(&count, NULL); 592 assert(!err); 593 594 if (global_layer_properties) { 595 free(global_layer_properties); 596 } 597 global_layer_properties = malloc(sizeof(VkLayerProperties) * count); 598 assert(global_layer_properties); 599 600 if (global_layers) { 601 free(global_layers); 602 } 603 global_layers = malloc(sizeof(struct LayerExtensionList) * count); 604 assert(global_layers); 605 606 err = vkEnumerateInstanceLayerProperties(&count, global_layer_properties); 607 } while (err == VK_INCOMPLETE); 608 assert(!err); 609 610 inst->global_layer_count = count; 611 inst->global_layers = global_layers; 612 613 for (uint32_t i = 0; i < inst->global_layer_count; i++) { 614 VkLayerProperties *src_info = &global_layer_properties[i]; 615 struct LayerExtensionList *dst_info = &inst->global_layers[i]; 616 memcpy(&dst_info->layer_properties, src_info, sizeof(VkLayerProperties)); 617 618 // Save away layer extension info for report 619 // Gets layer extensions, if first parameter is not NULL 620 AppGetGlobalLayerExtensions(src_info->layerName, &dst_info->extension_count, &dst_info->extension_properties); 621 } 622 free(global_layer_properties); 623 624 // Collect global extensions 625 inst->global_extension_count = 0; 626 // Gets instance extensions, if no layer was specified in the first 627 // paramteter 628 AppGetGlobalLayerExtensions(NULL, &inst->global_extension_count, &inst->global_extensions); 629} 630 631static void AppCreateInstance(struct AppInstance *inst) { 632 AppGetInstanceExtensions(inst); 633 634//---Build a list of extensions to load--- 635 636 const char *info_instance_extensions[] = {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 637 VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME, 638 VK_KHR_SURFACE_EXTENSION_NAME, 639 VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, 640 VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 641#ifdef VK_USE_PLATFORM_WIN32_KHR 642 VK_KHR_WIN32_SURFACE_EXTENSION_NAME 643#elif VK_USE_PLATFORM_XCB_KHR 644 VK_KHR_XCB_SURFACE_EXTENSION_NAME 645#elif VK_USE_PLATFORM_XLIB_KHR 646 VK_KHR_XLIB_SURFACE_EXTENSION_NAME 647#elif VK_USE_PLATFORM_WAYLAND_KHR 648 VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME 649#elif VK_USE_PLATFORM_ANDROID_KHR 650 VK_KHR_ANDROID_SURFACE_EXTENSION_NAME 651#endif 652 }; 653 uint32_t info_instance_extensions_count = ARRAY_SIZE(info_instance_extensions); 654 inst->inst_extensions = malloc(sizeof(char *) * ARRAY_SIZE(info_instance_extensions)); 655 inst->inst_extensions_count = 0; 656 657 for (uint32_t k = 0; (k < info_instance_extensions_count); k++) { 658 for (uint32_t j = 0; (j < inst->global_extension_count); j++) { 659 const char *found_name = inst->global_extensions[j].extensionName; 660 if (!strcmp(info_instance_extensions[k], found_name)) { 661 inst->inst_extensions[inst->inst_extensions_count++] = info_instance_extensions[k]; 662 break; 663 } 664 } 665 } 666 667 //---------------------------------------- 668 669 const VkApplicationInfo app_info = { 670 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, 671 .pNext = NULL, 672 .pApplicationName = APP_SHORT_NAME, 673 .applicationVersion = 1, 674 .pEngineName = APP_SHORT_NAME, 675 .engineVersion = 1, 676 .apiVersion = VK_API_VERSION_1_0, 677 }; 678 679 VkInstanceCreateInfo inst_info = {.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 680 .pNext = NULL, 681 .pApplicationInfo = &app_info, 682 .enabledLayerCount = 0, 683 .ppEnabledLayerNames = NULL, 684 .enabledExtensionCount = inst->inst_extensions_count, 685 .ppEnabledExtensionNames = inst->inst_extensions}; 686 687 VkDebugReportCallbackCreateInfoEXT dbg_info; 688 memset(&dbg_info, 0, sizeof(dbg_info)); 689 dbg_info.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; 690 dbg_info.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_INFORMATION_BIT_EXT; 691 dbg_info.pfnCallback = DbgCallback; 692 inst_info.pNext = &dbg_info; 693 694 VkResult U_ASSERT_ONLY err; 695 err = vkCreateInstance(&inst_info, NULL, &inst->instance); 696 if (err == VK_ERROR_INCOMPATIBLE_DRIVER) { 697 printf("Cannot create Vulkan instance.\n"); 698 ERR_EXIT(err); 699 } else if (err) { 700 ERR_EXIT(err); 701 } 702 703 inst->vkGetPhysicalDeviceSurfaceSupportKHR = 704 (PFN_vkGetPhysicalDeviceSurfaceSupportKHR)vkGetInstanceProcAddr(inst->instance, "vkGetPhysicalDeviceSurfaceSupportKHR"); 705 inst->vkGetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)vkGetInstanceProcAddr( 706 inst->instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"); 707 inst->vkGetPhysicalDeviceSurfaceFormatsKHR = 708 (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)vkGetInstanceProcAddr(inst->instance, "vkGetPhysicalDeviceSurfaceFormatsKHR"); 709 inst->vkGetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)vkGetInstanceProcAddr( 710 inst->instance, "vkGetPhysicalDeviceSurfacePresentModesKHR"); 711 inst->vkGetPhysicalDeviceProperties2KHR = 712 (PFN_vkGetPhysicalDeviceProperties2KHR)vkGetInstanceProcAddr(inst->instance, "vkGetPhysicalDeviceProperties2KHR"); 713 inst->vkGetPhysicalDeviceFormatProperties2KHR = (PFN_vkGetPhysicalDeviceFormatProperties2KHR)vkGetInstanceProcAddr( 714 inst->instance, "vkGetPhysicalDeviceFormatProperties2KHR"); 715 inst->vkGetPhysicalDeviceQueueFamilyProperties2KHR = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)vkGetInstanceProcAddr( 716 inst->instance, "vkGetPhysicalDeviceQueueFamilyProperties2KHR"); 717 inst->vkGetPhysicalDeviceFeatures2KHR = 718 (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(inst->instance, "vkGetPhysicalDeviceFeatures2KHR"); 719 inst->vkGetPhysicalDeviceMemoryProperties2KHR = (PFN_vkGetPhysicalDeviceMemoryProperties2KHR)vkGetInstanceProcAddr( 720 inst->instance, "vkGetPhysicalDeviceMemoryProperties2KHR"); 721 inst->vkGetPhysicalDeviceSurfaceCapabilities2KHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR)vkGetInstanceProcAddr( 722 inst->instance, "vkGetPhysicalDeviceSurfaceCapabilities2KHR"); 723 inst->vkGetPhysicalDeviceSurfaceCapabilities2EXT = (PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT)vkGetInstanceProcAddr( 724 inst->instance, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"); 725} 726 727//----------------------------------------------------------- 728 729static void AppDestroyInstance(struct AppInstance *inst) { 730 free(inst->global_extensions); 731 for (uint32_t i = 0; i < inst->global_layer_count; i++) { 732 free(inst->global_layers[i].extension_properties); 733 } 734 free(inst->global_layers); 735 free((char**)inst->inst_extensions); 736 vkDestroyInstance(inst->instance, NULL); 737} 738 739static void AppGpuInit(struct AppGpu *gpu, struct AppInstance *inst, uint32_t id, VkPhysicalDevice obj) { 740 uint32_t i; 741 742 memset(gpu, 0, sizeof(*gpu)); 743 744 gpu->id = id; 745 gpu->obj = obj; 746 gpu->inst = inst; 747 748 vkGetPhysicalDeviceProperties(gpu->obj, &gpu->props); 749 750 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, 751 gpu->inst->inst_extensions_count)) { 752 gpu->props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; 753 gpu->props2.pNext = NULL; 754 755 inst->vkGetPhysicalDeviceProperties2KHR(gpu->obj, &gpu->props2); 756 } 757 758 /* get queue count */ 759 vkGetPhysicalDeviceQueueFamilyProperties(gpu->obj, &gpu->queue_count, NULL); 760 761 gpu->queue_props = malloc(sizeof(gpu->queue_props[0]) * gpu->queue_count); 762 763 if (!gpu->queue_props) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); 764 vkGetPhysicalDeviceQueueFamilyProperties(gpu->obj, &gpu->queue_count, gpu->queue_props); 765 766 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, 767 gpu->inst->inst_extensions_count)) { 768 gpu->queue_props2 = malloc(sizeof(gpu->queue_props2[0]) * gpu->queue_count); 769 770 if (!gpu->queue_props2) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); 771 772 for (i = 0; i < gpu->queue_count; i++) { 773 gpu->queue_props2[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR; 774 gpu->queue_props2[i].pNext = NULL; 775 } 776 777 inst->vkGetPhysicalDeviceQueueFamilyProperties2KHR(gpu->obj, &gpu->queue_count, gpu->queue_props2); 778 } 779 780 /* set up queue requests */ 781 gpu->queue_reqs = malloc(sizeof(*gpu->queue_reqs) * gpu->queue_count); 782 if (!gpu->queue_reqs) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); 783 for (i = 0; i < gpu->queue_count; i++) { 784 float *queue_priorities = malloc(gpu->queue_props[i].queueCount * sizeof(float)); 785 if (!queue_priorities) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); 786 memset(queue_priorities, 0, gpu->queue_props[i].queueCount * sizeof(float)); 787 788 gpu->queue_reqs[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 789 gpu->queue_reqs[i].pNext = NULL; 790 gpu->queue_reqs[i].flags = 0; 791 gpu->queue_reqs[i].queueFamilyIndex = i; 792 gpu->queue_reqs[i].queueCount = gpu->queue_props[i].queueCount; 793 gpu->queue_reqs[i].pQueuePriorities = queue_priorities; 794 } 795 796 vkGetPhysicalDeviceMemoryProperties(gpu->obj, &gpu->memory_props); 797 798 vkGetPhysicalDeviceFeatures(gpu->obj, &gpu->features); 799 800 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, 801 gpu->inst->inst_extensions_count)) { 802 gpu->memory_props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR; 803 gpu->memory_props2.pNext = NULL; 804 805 inst->vkGetPhysicalDeviceMemoryProperties2KHR(gpu->obj, &gpu->memory_props2); 806 807 gpu->features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; 808 gpu->features2.pNext = NULL; 809 810 inst->vkGetPhysicalDeviceFeatures2KHR(gpu->obj, &gpu->features2); 811 } 812 813 AppDevInit(&gpu->dev, gpu); 814 AppDevInitFormats(&gpu->dev); 815} 816 817static void AppGpuDestroy(struct AppGpu *gpu) { 818 AppDevDestroy(&gpu->dev); 819 free(gpu->device_extensions); 820 821 for (uint32_t i = 0; i < gpu->queue_count; i++) { 822 free((void *)gpu->queue_reqs[i].pQueuePriorities); 823 } 824 free(gpu->queue_reqs); 825 826 free(gpu->queue_props); 827 if (CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, 828 gpu->inst->inst_extensions_count)) { 829 free(gpu->queue_props2); 830 } 831} 832 833// clang-format off 834 835//----------------------------------------------------------- 836 837//---------------------------Win32--------------------------- 838#ifdef VK_USE_PLATFORM_WIN32_KHR 839 840// MS-Windows event handling function: 841LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 842 return (DefWindowProc(hWnd, uMsg, wParam, lParam)); 843} 844 845static void AppCreateWin32Window(struct AppInstance *inst) { 846 inst->h_instance = GetModuleHandle(NULL); 847 848 WNDCLASSEX win_class; 849 850 // Initialize the window class structure: 851 win_class.cbSize = sizeof(WNDCLASSEX); 852 win_class.style = CS_HREDRAW | CS_VREDRAW; 853 win_class.lpfnWndProc = WndProc; 854 win_class.cbClsExtra = 0; 855 win_class.cbWndExtra = 0; 856 win_class.hInstance = inst->h_instance; 857 win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION); 858 win_class.hCursor = LoadCursor(NULL, IDC_ARROW); 859 win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 860 win_class.lpszMenuName = NULL; 861 win_class.lpszClassName = APP_SHORT_NAME; 862 win_class.hInstance = inst->h_instance; 863 win_class.hIconSm = LoadIcon(NULL, IDI_WINLOGO); 864 // Register window class: 865 if (!RegisterClassEx(&win_class)) { 866 // It didn't work, so try to give a useful error: 867 printf("Failed to register the window class!\n"); 868 fflush(stdout); 869 exit(1); 870 } 871 // Create window with the registered class: 872 RECT wr = { 0, 0, inst->width, inst->height }; 873 AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); 874 inst->h_wnd = CreateWindowEx(0, 875 APP_SHORT_NAME, // class name 876 APP_SHORT_NAME, // app name 877 //WS_VISIBLE | WS_SYSMENU | 878 WS_OVERLAPPEDWINDOW, // window style 879 100, 100, // x/y coords 880 wr.right - wr.left, // width 881 wr.bottom - wr.top, // height 882 NULL, // handle to parent 883 NULL, // handle to menu 884 inst->h_instance, // hInstance 885 NULL); // no extra parameters 886 if (!inst->h_wnd) { 887 // It didn't work, so try to give a useful error: 888 printf("Failed to create a window!\n"); 889 fflush(stdout); 890 exit(1); 891 } 892} 893 894static void AppCreateWin32Surface(struct AppInstance *inst) { 895 VkResult U_ASSERT_ONLY err; 896 VkWin32SurfaceCreateInfoKHR createInfo; 897 createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; 898 createInfo.pNext = NULL; 899 createInfo.flags = 0; 900 createInfo.hinstance = inst->h_instance; 901 createInfo.hwnd = inst->h_wnd; 902 err = vkCreateWin32SurfaceKHR(inst->instance, &createInfo, NULL, &inst->surface); 903 assert(!err); 904} 905 906static void AppDestroyWin32Window(struct AppInstance *inst) { 907 DestroyWindow(inst->h_wnd); 908} 909#endif //VK_USE_PLATFORM_WIN32_KHR 910//----------------------------------------------------------- 911 912#if defined(VK_USE_PLATFORM_XCB_KHR) || \ 913 defined(VK_USE_PLATFORM_XLIB_KHR) || \ 914 defined(VK_USE_PLATFORM_WIN32_KHR) 915static void AppDestroySurface(struct AppInstance *inst) { //same for all platforms 916 vkDestroySurfaceKHR(inst->instance, inst->surface, NULL); 917} 918#endif 919 920//----------------------------XCB---------------------------- 921 922#ifdef VK_USE_PLATFORM_XCB_KHR 923static void AppCreateXcbWindow(struct AppInstance *inst) { 924 //--Init Connection-- 925 const xcb_setup_t *setup; 926 xcb_screen_iterator_t iter; 927 int scr; 928 929 inst->xcb_connection = xcb_connect(NULL, &scr); 930 if (inst->xcb_connection == NULL) { 931 printf("XCB failed to connect to the X server.\nExiting ...\n"); 932 fflush(stdout); 933 exit(1); 934 } 935 936 int conn_error = xcb_connection_has_error(inst->xcb_connection); 937 if (conn_error) { 938 printf("XCB failed to connect to the X server due to error:%d.\nExiting ...\n", conn_error); 939 fflush(stdout); 940 exit(1); 941 } 942 943 setup = xcb_get_setup(inst->xcb_connection); 944 iter = xcb_setup_roots_iterator(setup); 945 while (scr-- > 0) { 946 xcb_screen_next(&iter); 947 } 948 949 inst->xcb_screen = iter.data; 950 //------------------- 951 952 inst->xcb_window = xcb_generate_id(inst->xcb_connection); 953 xcb_create_window(inst->xcb_connection, XCB_COPY_FROM_PARENT, inst->xcb_window, 954 inst->xcb_screen->root, 0, 0, inst->width, inst->height, 0, 955 XCB_WINDOW_CLASS_INPUT_OUTPUT, inst->xcb_screen->root_visual, 956 0, NULL); 957 958 xcb_intern_atom_cookie_t cookie = xcb_intern_atom(inst->xcb_connection, 1, 12, "WM_PROTOCOLS"); 959 xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(inst->xcb_connection, cookie, 0); 960 free(reply); 961} 962 963static void AppCreateXcbSurface(struct AppInstance *inst) { 964 VkResult U_ASSERT_ONLY err; 965 VkXcbSurfaceCreateInfoKHR xcb_createInfo; 966 xcb_createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; 967 xcb_createInfo.pNext = NULL; 968 xcb_createInfo.flags = 0; 969 xcb_createInfo.connection = inst->xcb_connection; 970 xcb_createInfo.window = inst->xcb_window; 971 err = vkCreateXcbSurfaceKHR(inst->instance, &xcb_createInfo, NULL, &inst->surface); 972 assert(!err); 973} 974 975static void AppDestroyXcbWindow(struct AppInstance *inst) { 976 xcb_destroy_window(inst->xcb_connection, inst->xcb_window); 977 xcb_disconnect(inst->xcb_connection); 978} 979//VK_USE_PLATFORM_XCB_KHR 980//----------------------------------------------------------- 981 982//----------------------------XLib--------------------------- 983#elif VK_USE_PLATFORM_XLIB_KHR 984static void AppCreateXlibWindow(struct AppInstance *inst) { 985 long visualMask = VisualScreenMask; 986 int numberOfVisuals; 987 988 inst->xlib_display = XOpenDisplay(NULL); 989 if (inst->xlib_display == NULL) { 990 printf("XLib failed to connect to the X server.\nExiting ...\n"); 991 fflush(stdout); 992 exit(1); 993 } 994 995 XVisualInfo vInfoTemplate={}; 996 vInfoTemplate.screen = DefaultScreen(inst->xlib_display); 997 XVisualInfo *visualInfo = XGetVisualInfo(inst->xlib_display, visualMask, 998 &vInfoTemplate, &numberOfVisuals); 999 inst->xlib_window = XCreateWindow( 1000 inst->xlib_display, RootWindow(inst->xlib_display, vInfoTemplate.screen), 0, 0, 1001 inst->width, inst->height, 0, visualInfo->depth, InputOutput, 1002 visualInfo->visual, 0, NULL); 1003 1004 XSync(inst->xlib_display,false); 1005} 1006 1007static void AppCreateXlibSurface(struct AppInstance *inst) { 1008 VkResult U_ASSERT_ONLY err; 1009 VkXlibSurfaceCreateInfoKHR createInfo; 1010 createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; 1011 createInfo.pNext = NULL; 1012 createInfo.flags = 0; 1013 createInfo.dpy = inst->xlib_display; 1014 createInfo.window = inst->xlib_window; 1015 err = vkCreateXlibSurfaceKHR(inst->instance, &createInfo, NULL, &inst->surface); 1016 assert(!err); 1017} 1018 1019static void AppDestroyXlibWindow(struct AppInstance *inst) { 1020 XDestroyWindow(inst->xlib_display, inst->xlib_window); 1021 XCloseDisplay(inst->xlib_display); 1022} 1023#endif //VK_USE_PLATFORM_XLIB_KHR 1024//----------------------------------------------------------- 1025 1026#if defined(VK_USE_PLATFORM_XCB_KHR) || \ 1027 defined(VK_USE_PLATFORM_XLIB_KHR) || \ 1028 defined(VK_USE_PLATFORM_WIN32_KHR) 1029static int AppDumpSurfaceFormats(struct AppInstance *inst, struct AppGpu *gpu){ 1030 // Get the list of VkFormat's that are supported: 1031 VkResult U_ASSERT_ONLY err; 1032 uint32_t format_count = 0; 1033 err = inst->vkGetPhysicalDeviceSurfaceFormatsKHR(gpu->obj, inst->surface, &format_count, NULL); 1034 assert(!err); 1035 1036 VkSurfaceFormatKHR *surf_formats = (VkSurfaceFormatKHR *)malloc(format_count * sizeof(VkSurfaceFormatKHR)); 1037 if (!surf_formats) 1038 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); 1039 err = inst->vkGetPhysicalDeviceSurfaceFormatsKHR(gpu->obj, inst->surface, &format_count, surf_formats); 1040 assert(!err); 1041 printf("Formats:\t\tcount = %d\n", format_count); 1042 1043 for (uint32_t i = 0; i < format_count; i++) { 1044 printf("\t%s\n", VkFormatString(surf_formats[i].format)); 1045 } 1046 fflush(stdout); 1047 1048 free(surf_formats); 1049 return format_count; 1050} 1051 1052static int AppDumpSurfacePresentModes(struct AppInstance *inst, struct AppGpu *gpu) { 1053 // Get the list of VkPresentMode's that are supported: 1054 VkResult U_ASSERT_ONLY err; 1055 uint32_t present_mode_count = 0; 1056 err = inst->vkGetPhysicalDeviceSurfacePresentModesKHR(gpu->obj, inst->surface, &present_mode_count, NULL); 1057 assert(!err); 1058 1059 VkPresentModeKHR *surf_present_modes = (VkPresentModeKHR *)malloc(present_mode_count * sizeof(VkPresentInfoKHR)); 1060 if (!surf_present_modes) 1061 ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); 1062 err = inst->vkGetPhysicalDeviceSurfacePresentModesKHR(gpu->obj, inst->surface, &present_mode_count, surf_present_modes); 1063 assert(!err); 1064 printf("Present Modes:\t\tcount = %d\n", present_mode_count); 1065 1066 for (uint32_t i = 0; i < present_mode_count; i++) { 1067 printf("\t%s\n", VkPresentModeString(surf_present_modes[i])); 1068 } 1069 printf("\n"); 1070 fflush(stdout); 1071 1072 free(surf_present_modes); 1073 return present_mode_count; 1074} 1075 1076static void AppDumpSurfaceCapabilities(struct AppInstance *inst, struct AppGpu *gpu) { 1077 if (CheckExtensionEnabled(VK_KHR_SURFACE_EXTENSION_NAME, gpu->inst->inst_extensions, gpu->inst->inst_extensions_count)) { 1078 1079 inst->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu->obj, inst->surface, &inst->surface_capabilities); 1080 1081 printf("\nVkSurfaceCapabilitiesKHR:\n"); 1082 printf("=========================\n\n"); 1083 printf("\tminImageCount = %u\n", inst->surface_capabilities.minImageCount); 1084 printf("\tmaxImageCount = %u\n", inst->surface_capabilities.maxImageCount); 1085 printf("\tcurrentExtent:\n"); 1086 printf("\t\twidth = %u\n", inst->surface_capabilities.currentExtent.width); 1087 printf("\t\theight = %u\n", inst->surface_capabilities.currentExtent.height); 1088 printf("\tminImageExtent:\n"); 1089 printf("\t\twidth = %u\n", inst->surface_capabilities.minImageExtent.width); 1090 printf("\t\theight = %u\n", inst->surface_capabilities.minImageExtent.height); 1091 printf("\tmaxImageExtent:\n"); 1092 printf("\t\twidth = %u\n", inst->surface_capabilities.maxImageExtent.width); 1093 printf("\t\theight = %u\n", inst->surface_capabilities.maxImageExtent.height); 1094 printf("\tmaxImageArrayLayers = %u\n", inst->surface_capabilities.maxImageArrayLayers); 1095 printf("\tsupportedTransform:\n"); 1096 if (inst->surface_capabilities.supportedTransforms == 0) { printf("\t\tNone\n"); } 1097 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR\n"); } 1098 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR\n"); } 1099 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR\n"); } 1100 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR\n"); } 1101 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR\n"); } 1102 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR\n"); } 1103 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR\n"); } 1104 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR\n"); } 1105 if (inst->surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_INHERIT_BIT_KHR\n"); } 1106 printf("\tcurrentTransform:\n"); 1107 if (inst->surface_capabilities.currentTransform == 0) { printf("\t\tNone\n"); } 1108 if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR\n"); } 1109 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR\n"); } 1110 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR\n"); } 1111 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR\n"); } 1112 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR\n"); } 1113 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR\n"); } 1114 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR\n"); } 1115 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR\n"); } 1116 else if (inst->surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR) { printf("\t\tVK_SURFACE_TRANSFORM_INHERIT_BIT_KHR\n"); } 1117 printf("\tsupportedCompositeAlpha:\n"); 1118 if (inst->surface_capabilities.supportedCompositeAlpha == 0) { printf("\t\tNone\n"); } 1119 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) { printf("\t\tVK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR\n"); } 1120 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR) { printf("\t\tVK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR\n"); } 1121 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR) { printf("\t\tVK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR\n"); } 1122 if (inst->surface_capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) { printf("\t\tVK_COMPOSITE_ALPHA_INHERIT_BIT_KHR\n"); } 1123 printf("\tsupportedUsageFlags:\n"); 1124 if (inst->surface_capabilities.supportedUsageFlags == 0) { printf("\t\tNone\n"); } 1125 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) { printf("\t\tVK_IMAGE_USAGE_TRANSFER_SRC_BIT\n"); } 1126 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) { printf("\t\tVK_IMAGE_USAGE_TRANSFER_DST_BIT\n"); } 1127 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) { printf("\t\tVK_IMAGE_USAGE_SAMPLED_BIT\n"); } 1128 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT) { printf("\t\tVK_IMAGE_USAGE_STORAGE_BIT\n"); } 1129 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { printf("\t\tVK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT\n"); } 1130 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { printf("\t\tVK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT\n"); } 1131 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) { printf("\t\tVK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT\n"); } 1132 if (inst->surface_capabilities.supportedUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) { printf("\t\tVK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT\n"); } 1133 1134 // Get additional surface capability information from vkGetPhysicalDeviceSurfaceCapabilities2EXT 1135 if (CheckExtensionEnabled(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME, gpu->inst->inst_extensions, gpu->inst->inst_extensions_count)) { 1136 memset(&inst->surface_capabilities2_ext, 0, sizeof(VkSurfaceCapabilities2EXT)); 1137 inst->surface_capabilities2_ext.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT; 1138 inst->surface_capabilities2_ext.pNext = NULL; 1139 1140 inst->vkGetPhysicalDeviceSurfaceCapabilities2EXT(gpu->obj, inst->surface, &inst->surface_capabilities2_ext); 1141 1142 printf("\nVkSurfaceCapabilities2EXT:\n"); 1143 printf("==========================\n\n"); 1144 printf("\tsupportedSurfaceCounters:\n"); 1145 if (inst->surface_capabilities2_ext.supportedSurfaceCounters == 0) { printf("\t\tNone\n"); } 1146 if (inst->surface_capabilities2_ext.supportedSurfaceCounters & VK_SURFACE_COUNTER_VBLANK_EXT) { printf("\t\tVK_SURFACE_COUNTER_VBLANK_EXT\n"); } 1147 } 1148 1149 // Get additional surface capability information from vkGetPhysicalDeviceSurfaceCapabilities2KHR 1150 if (CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, gpu->inst->inst_extensions, gpu->inst->inst_extensions_count)) { 1151 if (CheckExtensionEnabled(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, gpu->inst->inst_extensions, gpu->inst->inst_extensions_count)) { 1152 inst->shared_surface_capabilities.sType = VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR; 1153 inst->shared_surface_capabilities.pNext = NULL; 1154 inst->surface_capabilities2.pNext = &inst->shared_surface_capabilities; 1155 } else { 1156 inst->surface_capabilities2.pNext = NULL; 1157 } 1158 1159 inst->surface_capabilities2.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR; 1160 1161 VkPhysicalDeviceSurfaceInfo2KHR surface_info; 1162 surface_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR; 1163 surface_info.pNext = NULL; 1164 surface_info.surface = inst->surface; 1165 1166 inst->vkGetPhysicalDeviceSurfaceCapabilities2KHR(gpu->obj, &surface_info, &inst->surface_capabilities2); 1167 1168 void *place = inst->surface_capabilities2.pNext; 1169 while (place) { 1170 struct VkStructureHeader* work = (struct VkStructureHeader*) place; 1171 if (work->sType == VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR) { 1172 printf("\nVkSharedPresentSurfaceCapabilitiesKHR:\n"); 1173 printf("========================================\n"); 1174 VkSharedPresentSurfaceCapabilitiesKHR* shared_surface_capabilities = (VkSharedPresentSurfaceCapabilitiesKHR*)place; 1175 printf("\tsharedPresentSupportedUsageFlags:\n"); 1176 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags == 0) { printf("\t\tNone\n"); } 1177 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) { printf("\t\tVK_IMAGE_USAGE_TRANSFER_SRC_BIT\n"); } 1178 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) { printf("\t\tVK_IMAGE_USAGE_TRANSFER_DST_BIT\n"); } 1179 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) { printf("\t\tVK_IMAGE_USAGE_SAMPLED_BIT\n"); } 1180 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_STORAGE_BIT) { printf("\t\tVK_IMAGE_USAGE_STORAGE_BIT\n"); } 1181 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { printf("\t\tVK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT\n"); } 1182 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { printf("\t\tVK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT\n"); } 1183 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) { printf("\t\tVK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT\n"); } 1184 if (shared_surface_capabilities->sharedPresentSupportedUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) { printf("\t\tVK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT\n"); } 1185 } 1186 1187 place = work->pNext; 1188 } 1189 } 1190 } 1191} 1192 1193#endif 1194 1195static void AppDevDumpFormatProps(const struct AppDev *dev, VkFormat fmt) 1196{ 1197 const VkFormatProperties *props = &dev->format_props[fmt]; 1198 struct { 1199 const char *name; 1200 VkFlags flags; 1201 } features[3]; 1202 1203 features[0].name = "linearTiling FormatFeatureFlags"; 1204 features[0].flags = props->linearTilingFeatures; 1205 features[1].name = "optimalTiling FormatFeatureFlags"; 1206 features[1].flags = props->optimalTilingFeatures; 1207 features[2].name = "bufferFeatures FormatFeatureFlags"; 1208 features[2].flags = props->bufferFeatures; 1209 1210 printf("\nFORMAT_%s:", VkFormatString(fmt)); 1211 for (uint32_t i = 0; i < ARRAY_SIZE(features); i++) { 1212 printf("\n\t%s:", features[i].name); 1213 if (features[i].flags == 0) { 1214 printf("\n\t\tNone"); 1215 } else { 1216 printf("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", 1217 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT" : ""), //0x0001 1218 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_BIT" : ""), //0x0002 1219 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT" : ""), //0x0004 1220 ((features[i].flags & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT" : ""), //0x0008 1221 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT" : ""), //0x0010 1222 ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT" : ""), //0x0020 1223 ((features[i].flags & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_VERTEX_BUFFER_BIT" : ""), //0x0040 1224 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT" : ""), //0x0080 1225 ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT" : ""), //0x0100 1226 ((features[i].flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) ? "\n\t\tVK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT" : ""), //0x0200 1227 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_SRC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_SRC_BIT" : ""), //0x0400 1228 ((features[i].flags & VK_FORMAT_FEATURE_BLIT_DST_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_DST_BIT" : ""), //0x0800 1229 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT" : ""), //0x1000 1230 ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG) ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG" : ""), //0x2000 1231 ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR) ? "\n\t\tVK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR" : ""), //0x4000 1232 ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR) ? "\n\t\tVK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR" : "")); //0x8000 1233 } 1234 } 1235 printf("\n"); 1236} 1237 1238static void 1239AppDevDump(const struct AppDev *dev) 1240{ 1241 printf("Format Properties:\n"); 1242 printf("=================="); 1243 VkFormat fmt; 1244 1245 for (fmt = 0; fmt < VK_FORMAT_RANGE_SIZE; fmt++) { 1246 AppDevDumpFormatProps(dev, fmt); 1247 } 1248} 1249 1250#ifdef _WIN32 1251#define PRINTF_SIZE_T_SPECIFIER "%Iu" 1252#else 1253#define PRINTF_SIZE_T_SPECIFIER "%zu" 1254#endif 1255 1256static void AppGpuDumpFeatures(const struct AppGpu *gpu) 1257{ 1258 const VkPhysicalDeviceFeatures *features = &gpu->features; 1259 1260 printf("VkPhysicalDeviceFeatures:\n"); 1261 printf("=========================\n"); 1262 1263 printf("\trobustBufferAccess = %u\n", features->robustBufferAccess ); 1264 printf("\tfullDrawIndexUint32 = %u\n", features->fullDrawIndexUint32 ); 1265 printf("\timageCubeArray = %u\n", features->imageCubeArray ); 1266 printf("\tindependentBlend = %u\n", features->independentBlend ); 1267 printf("\tgeometryShader = %u\n", features->geometryShader ); 1268 printf("\ttessellationShader = %u\n", features->tessellationShader ); 1269 printf("\tsampleRateShading = %u\n", features->sampleRateShading ); 1270 printf("\tdualSrcBlend = %u\n", features->dualSrcBlend ); 1271 printf("\tlogicOp = %u\n", features->logicOp ); 1272 printf("\tmultiDrawIndirect = %u\n", features->multiDrawIndirect ); 1273 printf("\tdrawIndirectFirstInstance = %u\n", features->drawIndirectFirstInstance ); 1274 printf("\tdepthClamp = %u\n", features->depthClamp ); 1275 printf("\tdepthBiasClamp = %u\n", features->depthBiasClamp ); 1276 printf("\tfillModeNonSolid = %u\n", features->fillModeNonSolid ); 1277 printf("\tdepthBounds = %u\n", features->depthBounds ); 1278 printf("\twideLines = %u\n", features->wideLines ); 1279 printf("\tlargePoints = %u\n", features->largePoints ); 1280 printf("\talphaToOne = %u\n", features->alphaToOne ); 1281 printf("\tmultiViewport = %u\n", features->multiViewport ); 1282 printf("\tsamplerAnisotropy = %u\n", features->samplerAnisotropy ); 1283 printf("\ttextureCompressionETC2 = %u\n", features->textureCompressionETC2 ); 1284 printf("\ttextureCompressionASTC_LDR = %u\n", features->textureCompressionASTC_LDR ); 1285 printf("\ttextureCompressionBC = %u\n", features->textureCompressionBC ); 1286 printf("\tocclusionQueryPrecise = %u\n", features->occlusionQueryPrecise ); 1287 printf("\tpipelineStatisticsQuery = %u\n", features->pipelineStatisticsQuery ); 1288 printf("\tvertexPipelineStoresAndAtomics = %u\n", features->vertexPipelineStoresAndAtomics ); 1289 printf("\tfragmentStoresAndAtomics = %u\n", features->fragmentStoresAndAtomics ); 1290 printf("\tshaderTessellationAndGeometryPointSize = %u\n", features->shaderTessellationAndGeometryPointSize ); 1291 printf("\tshaderImageGatherExtended = %u\n", features->shaderImageGatherExtended ); 1292 printf("\tshaderStorageImageExtendedFormats = %u\n", features->shaderStorageImageExtendedFormats ); 1293 printf("\tshaderStorageImageMultisample = %u\n", features->shaderStorageImageMultisample ); 1294 printf("\tshaderStorageImageReadWithoutFormat = %u\n", features->shaderStorageImageReadWithoutFormat ); 1295 printf("\tshaderStorageImageWriteWithoutFormat = %u\n", features->shaderStorageImageWriteWithoutFormat ); 1296 printf("\tshaderUniformBufferArrayDynamicIndexing = %u\n", features->shaderUniformBufferArrayDynamicIndexing); 1297 printf("\tshaderSampledImageArrayDynamicIndexing = %u\n", features->shaderSampledImageArrayDynamicIndexing ); 1298 printf("\tshaderStorageBufferArrayDynamicIndexing = %u\n", features->shaderStorageBufferArrayDynamicIndexing); 1299 printf("\tshaderStorageImageArrayDynamicIndexing = %u\n", features->shaderStorageImageArrayDynamicIndexing ); 1300 printf("\tshaderClipDistance = %u\n", features->shaderClipDistance ); 1301 printf("\tshaderCullDistance = %u\n", features->shaderCullDistance ); 1302 printf("\tshaderFloat64 = %u\n", features->shaderFloat64 ); 1303 printf("\tshaderInt64 = %u\n", features->shaderInt64 ); 1304 printf("\tshaderInt16 = %u\n", features->shaderInt16 ); 1305 printf("\tshaderResourceResidency = %u\n", features->shaderResourceResidency ); 1306 printf("\tshaderResourceMinLod = %u\n", features->shaderResourceMinLod ); 1307 printf("\tsparseBinding = %u\n", features->sparseBinding ); 1308 printf("\tsparseResidencyBuffer = %u\n", features->sparseResidencyBuffer ); 1309 printf("\tsparseResidencyImage2D = %u\n", features->sparseResidencyImage2D ); 1310 printf("\tsparseResidencyImage3D = %u\n", features->sparseResidencyImage3D ); 1311 printf("\tsparseResidency2Samples = %u\n", features->sparseResidency2Samples ); 1312 printf("\tsparseResidency4Samples = %u\n", features->sparseResidency4Samples ); 1313 printf("\tsparseResidency8Samples = %u\n", features->sparseResidency8Samples ); 1314 printf("\tsparseResidency16Samples = %u\n", features->sparseResidency16Samples ); 1315 printf("\tsparseResidencyAliased = %u\n", features->sparseResidencyAliased ); 1316 printf("\tvariableMultisampleRate = %u\n", features->variableMultisampleRate ); 1317 printf("\tinheritedQueries = %u\n", features->inheritedQueries ); 1318} 1319 1320static void AppDumpSparseProps(const VkPhysicalDeviceSparseProperties *sparse_props) 1321{ 1322 1323 printf("\tVkPhysicalDeviceSparseProperties:\n"); 1324 printf("\t---------------------------------\n"); 1325 1326 printf("\t\tresidencyStandard2DBlockShape = %u\n", sparse_props->residencyStandard2DBlockShape ); 1327 printf("\t\tresidencyStandard2DMultisampleBlockShape = %u\n", sparse_props->residencyStandard2DMultisampleBlockShape); 1328 printf("\t\tresidencyStandard3DBlockShape = %u\n", sparse_props->residencyStandard3DBlockShape ); 1329 printf("\t\tresidencyAlignedMipSize = %u\n", sparse_props->residencyAlignedMipSize ); 1330 printf("\t\tresidencyNonResidentStrict = %u\n", sparse_props->residencyNonResidentStrict ); 1331} 1332 1333static void AppDumpLimits(const VkPhysicalDeviceLimits *limits) 1334{ 1335 printf("\tVkPhysicalDeviceLimits:\n"); 1336 printf("\t-----------------------\n"); 1337 printf("\t\tmaxImageDimension1D = %u\n", limits->maxImageDimension1D ); 1338 printf("\t\tmaxImageDimension2D = %u\n", limits->maxImageDimension2D ); 1339 printf("\t\tmaxImageDimension3D = %u\n", limits->maxImageDimension3D ); 1340 printf("\t\tmaxImageDimensionCube = %u\n", limits->maxImageDimensionCube ); 1341 printf("\t\tmaxImageArrayLayers = %u\n", limits->maxImageArrayLayers ); 1342 printf("\t\tmaxTexelBufferElements = 0x%" PRIxLEAST32 "\n", limits->maxTexelBufferElements ); 1343 printf("\t\tmaxUniformBufferRange = 0x%" PRIxLEAST32 "\n", limits->maxUniformBufferRange ); 1344 printf("\t\tmaxStorageBufferRange = 0x%" PRIxLEAST32 "\n", limits->maxStorageBufferRange ); 1345 printf("\t\tmaxPushConstantsSize = %u\n", limits->maxPushConstantsSize ); 1346 printf("\t\tmaxMemoryAllocationCount = %u\n", limits->maxMemoryAllocationCount ); 1347 printf("\t\tmaxSamplerAllocationCount = %u\n", limits->maxSamplerAllocationCount ); 1348 printf("\t\tbufferImageGranularity = 0x%" PRIxLEAST64 "\n", limits->bufferImageGranularity ); 1349 printf("\t\tsparseAddressSpaceSize = 0x%" PRIxLEAST64 "\n", limits->sparseAddressSpaceSize ); 1350 printf("\t\tmaxBoundDescriptorSets = %u\n", limits->maxBoundDescriptorSets ); 1351 printf("\t\tmaxPerStageDescriptorSamplers = %u\n", limits->maxPerStageDescriptorSamplers ); 1352 printf("\t\tmaxPerStageDescriptorUniformBuffers = %u\n", limits->maxPerStageDescriptorUniformBuffers ); 1353 printf("\t\tmaxPerStageDescriptorStorageBuffers = %u\n", limits->maxPerStageDescriptorStorageBuffers ); 1354 printf("\t\tmaxPerStageDescriptorSampledImages = %u\n", limits->maxPerStageDescriptorSampledImages ); 1355 printf("\t\tmaxPerStageDescriptorStorageImages = %u\n", limits->maxPerStageDescriptorStorageImages ); 1356 printf("\t\tmaxPerStageDescriptorInputAttachments = %u\n", limits->maxPerStageDescriptorInputAttachments ); 1357 printf("\t\tmaxPerStageResources = %u\n", limits->maxPerStageResources ); 1358 printf("\t\tmaxDescriptorSetSamplers = %u\n", limits->maxDescriptorSetSamplers ); 1359 printf("\t\tmaxDescriptorSetUniformBuffers = %u\n", limits->maxDescriptorSetUniformBuffers ); 1360 printf("\t\tmaxDescriptorSetUniformBuffersDynamic = %u\n", limits->maxDescriptorSetUniformBuffersDynamic ); 1361 printf("\t\tmaxDescriptorSetStorageBuffers = %u\n", limits->maxDescriptorSetStorageBuffers ); 1362 printf("\t\tmaxDescriptorSetStorageBuffersDynamic = %u\n", limits->maxDescriptorSetStorageBuffersDynamic ); 1363 printf("\t\tmaxDescriptorSetSampledImages = %u\n", limits->maxDescriptorSetSampledImages ); 1364 printf("\t\tmaxDescriptorSetStorageImages = %u\n", limits->maxDescriptorSetStorageImages ); 1365 printf("\t\tmaxDescriptorSetInputAttachments = %u\n", limits->maxDescriptorSetInputAttachments ); 1366 printf("\t\tmaxVertexInputAttributes = %u\n", limits->maxVertexInputAttributes ); 1367 printf("\t\tmaxVertexInputBindings = %u\n", limits->maxVertexInputBindings ); 1368 printf("\t\tmaxVertexInputAttributeOffset = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputAttributeOffset ); 1369 printf("\t\tmaxVertexInputBindingStride = 0x%" PRIxLEAST32 "\n", limits->maxVertexInputBindingStride ); 1370 printf("\t\tmaxVertexOutputComponents = %u\n", limits->maxVertexOutputComponents ); 1371 printf("\t\tmaxTessellationGenerationLevel = %u\n", limits->maxTessellationGenerationLevel ); 1372 printf("\t\tmaxTessellationPatchSize = %u\n", limits->maxTessellationPatchSize ); 1373 printf("\t\tmaxTessellationControlPerVertexInputComponents = %u\n", limits->maxTessellationControlPerVertexInputComponents ); 1374 printf("\t\tmaxTessellationControlPerVertexOutputComponents = %u\n", limits->maxTessellationControlPerVertexOutputComponents); 1375 printf("\t\tmaxTessellationControlPerPatchOutputComponents = %u\n", limits->maxTessellationControlPerPatchOutputComponents ); 1376 printf("\t\tmaxTessellationControlTotalOutputComponents = %u\n", limits->maxTessellationControlTotalOutputComponents ); 1377 printf("\t\tmaxTessellationEvaluationInputComponents = %u\n", limits->maxTessellationEvaluationInputComponents ); 1378 printf("\t\tmaxTessellationEvaluationOutputComponents = %u\n", limits->maxTessellationEvaluationOutputComponents ); 1379 printf("\t\tmaxGeometryShaderInvocations = %u\n", limits->maxGeometryShaderInvocations ); 1380 printf("\t\tmaxGeometryInputComponents = %u\n", limits->maxGeometryInputComponents ); 1381 printf("\t\tmaxGeometryOutputComponents = %u\n", limits->maxGeometryOutputComponents ); 1382 printf("\t\tmaxGeometryOutputVertices = %u\n", limits->maxGeometryOutputVertices ); 1383 printf("\t\tmaxGeometryTotalOutputComponents = %u\n", limits->maxGeometryTotalOutputComponents ); 1384 printf("\t\tmaxFragmentInputComponents = %u\n", limits->maxFragmentInputComponents ); 1385 printf("\t\tmaxFragmentOutputAttachments = %u\n", limits->maxFragmentOutputAttachments ); 1386 printf("\t\tmaxFragmentDualSrcAttachments = %u\n", limits->maxFragmentDualSrcAttachments ); 1387 printf("\t\tmaxFragmentCombinedOutputResources = %u\n", limits->maxFragmentCombinedOutputResources ); 1388 printf("\t\tmaxComputeSharedMemorySize = 0x%" PRIxLEAST32 "\n", limits->maxComputeSharedMemorySize ); 1389 printf("\t\tmaxComputeWorkGroupCount[0] = %u\n", limits->maxComputeWorkGroupCount[0] ); 1390 printf("\t\tmaxComputeWorkGroupCount[1] = %u\n", limits->maxComputeWorkGroupCount[1] ); 1391 printf("\t\tmaxComputeWorkGroupCount[2] = %u\n", limits->maxComputeWorkGroupCount[2] ); 1392 printf("\t\tmaxComputeWorkGroupInvocations = %u\n", limits->maxComputeWorkGroupInvocations ); 1393 printf("\t\tmaxComputeWorkGroupSize[0] = %u\n", limits->maxComputeWorkGroupSize[0] ); 1394 printf("\t\tmaxComputeWorkGroupSize[1] = %u\n", limits->maxComputeWorkGroupSize[1] ); 1395 printf("\t\tmaxComputeWorkGroupSize[2] = %u\n", limits->maxComputeWorkGroupSize[2] ); 1396 printf("\t\tsubPixelPrecisionBits = %u\n", limits->subPixelPrecisionBits ); 1397 printf("\t\tsubTexelPrecisionBits = %u\n", limits->subTexelPrecisionBits ); 1398 printf("\t\tmipmapPrecisionBits = %u\n", limits->mipmapPrecisionBits ); 1399 printf("\t\tmaxDrawIndexedIndexValue = %u\n", limits->maxDrawIndexedIndexValue ); 1400 printf("\t\tmaxDrawIndirectCount = %u\n", limits->maxDrawIndirectCount ); 1401 printf("\t\tmaxSamplerLodBias = %f\n", limits->maxSamplerLodBias ); 1402 printf("\t\tmaxSamplerAnisotropy = %f\n", limits->maxSamplerAnisotropy ); 1403 printf("\t\tmaxViewports = %u\n", limits->maxViewports ); 1404 printf("\t\tmaxViewportDimensions[0] = %u\n", limits->maxViewportDimensions[0] ); 1405 printf("\t\tmaxViewportDimensions[1] = %u\n", limits->maxViewportDimensions[1] ); 1406 printf("\t\tviewportBoundsRange[0] =%13f\n", limits->viewportBoundsRange[0] ); 1407 printf("\t\tviewportBoundsRange[1] =%13f\n", limits->viewportBoundsRange[1] ); 1408 printf("\t\tviewportSubPixelBits = %u\n", limits->viewportSubPixelBits ); 1409 printf("\t\tminMemoryMapAlignment = " PRINTF_SIZE_T_SPECIFIER "\n", limits->minMemoryMapAlignment ); 1410 printf("\t\tminTexelBufferOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->minTexelBufferOffsetAlignment ); 1411 printf("\t\tminUniformBufferOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->minUniformBufferOffsetAlignment ); 1412 printf("\t\tminStorageBufferOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->minStorageBufferOffsetAlignment ); 1413 printf("\t\tminTexelOffset =%3d\n", limits->minTexelOffset ); 1414 printf("\t\tmaxTexelOffset =%3d\n", limits->maxTexelOffset ); 1415 printf("\t\tminTexelGatherOffset =%3d\n", limits->minTexelGatherOffset ); 1416 printf("\t\tmaxTexelGatherOffset =%3d\n", limits->maxTexelGatherOffset ); 1417 printf("\t\tminInterpolationOffset =%9f\n", limits->minInterpolationOffset ); 1418 printf("\t\tmaxInterpolationOffset =%9f\n", limits->maxInterpolationOffset ); 1419 printf("\t\tsubPixelInterpolationOffsetBits = %u\n", limits->subPixelInterpolationOffsetBits ); 1420 printf("\t\tmaxFramebufferWidth = %u\n", limits->maxFramebufferWidth ); 1421 printf("\t\tmaxFramebufferHeight = %u\n", limits->maxFramebufferHeight ); 1422 printf("\t\tmaxFramebufferLayers = %u\n", limits->maxFramebufferLayers ); 1423 printf("\t\tframebufferColorSampleCounts = %u\n", limits->framebufferColorSampleCounts ); 1424 printf("\t\tframebufferDepthSampleCounts = %u\n", limits->framebufferDepthSampleCounts ); 1425 printf("\t\tframebufferStencilSampleCounts = %u\n", limits->framebufferStencilSampleCounts ); 1426 printf("\t\tframebufferNoAttachmentsSampleCounts = %u\n", limits->framebufferNoAttachmentsSampleCounts ); 1427 printf("\t\tmaxColorAttachments = %u\n", limits->maxColorAttachments ); 1428 printf("\t\tsampledImageColorSampleCounts = %u\n", limits->sampledImageColorSampleCounts ); 1429 printf("\t\tsampledImageDepthSampleCounts = %u\n", limits->sampledImageDepthSampleCounts ); 1430 printf("\t\tsampledImageStencilSampleCounts = %u\n", limits->sampledImageStencilSampleCounts ); 1431 printf("\t\tsampledImageIntegerSampleCounts = %u\n", limits->sampledImageIntegerSampleCounts ); 1432 printf("\t\tstorageImageSampleCounts = %u\n", limits->storageImageSampleCounts ); 1433 printf("\t\tmaxSampleMaskWords = %u\n", limits->maxSampleMaskWords ); 1434 printf("\t\ttimestampComputeAndGraphics = %u\n", limits->timestampComputeAndGraphics ); 1435 printf("\t\ttimestampPeriod = %f\n", limits->timestampPeriod ); 1436 printf("\t\tmaxClipDistances = %u\n", limits->maxClipDistances ); 1437 printf("\t\tmaxCullDistances = %u\n", limits->maxCullDistances ); 1438 printf("\t\tmaxCombinedClipAndCullDistances = %u\n", limits->maxCombinedClipAndCullDistances ); 1439 printf("\t\tdiscreteQueuePriorities = %u\n", limits->discreteQueuePriorities ); 1440 printf("\t\tpointSizeRange[0] = %f\n", limits->pointSizeRange[0] ); 1441 printf("\t\tpointSizeRange[1] = %f\n", limits->pointSizeRange[1] ); 1442 printf("\t\tlineWidthRange[0] = %f\n", limits->lineWidthRange[0] ); 1443 printf("\t\tlineWidthRange[1] = %f\n", limits->lineWidthRange[1] ); 1444 printf("\t\tpointSizeGranularity = %f\n", limits->pointSizeGranularity ); 1445 printf("\t\tlineWidthGranularity = %f\n", limits->lineWidthGranularity ); 1446 printf("\t\tstrictLines = %u\n", limits->strictLines ); 1447 printf("\t\tstandardSampleLocations = %u\n", limits->standardSampleLocations ); 1448 printf("\t\toptimalBufferCopyOffsetAlignment = 0x%" PRIxLEAST64 "\n", limits->optimalBufferCopyOffsetAlignment ); 1449 printf("\t\toptimalBufferCopyRowPitchAlignment = 0x%" PRIxLEAST64 "\n", limits->optimalBufferCopyRowPitchAlignment ); 1450 printf("\t\tnonCoherentAtomSize = 0x%" PRIxLEAST64 "\n", limits->nonCoherentAtomSize ); 1451} 1452 1453static void AppGpuDumpProps(const struct AppGpu *gpu) 1454{ 1455 const VkPhysicalDeviceProperties *props = &gpu->props; 1456 const uint32_t apiVersion=props->apiVersion; 1457 const uint32_t major = VK_VERSION_MAJOR(apiVersion); 1458 const uint32_t minor = VK_VERSION_MINOR(apiVersion); 1459 const uint32_t patch = VK_VERSION_PATCH(apiVersion); 1460 1461 printf("VkPhysicalDeviceProperties:\n"); 1462 printf("===========================\n"); 1463 printf("\tapiVersion = 0x%" PRIxLEAST32 " (%d.%d.%d)\n", apiVersion, major, minor, patch); 1464 printf("\tdriverVersion = %u (0x%" PRIxLEAST32 ")\n",props->driverVersion, props->driverVersion); 1465 printf("\tvendorID = 0x%04x\n", props->vendorID); 1466 printf("\tdeviceID = 0x%04x\n", props->deviceID); 1467 printf("\tdeviceType = %s\n", VkPhysicalDeviceTypeString(props->deviceType)); 1468 printf("\tdeviceName = %s\n", props->deviceName); 1469 1470 AppDumpLimits(&gpu->props.limits); 1471 AppDumpSparseProps(&gpu->props.sparseProperties); 1472 1473 fflush(stdout); 1474} 1475// clang-format on 1476 1477static void AppDumpExtensions(const char *indent, const char *layer_name, const uint32_t extension_count, 1478 const VkExtensionProperties *extension_properties) { 1479 uint32_t i; 1480 if (layer_name && (strlen(layer_name) > 0)) { 1481 printf("%s%s Extensions", indent, layer_name); 1482 } else { 1483 printf("%sExtensions", indent); 1484 } 1485 printf("\tcount = %d\n", extension_count); 1486 for (i = 0; i < extension_count; i++) { 1487 VkExtensionProperties const *ext_prop = &extension_properties[i]; 1488 1489 printf("%s\t", indent); 1490 printf("%-36s: extension revision %2d\n", ext_prop->extensionName, ext_prop->specVersion); 1491 } 1492 fflush(stdout); 1493} 1494 1495static void AppGpuDumpQueueProps(const struct AppGpu *gpu, uint32_t id) { 1496 const VkQueueFamilyProperties *props = &gpu->queue_props[id]; 1497 1498 printf("VkQueueFamilyProperties[%d]:\n", id); 1499 printf("===========================\n"); 1500 char *sep = ""; // separator character 1501 printf("\tqueueFlags = "); 1502 if (props->queueFlags & VK_QUEUE_GRAPHICS_BIT) { 1503 printf("GRAPHICS"); 1504 sep = " | "; 1505 } 1506 if (props->queueFlags & VK_QUEUE_COMPUTE_BIT) { 1507 printf("%sCOMPUTE", sep); 1508 sep = " | "; 1509 } 1510 if (props->queueFlags & VK_QUEUE_TRANSFER_BIT) { 1511 printf("%sTRANSFER", sep); 1512 sep = " | "; 1513 } 1514 if (props->queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) { 1515 printf("%sSPARSE", sep); 1516 } 1517 printf("\n"); 1518 1519 printf("\tqueueCount = %u\n", props->queueCount); 1520 printf("\ttimestampValidBits = %u\n", props->timestampValidBits); 1521 printf("\tminImageTransferGranularity = (%d, %d, %d)\n", props->minImageTransferGranularity.width, 1522 props->minImageTransferGranularity.height, props->minImageTransferGranularity.depth); 1523 fflush(stdout); 1524} 1525 1526// This prints a number of bytes in a human-readable format according to prefixes of the International System of Quantities (ISQ), 1527// defined in ISO/IEC 80000. The prefixes used here are not SI prefixes, but rather the binary prefixes based on powers of 1024 1528// (kibi-, mebi-, gibi- etc.). 1529#define kBufferSize 32 1530 1531static char *HumanReadable(const size_t sz) { 1532 const char prefixes[] = "KMGTPEZY"; 1533 char buf[kBufferSize]; 1534 int which = -1; 1535 double result = (double)sz; 1536 while (result > 1024 && which < 7) { 1537 result /= 1024; 1538 ++which; 1539 } 1540 1541 char unit[] = "\0i"; 1542 if (which >= 0) { 1543 unit[0] = prefixes[which]; 1544 } 1545 snprintf(buf, kBufferSize, "%.2f %sB", result, unit); 1546 return strndup(buf, kBufferSize); 1547} 1548 1549static void AppGpuDumpMemoryProps(const struct AppGpu *gpu) { 1550 const VkPhysicalDeviceMemoryProperties *props = &gpu->memory_props; 1551 1552 printf("VkPhysicalDeviceMemoryProperties:\n"); 1553 printf("=================================\n"); 1554 printf("\tmemoryTypeCount = %u\n", props->memoryTypeCount); 1555 for (uint32_t i = 0; i < props->memoryTypeCount; i++) { 1556 printf("\tmemoryTypes[%u] :\n", i); 1557 printf("\t\theapIndex = %u\n", props->memoryTypes[i].heapIndex); 1558 printf("\t\tpropertyFlags = 0x%" PRIxLEAST32 ":\n", props->memoryTypes[i].propertyFlags); 1559 1560 // Print each named flag, if it is set. 1561 VkFlags flags = props->memoryTypes[i].propertyFlags; 1562#define PRINT_FLAG(FLAG) \ 1563 if (flags & FLAG) printf("\t\t\t" #FLAG "\n"); 1564 PRINT_FLAG(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) 1565 PRINT_FLAG(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) 1566 PRINT_FLAG(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) 1567 PRINT_FLAG(VK_MEMORY_PROPERTY_HOST_CACHED_BIT) 1568 PRINT_FLAG(VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) 1569#undef PRINT_FLAG 1570 } 1571 printf("\n"); 1572 printf("\tmemoryHeapCount = %u\n", props->memoryHeapCount); 1573 for (uint32_t i = 0; i < props->memoryHeapCount; i++) { 1574 printf("\tmemoryHeaps[%u] :\n", i); 1575 const VkDeviceSize memSize = props->memoryHeaps[i].size; 1576 char *mem_size_human_readable = HumanReadable((const size_t)memSize); 1577 printf("\t\tsize = " PRINTF_SIZE_T_SPECIFIER " (0x%" PRIxLEAST64 ") (%s)\n", (size_t)memSize, memSize, 1578 mem_size_human_readable); 1579 free(mem_size_human_readable); 1580 1581 VkMemoryHeapFlags heap_flags = props->memoryHeaps[i].flags; 1582 printf("\t\tflags:\n\t\t\t"); 1583 printf((heap_flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) ? "VK_MEMORY_HEAP_DEVICE_LOCAL_BIT\n" : "None\n"); 1584 } 1585 fflush(stdout); 1586} 1587 1588static void AppGpuDump(const struct AppGpu *gpu) { 1589 uint32_t i; 1590 1591 printf("\nDevice Properties and Extensions :\n"); 1592 printf("==================================\n"); 1593 printf("GPU%u\n", gpu->id); 1594 AppGpuDumpProps(gpu); 1595 printf("\n"); 1596 AppDumpExtensions("", "Device", gpu->device_extension_count, gpu->device_extensions); 1597 printf("\n"); 1598 for (i = 0; i < gpu->queue_count; i++) { 1599 AppGpuDumpQueueProps(gpu, i); 1600 printf("\n"); 1601 } 1602 AppGpuDumpMemoryProps(gpu); 1603 printf("\n"); 1604 AppGpuDumpFeatures(gpu); 1605 printf("\n"); 1606 AppDevDump(&gpu->dev); 1607} 1608 1609#ifdef _WIN32 1610// Enlarges the console window to have a large scrollback size. 1611static void ConsoleEnlarge() { 1612 HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE); 1613 1614 // make the console window bigger 1615 CONSOLE_SCREEN_BUFFER_INFO csbi; 1616 COORD buffer_size; 1617 if (GetConsoleScreenBufferInfo(console_handle, &csbi)) { 1618 buffer_size.X = csbi.dwSize.X + 30; 1619 buffer_size.Y = 20000; 1620 SetConsoleScreenBufferSize(console_handle, buffer_size); 1621 } 1622 1623 SMALL_RECT r; 1624 r.Left = r.Top = 0; 1625 r.Right = csbi.dwSize.X - 1 + 30; 1626 r.Bottom = 50; 1627 SetConsoleWindowInfo(console_handle, true, &r); 1628 1629 // change the console window title 1630 SetConsoleTitle(TEXT(APP_SHORT_NAME)); 1631} 1632#endif 1633 1634int main(int argc, char **argv) { 1635 uint32_t vulkan_major, vulkan_minor, vulkan_patch; 1636 struct AppGpu *gpus; 1637 VkPhysicalDevice *objs; 1638 uint32_t gpu_count; 1639 VkResult err; 1640 struct AppInstance inst; 1641 1642#ifdef _WIN32 1643 if (ConsoleIsExclusive()) ConsoleEnlarge(); 1644#endif 1645 1646 vulkan_major = VK_VERSION_MAJOR(VK_API_VERSION_1_0); 1647 vulkan_minor = VK_VERSION_MINOR(VK_API_VERSION_1_0); 1648 vulkan_patch = VK_VERSION_PATCH(VK_HEADER_VERSION); 1649 1650 printf("===========\n"); 1651 printf("VULKAN INFO\n"); 1652 printf("===========\n\n"); 1653 printf("Vulkan API Version: %d.%d.%d\n\n", vulkan_major, vulkan_minor, vulkan_patch); 1654 1655 AppCreateInstance(&inst); 1656 1657 printf("\nInstance Extensions:\n"); 1658 printf("====================\n"); 1659 AppDumpExtensions("", "Instance", inst.global_extension_count, inst.global_extensions); 1660 1661 err = vkEnumeratePhysicalDevices(inst.instance, &gpu_count, NULL); 1662 if (err) ERR_EXIT(err); 1663 objs = malloc(sizeof(objs[0]) * gpu_count); 1664 if (!objs) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); 1665 err = vkEnumeratePhysicalDevices(inst.instance, &gpu_count, objs); 1666 if (err) ERR_EXIT(err); 1667 1668 gpus = malloc(sizeof(gpus[0]) * gpu_count); 1669 if (!gpus) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY); 1670 for (uint32_t i = 0; i < gpu_count; i++) { 1671 AppGpuInit(&gpus[i], &inst, i, objs[i]); 1672 printf("\n\n"); 1673 } 1674 1675 //---Layer-Device-Extensions--- 1676 printf("Layers: count = %d\n", inst.global_layer_count); 1677 printf("=======\n"); 1678 for (uint32_t i = 0; i < inst.global_layer_count; i++) { 1679 uint32_t layer_major, layer_minor, layer_patch; 1680 char spec_version[64], layer_version[64]; 1681 VkLayerProperties const *layer_prop = &inst.global_layers[i].layer_properties; 1682 1683 ExtractVersion(layer_prop->specVersion, &layer_major, &layer_minor, &layer_patch); 1684 snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", layer_major, layer_minor, layer_patch); 1685 snprintf(layer_version, sizeof(layer_version), "%d", layer_prop->implementationVersion); 1686 printf("%s (%s) Vulkan version %s, layer version %s\n", layer_prop->layerName, (char *)layer_prop->description, 1687 spec_version, layer_version); 1688 1689 AppDumpExtensions("\t", "Layer", inst.global_layers[i].extension_count, inst.global_layers[i].extension_properties); 1690 1691 char *layer_name = inst.global_layers[i].layer_properties.layerName; 1692 printf("\tDevices \tcount = %d\n", gpu_count); 1693 for (uint32_t j = 0; j < gpu_count; j++) { 1694 printf("\t\tGPU id : %u (%s)\n", j, gpus[j].props.deviceName); 1695 uint32_t count = 0; 1696 VkExtensionProperties *props; 1697 AppGetPhysicalDeviceLayerExtensions(&gpus[j], layer_name, &count, &props); 1698 AppDumpExtensions("\t\t", "Layer-Device", count, props); 1699 free(props); 1700 } 1701 printf("\n"); 1702 } 1703 fflush(stdout); 1704 //----------------------------- 1705 1706 printf("Presentable Surfaces:\n"); 1707 printf("=====================\n"); 1708 inst.width = 256; 1709 inst.height = 256; 1710 int format_count = 0; 1711 int present_mode_count = 0; 1712 1713#if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) 1714 if (getenv("DISPLAY") == NULL) { 1715 printf("'DISPLAY' environment variable not set... Exiting!\n"); 1716 fflush(stdout); 1717 exit(1); 1718 } 1719#endif 1720//--WIN32-- 1721#ifdef VK_USE_PLATFORM_WIN32_KHR 1722 if (CheckExtensionEnabled(VK_KHR_WIN32_SURFACE_EXTENSION_NAME, inst.inst_extensions, inst.inst_extensions_count)) { 1723 AppCreateWin32Window(&inst); 1724 for (uint32_t i = 0; i < gpu_count; i++) { 1725 AppCreateWin32Surface(&inst); 1726 printf("GPU id : %u (%s)\n", i, gpus[i].props.deviceName); 1727 printf("Surface type : %s\n", VK_KHR_WIN32_SURFACE_EXTENSION_NAME); 1728 format_count += AppDumpSurfaceFormats(&inst, &gpus[i]); 1729 present_mode_count += AppDumpSurfacePresentModes(&inst, &gpus[i]); 1730 AppDumpSurfaceCapabilities(&inst, &gpus[i]); 1731 AppDestroySurface(&inst); 1732 } 1733 AppDestroyWin32Window(&inst); 1734 } 1735//--XCB-- 1736#elif VK_USE_PLATFORM_XCB_KHR 1737 if (CheckExtensionEnabled(VK_KHR_XCB_SURFACE_EXTENSION_NAME, inst.inst_extensions, inst.inst_extensions_count)) { 1738 AppCreateXcbWindow(&inst); 1739 for (uint32_t i = 0; i < gpu_count; i++) { 1740 AppCreateXcbSurface(&inst); 1741 printf("GPU id : %u (%s)\n", i, gpus[i].props.deviceName); 1742 printf("Surface type : %s\n", VK_KHR_XCB_SURFACE_EXTENSION_NAME); 1743 format_count += AppDumpSurfaceFormats(&inst, &gpus[i]); 1744 present_mode_count += AppDumpSurfacePresentModes(&inst, &gpus[i]); 1745 AppDumpSurfaceCapabilities(&inst, &gpus[i]); 1746 AppDestroySurface(&inst); 1747 } 1748 AppDestroyXcbWindow(&inst); 1749 } 1750//--XLIB-- 1751#elif VK_USE_PLATFORM_XLIB_KHR 1752 if (CheckExtensionEnabled(VK_KHR_XLIB_SURFACE_EXTENSION_NAME, inst.inst_extensions, inst.inst_extensions_count)) { 1753 AppCreateXlibWindow(&inst); 1754 for (uint32_t i = 0; i < gpu_count; i++) { 1755 AppCreateXlibSurface(&inst); 1756 printf("GPU id : %u (%s)\n", i, gpus[i].props.deviceName); 1757 printf("Surface type : %s\n", VK_KHR_XLIB_SURFACE_EXTENSION_NAME); 1758 format_count += AppDumpSurfaceFormats(&inst, &gpus[i]); 1759 present_mode_count += AppDumpSurfacePresentModes(&inst, &gpus[i]); 1760 AppDumpSurfaceCapabilities(&inst, &gpus[i]); 1761 AppDestroySurface(&inst); 1762 } 1763 AppDestroyXlibWindow(&inst); 1764 } 1765#endif 1766 // TODO: Android / Wayland / MIR 1767 if (!format_count && !present_mode_count) printf("None found\n"); 1768 //--------- 1769 1770 for (uint32_t i = 0; i < gpu_count; i++) { 1771 AppGpuDump(&gpus[i]); 1772 printf("\n\n"); 1773 } 1774 1775 for (uint32_t i = 0; i < gpu_count; i++) AppGpuDestroy(&gpus[i]); 1776 free(gpus); 1777 free(objs); 1778 1779 AppDestroyInstance(&inst); 1780 1781 fflush(stdout); 1782#ifdef _WIN32 1783 if (ConsoleIsExclusive()) Sleep(INFINITE); 1784#endif 1785 1786 return 0; 1787} 1788