set cc [C] $cc cflags -I./vendor $cc code { #define VOLK_IMPLEMENTATION #include "volk/volk.h" } $cc proc enumerateDisplays {} Jim_Obj* { FOLK_ENSURE(volkInitialize() == VK_SUCCESS); // Create a minimal Vulkan instance for display enumeration. VkInstance instance; { VkInstanceCreateInfo createInfo = {0}; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; const char* enabledExtensions[] = { VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, #ifdef __APPLE__ VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, #endif }; createInfo.enabledExtensionCount = sizeof(enabledExtensions)/sizeof(enabledExtensions[0]); createInfo.ppEnabledExtensionNames = enabledExtensions; #ifdef __APPLE__ createInfo.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; #endif VkResult res = vkCreateInstance(&createInfo, NULL, &instance); if (res != VK_SUCCESS) { if (res == VK_ERROR_EXTENSION_NOT_PRESENT) { FOLK_ERROR("Unable to enumerate displays (for example, this doesn't work on macOS)"); } FOLK_ERROR("Failed to create Vulkan instance: %d", res); } } volkLoadInstance(instance); uint32_t physicalDeviceCount = 0; vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, NULL); if (physicalDeviceCount == 0) { vkDestroyInstance(instance, NULL); return Jim_NewListObj(interp, NULL, 0); } VkPhysicalDevice physicalDevices[physicalDeviceCount]; vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices); Jim_Obj *allDisplaysList = Jim_NewListObj(interp, NULL, 0); // Enumerate displays for each physical device for (uint32_t devIdx = 0; devIdx < physicalDeviceCount; devIdx++) { VkPhysicalDevice physicalDevice = physicalDevices[devIdx]; uint32_t displayCount; vkGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &displayCount, NULL); VkDisplayPropertiesKHR displayProps[displayCount]; vkGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &displayCount, displayProps); for (uint32_t i = 0; i < displayCount; i++) { uint32_t modeCount; vkGetDisplayModePropertiesKHR(physicalDevice, displayProps[i].display, &modeCount, NULL); VkDisplayModePropertiesKHR modeProps[modeCount]; vkGetDisplayModePropertiesKHR(physicalDevice, displayProps[i].display, &modeCount, modeProps); Jim_Obj *modesList = Jim_NewListObj(interp, NULL, 0); for (uint32_t j = 0; j < modeCount; j++) { Jim_Obj *modeDict = Jim_ObjPrintf("visibleRegion {%u %u} refreshRate %u", modeProps[j].parameters.visibleRegion.width, modeProps[j].parameters.visibleRegion.height, modeProps[j].parameters.refreshRate); Jim_ListAppendElement(interp, modesList, modeDict); } int modesLen; const char *modesStr = Jim_GetString(modesList, &modesLen); Jim_Obj *displayDict = Jim_ObjPrintf("name {%s} physicalDimensions {%u %u} " "physicalResolution {%u %u} modes {%s}", displayProps[i].displayName ? displayProps[i].displayName : "", displayProps[i].physicalDimensions.width, displayProps[i].physicalDimensions.height, displayProps[i].physicalResolution.width, displayProps[i].physicalResolution.height, modesStr); Jim_ListAppendElement(interp, allDisplaysList, displayDict); } } vkDestroyInstance(instance, NULL); return allDisplaysList; } set displayLib [$cc compile] if {![catch {exec pkg-config --exists glfw3}]} { Claim $::thisNode has display glfw with info {name "GLFW (windowed)"} } try { foreach display [$displayLib enumerateDisplays] { Claim $::thisNode has display $display(name) with info $display } } finally { Claim $::thisNode has had displays enumerated }