From 1586f9cec9d1f44b8d5d2609531fdbecf811fc57 Mon Sep 17 00:00:00 2001 From: Rene Lindsay Date: Fri, 10 Jun 2016 08:26:26 -0700 Subject: [PATCH] Show "Presentable Formats" per GPU for Win32/XCB/XLib Change-Id: I5ef0862326d9a7ce4e59fe7c8947b532f252d604 --- demos/vulkaninfo.c | 482 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 420 insertions(+), 62 deletions(-) diff --git a/demos/vulkaninfo.c b/demos/vulkaninfo.c index 7754625..7d5214e 100644 --- a/demos/vulkaninfo.c +++ b/demos/vulkaninfo.c @@ -18,6 +18,7 @@ * Author: Courtney Goeltzenleuchter * Author: David Pinedo * Author: Mark Lobodzinski + * Author: Rene Lindsay */ #include #include @@ -31,6 +32,10 @@ #include #endif // _WIN32 +#ifdef __linux__ +#include +#endif + #include #define ERR(err) \ @@ -100,7 +105,37 @@ struct app_instance { uint32_t global_layer_count; struct layer_extension_list *global_layers; uint32_t global_extension_count; - VkExtensionProperties *global_extensions; + VkExtensionProperties *global_extensions; //Instance Extensions + + PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR; + PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR; + PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR; + PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR; + + VkSurfaceKHR surface; + int width, height; + +#ifdef VK_USE_PLATFORM_WIN32_KHR + HINSTANCE hInstance; // Windows Instance + HWND hWnd; // window handle +#endif + +#ifdef VK_USE_PLATFORM_XCB_KHR + xcb_connection_t* xcb_connection; + xcb_screen_t* xcb_screen; + xcb_window_t xcb_window; + xcb_intern_atom_reply_t *xcb_wm_delete_window; +#endif + +#ifdef VK_USE_PLATFORM_XLIB_KHR + Display* xlib_display; + Window xlib_window; + Atom xlib_wm_delete_window; +#endif + +#ifdef VK_USE_PLATFORM_ANDROID_KHR //TODO + ANativeWindow* window; +#endif }; struct app_gpu { @@ -524,7 +559,7 @@ app_get_global_layer_extensions(char *layer_name, uint32_t *extension_count, /* repeat get until VK_INCOMPLETE goes away */ do { - err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, + err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, //get extension count NULL); assert(!err); @@ -532,16 +567,99 @@ app_get_global_layer_extensions(char *layer_name, uint32_t *extension_count, free(ext_ptr); } ext_ptr = malloc(ext_count * sizeof(VkExtensionProperties)); - err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, + err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, //get extension properties ext_ptr); } while (err == VK_INCOMPLETE); assert(!err); - *extension_count = ext_count; *extension_properties = ext_ptr; } +static void app_get_instance_extensions(struct app_instance *inst) { //get list of layer and instance extensions + VkResult U_ASSERT_ONLY err; + + uint32_t count = 0; + + /* Scan layers */ + VkLayerProperties *global_layer_properties = NULL; + struct layer_extension_list *global_layers = NULL; + + do { + err = vkEnumerateInstanceLayerProperties(&count, NULL); + assert(!err); + + if (global_layer_properties) { + free(global_layer_properties); + } + global_layer_properties = malloc(sizeof(VkLayerProperties) * count); + assert(global_layer_properties); + + if (global_layers) { + free(global_layers); + } + global_layers = malloc(sizeof(struct layer_extension_list) * count); + assert(global_layers); + + err = vkEnumerateInstanceLayerProperties(&count, global_layer_properties); + } while (err == VK_INCOMPLETE); + assert(!err); + + inst->global_layer_count = count; + inst->global_layers = global_layers; + + for (uint32_t i = 0; i < inst->global_layer_count; i++) { + VkLayerProperties *src_info = &global_layer_properties[i]; + struct layer_extension_list *dst_info = &inst->global_layers[i]; + memcpy(&dst_info->layer_properties, src_info, + sizeof(VkLayerProperties)); + + /* Save away layer extension info for report */ + app_get_global_layer_extensions(src_info->layerName, //get Layer extensions + &dst_info->extension_count, + &dst_info->extension_properties); + } + free(global_layer_properties); + + /* Collect global extensions */ + inst->global_extension_count = 0; + app_get_global_layer_extensions(NULL, &inst->global_extension_count, //get Instance extensions (first param is NULL) + &inst->global_extensions); + +} + static void app_create_instance(struct app_instance *inst) { + app_get_instance_extensions(inst); //get a list of available extensions + + + //---Build a list of extensions to load--- + #define MAX_EXTENSIONS 4 + uint32_t i = 0; + uint32_t ext_count = 0; + const char* ext_names[MAX_EXTENSIONS]; //array of string pointers to extension names + for (i = 0; (i < inst->global_extension_count); i++){ + const char* found_name=inst->global_extensions[i].extensionName; + if (!strcmp(VK_KHR_SURFACE_EXTENSION_NAME, found_name)) ext_names[ext_count++] = VK_KHR_SURFACE_EXTENSION_NAME; + } + + if(ext_count) + for (i = 0; ((i < inst->global_extension_count) && (ext_count < MAX_EXTENSIONS)); i++){ + const char* found_name=inst->global_extensions[i].extensionName; +#ifdef VK_USE_PLATFORM_WIN32_KHR + if(!strcmp(VK_KHR_WIN32_SURFACE_EXTENSION_NAME, found_name)) ext_names[ext_count++] = VK_KHR_WIN32_SURFACE_EXTENSION_NAME; +#endif +#ifdef VK_USE_PLATFORM_XCB_KHR + if(!strcmp(VK_KHR_XCB_SURFACE_EXTENSION_NAME, found_name)) ext_names[ext_count++] = VK_KHR_XCB_SURFACE_EXTENSION_NAME; +#endif +#ifdef VK_USE_PLATFORM_XLIB_KHR + if(!strcmp(VK_KHR_XLIB_SURFACE_EXTENSION_NAME, found_name)) ext_names[ext_count++] = VK_KHR_XLIB_SURFACE_EXTENSION_NAME; +#endif +#ifdef VK_USE_PLATFORM_ANDROID_KHR + if(!strcmp(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, found_name)) ext_names[ext_count++] = VK_KHR_ANDROID_SURFACE_EXTENSION_NAME; +#endif + } + if(ext_count<2) ext_count=0; // Load at least 2 extensions, or none at all. + //---------------------------------------- + const VkApplicationInfo app_info = { .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, .pNext = NULL, @@ -551,65 +669,16 @@ static void app_create_instance(struct app_instance *inst) { .engineVersion = 1, .apiVersion = VK_API_VERSION_1_0, }; + VkInstanceCreateInfo inst_info = { .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .pNext = NULL, .pApplicationInfo = &app_info, .enabledLayerCount = 0, .ppEnabledLayerNames = NULL, - .enabledExtensionCount = 0, - .ppEnabledExtensionNames = NULL, + .enabledExtensionCount = ext_count, + .ppEnabledExtensionNames = ext_names, }; - VkResult U_ASSERT_ONLY err; - - uint32_t count = 0; - - /* Scan layers */ - VkLayerProperties *global_layer_properties = NULL; - struct layer_extension_list *global_layers = NULL; - - do { - err = vkEnumerateInstanceLayerProperties(&count, NULL); - assert(!err); - - if (global_layer_properties) { - free(global_layer_properties); - } - global_layer_properties = malloc(sizeof(VkLayerProperties) * count); - assert(global_layer_properties); - - if (global_layers) { - free(global_layers); - } - global_layers = malloc(sizeof(struct layer_extension_list) * count); - assert(global_layers); - - err = - vkEnumerateInstanceLayerProperties(&count, global_layer_properties); - } while (err == VK_INCOMPLETE); - assert(!err); - - inst->global_layer_count = count; - inst->global_layers = global_layers; - - for (uint32_t i = 0; i < inst->global_layer_count; i++) { - VkLayerProperties *src_info = &global_layer_properties[i]; - struct layer_extension_list *dst_info = &inst->global_layers[i]; - memcpy(&dst_info->layer_properties, src_info, - sizeof(VkLayerProperties)); - - /* Save away layer extension info for report */ - app_get_global_layer_extensions(src_info->layerName, - &dst_info->extension_count, - &dst_info->extension_properties); - } - free(global_layer_properties); - - /* Collect global extensions */ - inst->global_extension_count = 0; - app_get_global_layer_extensions(NULL, &inst->global_extension_count, - &inst->global_extensions); - VkDebugReportCallbackCreateInfoEXT dbg_info; memset(&dbg_info, 0, sizeof(dbg_info)); @@ -620,6 +689,7 @@ static void app_create_instance(struct app_instance *inst) { dbg_info.pfnCallback = dbg_callback; inst_info.pNext = &dbg_info; + VkResult U_ASSERT_ONLY err; err = vkCreateInstance(&inst_info, NULL, &inst->instance); if (err == VK_ERROR_INCOMPATIBLE_DRIVER) { printf("Cannot create Vulkan instance.\n"); @@ -627,8 +697,20 @@ static void app_create_instance(struct app_instance *inst) { } else if (err) { ERR_EXIT(err); } + + if(ext_count>0){ + //--Load Extensions-- +#define GET_INSTANCE_PROC_ADDR(ENTRYPOINT) { inst->ENTRYPOINT = (void*)vkGetInstanceProcAddr(inst->instance, #ENTRYPOINT); } + GET_INSTANCE_PROC_ADDR(vkGetPhysicalDeviceSurfaceSupportKHR ) + GET_INSTANCE_PROC_ADDR(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) + GET_INSTANCE_PROC_ADDR(vkGetPhysicalDeviceSurfaceFormatsKHR ) + GET_INSTANCE_PROC_ADDR(vkGetPhysicalDeviceSurfacePresentModesKHR) +#undef GET_INSTANCE_PROC_ADDR + } } +//----------------------------------------------------------- + static void app_destroy_instance(struct app_instance *inst) { free(inst->global_extensions); vkDestroyInstance(inst->instance, NULL); @@ -691,6 +773,232 @@ static void app_gpu_destroy(struct app_gpu *gpu) { } // clang-format off + +//----------------------------------------------------------- + +//---------------------------Win32--------------------------- +#ifdef VK_USE_PLATFORM_WIN32_KHR + +// MS-Windows event handling function: +LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + switch (uMsg) { + case WM_CLOSE: + PostQuitMessage(WM_QUIT); + break; + case WM_PAINT: + break; + case WM_SIZE: + break; + default: + break; + } + return (DefWindowProc(hWnd, uMsg, wParam, lParam)); +} + +static void app_create_win32_window(struct app_instance *inst) { + inst->hInstance = GetModuleHandle(NULL); + + WNDCLASSEX win_class; + + // Initialize the window class structure: + win_class.cbSize = sizeof(WNDCLASSEX); + win_class.style = CS_HREDRAW | CS_VREDRAW; + win_class.lpfnWndProc = WndProc; + win_class.cbClsExtra = 0; + win_class.cbWndExtra = 0; + win_class.hInstance = inst->hInstance; + win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION); + win_class.hCursor = LoadCursor(NULL, IDC_ARROW); + win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); + win_class.lpszMenuName = NULL; + win_class.lpszClassName = APP_SHORT_NAME; + win_class.hIconSm = LoadIcon(NULL, IDI_WINLOGO); + // Register window class: + if (!RegisterClassEx(&win_class)) { + // It didn't work, so try to give a useful error: + printf("Unexpected error trying to start the application!\n"); + fflush(stdout); + exit(1); + } + // Create window with the registered class: + RECT wr = { 0, 0, inst->width, inst->height }; + AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); + inst->hWnd = CreateWindowEx(0, + APP_SHORT_NAME, // class name + APP_SHORT_NAME, // app name + //WS_VISIBLE | WS_SYSMENU | + WS_OVERLAPPEDWINDOW, // window style + 100, 100, // x/y coords + wr.right - wr.left, // width + wr.bottom - wr.top, // height + NULL, // handle to parent + NULL, // handle to menu + inst->hInstance, // hInstance + NULL); // no extra parameters + if (!inst->hWnd) { + // It didn't work, so try to give a useful error: + printf("Cannot create a window in which to draw!\n"); + fflush(stdout); + exit(1); + } +} + +static void app_create_win32_surface(struct app_instance *inst, struct app_gpu *gpu) { + VkResult U_ASSERT_ONLY err; + VkWin32SurfaceCreateInfoKHR createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.hinstance = inst->hInstance; + createInfo.hwnd = inst->hWnd; + err = vkCreateWin32SurfaceKHR(inst->instance, &createInfo, NULL, &inst->surface); assert(!err); +} + +static void app_destroy_win32_window(struct app_instance *inst) { + DestroyWindow(inst->hWnd); +} +#endif //VK_USE_PLATFORM_WIN32_KHR +//----------------------------------------------------------- + +static void app_destroy_surface(struct app_instance *inst) { //same for all platforms + vkDestroySurfaceKHR(inst->instance, inst->surface, NULL); +} + +//----------------------------XCB---------------------------- +#ifdef VK_USE_PLATFORM_XCB_KHR +static void app_create_xcb_window(struct app_instance *inst) { + //--Init Connection-- + const xcb_setup_t *setup; + xcb_screen_iterator_t iter; + int scr; + + inst->xcb_connection = xcb_connect(NULL, &scr); + if (inst->xcb_connection == NULL) { + printf("Cannot find a compatible Vulkan installable client driver (ICD).\nExiting ...\n"); + fflush(stdout); + exit(1); + } + + setup = xcb_get_setup(inst->xcb_connection); + iter = xcb_setup_roots_iterator(setup); + while (scr-- > 0) + xcb_screen_next(&iter); + + inst->xcb_screen = iter.data; + //------------------- + + uint32_t value_mask, value_list[32]; + inst->xcb_window = xcb_generate_id(inst->xcb_connection); + value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; + value_list[0] = inst->xcb_screen->black_pixel; + value_list[1] = XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_EXPOSURE | + XCB_EVENT_MASK_STRUCTURE_NOTIFY; + + xcb_create_window(inst->xcb_connection, XCB_COPY_FROM_PARENT, inst->xcb_window, + inst->xcb_screen->root, 0, 0, inst->width, inst->height, 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, inst->xcb_screen->root_visual, + value_mask, value_list); + + /* Magic code that will send notification when window is destroyed */ + xcb_intern_atom_cookie_t cookie = xcb_intern_atom(inst->xcb_connection, 1, 12, "WM_PROTOCOLS"); + xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(inst->xcb_connection, cookie, 0); + + xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(inst->xcb_connection, 0, 16, "WM_DELETE_WINDOW"); + inst->xcb_wm_delete_window = xcb_intern_atom_reply(inst->xcb_connection, cookie2, 0); + free(reply); + + xcb_map_window(inst->xcb_connection, inst->xcb_window); + + // Force the x/y coordinates to 100,100 results are identical in consecutive runs + const uint32_t coords[] = {100, 100}; + xcb_configure_window(inst->xcb_connection, inst->xcb_window, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, coords); +} + +static void app_create_xcb_surface(struct app_instance *inst, struct app_gpu *gpu) { + VkResult U_ASSERT_ONLY err; + VkXcbSurfaceCreateInfoKHR xcb_createInfo; + xcb_createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; + xcb_createInfo.pNext = NULL; + xcb_createInfo.flags = 0; + xcb_createInfo.connection = inst->xcb_connection; + xcb_createInfo.window = inst->xcb_window; + err = vkCreateXcbSurfaceKHR(inst->instance, &xcb_createInfo, NULL, &inst->surface); assert(!err); +} + +static void app_destroy_xcb_window(struct app_instance *inst) { + xcb_destroy_window(inst->xcb_connection, inst->xcb_window); + xcb_disconnect(inst->xcb_connection); + free(inst->xcb_wm_delete_window); +} +#endif //VK_USE_PLATFORM_XCB_KHR +//----------------------------------------------------------- + +//----------------------------XLib--------------------------- +#ifdef VK_USE_PLATFORM_XLIB_KHR +static void app_create_xlib_window(struct app_instance *inst) { + inst->xlib_display = XOpenDisplay(NULL); + long visualMask = VisualScreenMask; + int numberOfVisuals; + XVisualInfo vInfoTemplate; + vInfoTemplate.screen = DefaultScreen(inst->xlib_display); + XVisualInfo *visualInfo = XGetVisualInfo(inst->xlib_display, visualMask, + &vInfoTemplate, &numberOfVisuals); + Colormap colormap = XCreateColormap( + inst->xlib_display, RootWindow(inst->xlib_display, vInfoTemplate.screen), + visualInfo->visual, AllocNone); + + XSetWindowAttributes windowAttributes; + windowAttributes.colormap = colormap; + windowAttributes.background_pixel = 0xFFFFFFFF; + windowAttributes.border_pixel = 0; + windowAttributes.event_mask = + KeyPressMask | KeyReleaseMask | StructureNotifyMask | ExposureMask; + + inst->xlib_window = XCreateWindow( + inst->xlib_display, RootWindow(inst->xlib_display, vInfoTemplate.screen), 0, 0, + inst->width, inst->height, 0, visualInfo->depth, InputOutput, + visualInfo->visual, + CWBackPixel | CWBorderPixel | CWEventMask | CWColormap, &windowAttributes); + + XSelectInput(inst->xlib_display, inst->xlib_window, ExposureMask | KeyPressMask); + XMapWindow(inst->xlib_display, inst->xlib_window); + XFlush(inst->xlib_display); + inst->xlib_wm_delete_window = XInternAtom(inst->xlib_display, "WM_DELETE_WINDOW", False); +} + +static void app_create_xlib_surface(struct app_instance *inst, struct app_gpu *gpu) { + VkResult U_ASSERT_ONLY err; + VkXlibSurfaceCreateInfoKHR createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.dpy = inst->xlib_display; + createInfo.window = inst->xlib_window; + err = vkCreateXlibSurfaceKHR(inst->instance, &createInfo, NULL, &inst->surface); assert(!err); +} + +static void app_destroy_xlib_window(struct app_instance *inst) { + XDestroyWindow(inst->xlib_display, inst->xlib_window); + XCloseDisplay(inst->xlib_display); +} +#endif //VK_USE_PLATFORM_XLIB_KHR +//----------------------------------------------------------- + +static int app_dump_surface_formats(struct app_instance *inst, struct app_gpu *gpu){ + // Get the list of VkFormat's that are supported: + VkResult U_ASSERT_ONLY err; + uint32_t formatCount=0; + err = inst->vkGetPhysicalDeviceSurfaceFormatsKHR(gpu->obj, inst->surface, &formatCount, NULL); assert(!err); + VkSurfaceFormatKHR *surfFormats = (VkSurfaceFormatKHR *)malloc(formatCount * sizeof(VkSurfaceFormatKHR)); + err = inst->vkGetPhysicalDeviceSurfaceFormatsKHR(gpu->obj, inst->surface, &formatCount, surfFormats); assert(!err); + printf("Format count = %d\n",formatCount); + uint32_t i; + for(i=0;iformat_props[fmt]; @@ -995,11 +1303,15 @@ static void app_gpu_dump_queue_props(const struct app_gpu *gpu, uint32_t id) { const VkQueueFamilyProperties *props = &gpu->queue_props[id]; printf("VkQueueFamilyProperties[%d]:\n", id); - printf("============================\n"); - printf("\tqueueFlags = %c%c%c\n", - (props->queueFlags & VK_QUEUE_GRAPHICS_BIT) ? 'G' : '.', - (props->queueFlags & VK_QUEUE_COMPUTE_BIT ) ? 'C' : '.', - (props->queueFlags & VK_QUEUE_TRANSFER_BIT) ? 'D' : '.'); + printf("===========================\n"); + char* sep=""; // separator character + printf("\tqueueFlags = "); + if(props->queueFlags & VK_QUEUE_GRAPHICS_BIT) { printf( "GRAPHICS" ); sep=" | "; } + if(props->queueFlags & VK_QUEUE_COMPUTE_BIT ) { printf("%sCOMPUTE" ,sep); sep=" | "; } + if(props->queueFlags & VK_QUEUE_TRANSFER_BIT) { printf("%sTRANSFER",sep); sep=" | "; } + if(props->queueFlags & VK_QUEUE_SPARSE_BINDING_BIT){ printf("%sSPARSE" ,sep); } + printf("\n"); + printf("\tqueueCount = %u\n", props->queueCount); printf("\ttimestampValidBits = %u\n", props->timestampValidBits); printf("\tminImageTransferGranularity = (%d, %d, %d)\n", @@ -1022,7 +1334,7 @@ static void app_gpu_dump_memory_props(const struct app_gpu *gpu) { //Print each named flag, if it is set. VkFlags flags=props->memoryTypes[i].propertyFlags; -#define PRINT_FLAG(FLAG) printf((flags & FLAG) ? "\t\t\t"#FLAG"\n" : ""); +#define PRINT_FLAG(FLAG) if(flags & FLAG) printf("\t\t\t"#FLAG"\n"); PRINT_FLAG(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) PRINT_FLAG(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) PRINT_FLAG(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) @@ -1185,6 +1497,52 @@ int main(int argc, char **argv) { printf("\n\n"); } + printf("Presentable Surface formats:\n"); + printf("============================\n"); + inst.width =256; + inst.height=256; + int formatCount=0; + + //--WIN32-- +#ifdef VK_USE_PLATFORM_WIN32_KHR + app_create_win32_window(&inst); + for (i = 0; i < gpu_count; i++) { + app_create_win32_surface(&inst, &gpus[i]); + printf("GPU id : %u (%s)\n", i, gpus[i].props.deviceName); + printf("Surface type : %s\n", VK_KHR_WIN32_SURFACE_EXTENSION_NAME); + formatCount+=app_dump_surface_formats(&inst, &gpus[i]); + app_destroy_surface(&inst); + } + app_destroy_win32_window(&inst); +#endif + //--XCB-- +#ifdef VK_USE_PLATFORM_XCB_KHR + app_create_xcb_window(&inst); + for (i = 0; i < gpu_count; i++){ + app_create_xcb_surface(&inst,&gpus[i]); + printf("GPU id : %u (%s)\n", i, gpus[i].props.deviceName); + printf("Surface type : %s\n" ,VK_KHR_XCB_SURFACE_EXTENSION_NAME); + formatCount+=app_dump_surface_formats(&inst,&gpus[i]); + app_destroy_surface(&inst); + } + app_destroy_xcb_window(&inst); +#endif + //--XLIB-- +#ifdef VK_USE_PLATFORM_XLIB_KHR + app_create_xlib_window(&inst); + for (i = 0; i < gpu_count; i++){ + app_create_xlib_surface(&inst,&gpus[i]); + printf("GPU id : %u (%s)\n", i, gpus[i].props.deviceName); + printf("Surface type : %s\n" ,VK_KHR_XLIB_SURFACE_EXTENSION_NAME); + formatCount+=app_dump_surface_formats(&inst,&gpus[i]); + app_destroy_surface(&inst); + } + app_destroy_xlib_window(&inst); +#endif + //TODO: Android / Wayland / MIR + if (!formatCount) printf("None found\n"); + //--------- + for (i = 0; i < gpu_count; i++) app_gpu_destroy(&gpus[i]); -- 2.7.4