diff --git a/.gitignore b/.gitignore index 5e1f38c..260b4ef 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,10 @@ /Vulkan-Tools-sdk-1.3.283.0.tar.gz /Vulkan-Tools-sdk-1.3.290.0.tar.gz /Vulkan-Tools-sdk-1.3.296.0.tar.gz +/Vulkan-Tools-sdk-1.4.304.0.tar.gz +/Vulkan-Tools-sdk-1.4.309.0.tar.gz +/Vulkan-Tools-sdk-1.4.313.0.tar.gz +/Vulkan-Tools-sdk-1.4.321.0.tar.gz +/Vulkan-Tools-sdk-1.4.328.1.tar.gz +/Vulkan-Tools-sdk-1.4.341.0.tar.gz +/Vulkan-Tools-sdk-1.4.350.0.tar.gz diff --git a/.packit.yaml b/.packit.yaml new file mode 100644 index 0000000..06febbe --- /dev/null +++ b/.packit.yaml @@ -0,0 +1,13 @@ +# packit config for vulkan-tools +# Build Stage 4 - depends on glslang, vulkan-volk + +jobs: + - job: koji_build + trigger: commit | koji_build + allowed_committers: [all_admins] + dist_git_branches: + - fedora-all + sidetag_group: vulkan-sdk-releases + dependencies: + - glslang + - vulkan-volk diff --git a/0001-cube-Support-runtime-selection-of-WSI-platform.patch b/0001-cube-Support-runtime-selection-of-WSI-platform.patch deleted file mode 100644 index 0256e42..0000000 --- a/0001-cube-Support-runtime-selection-of-WSI-platform.patch +++ /dev/null @@ -1,4020 +0,0 @@ -From f12bc32cddc33f4a37735929632c1a7bb8051755 Mon Sep 17 00:00:00 2001 -From: Charles Giessen -Date: Thu, 5 Sep 2024 12:43:39 -0500 -Subject: [PATCH] cube: Support runtime selection of WSI platform - -By changing the selection of a WSI platform from a build time choice to a -runtime choice, this allows the removal of vkcube-wayland as a separate -binary. - -Use `--wsi ` to choose the WSI platform that vkcube will render -with. The chosen platform must be one that vkcube was compiled with -support for, so directfb will be unavailable without changing the build -parameters to enable it. - -These changes have been made to both vkcube and vkcubepp. - -This includes enabling VK_KHR_display where applicable, which is supported -on linux and windows at the current time. ---- - cube/CMakeLists.txt | 211 ++-- - cube/android/CMakeLists.txt | 2 +- - cube/cube.c | 1626 ++++++++++++++++++++---------- - cube/cube.cpp | 915 ++++++++++++----- - cube/macOS/cube/CMakeLists.txt | 2 +- - cube/macOS/cubepp/CMakeLists.txt | 2 +- - cube/wayland_loader.h | 124 +++ - cube/xcb_loader.h | 129 +++ - cube/xlib_loader.h | 109 ++ - 10 files changed, 2250 insertions(+), 890 deletions(-) - create mode 100644 cube/wayland_loader.h - create mode 100644 cube/xcb_loader.h - create mode 100644 cube/xlib_loader.h - -diff --git a/cube/CMakeLists.txt b/cube/CMakeLists.txt -index 880cf741..4ecd3e36 100644 ---- a/cube/CMakeLists.txt -+++ b/cube/CMakeLists.txt -@@ -61,32 +61,58 @@ if(APPLE) - endif() - endif() - -+if(ANDROID OR APPLE) -+ set(WSI_DISPLAY_DEFAULT_SETTING "OFF") -+else() -+ set(WSI_DISPLAY_DEFAULT_SETTING "ON") -+endif() -+ -+option(BUILD_WSI_DISPLAY_SUPPORT "Build DISPLAY WSI support" ${WSI_DISPLAY_DEFAULT_SETTING}) -+ - if (CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU") - option(BUILD_WSI_XCB_SUPPORT "Build XCB WSI support" ON) - option(BUILD_WSI_XLIB_SUPPORT "Build Xlib WSI support" ON) - option(BUILD_WSI_WAYLAND_SUPPORT "Build Wayland WSI support" ON) - option(BUILD_WSI_DIRECTFB_SUPPORT "Build DirectFB WSI support" OFF) -- set(CUBE_WSI_SELECTION "XCB" CACHE STRING "Select WSI target for vkcube (XCB, XLIB, WAYLAND, DIRECTFB, DISPLAY)") - - find_package(PkgConfig REQUIRED QUIET) # Use PkgConfig to find Linux system libraries - - if(BUILD_WSI_XCB_SUPPORT) - pkg_check_modules(XCB REQUIRED QUIET IMPORTED_TARGET xcb) -+ pkg_get_variable(XCB_INCLUDE_DIRS xcb includedir) -+ message(DEBUG "XCB_INCLUDE_DIRS = ${XCB_INCLUDE_DIRS}") - endif() - - if(BUILD_WSI_XLIB_SUPPORT) - pkg_check_modules(X11 REQUIRED QUIET IMPORTED_TARGET x11) -+ pkg_get_variable(XLIB_INCLUDE_DIRS x11 includedir) -+ message(DEBUG "XLIB_INCLUDE_DIRS = ${XLIB_INCLUDE_DIRS}") - endif() - - if(BUILD_WSI_WAYLAND_SUPPORT) - pkg_check_modules(WAYLAND_CLIENT REQUIRED IMPORTED_TARGET wayland-client) -+ pkg_get_variable(WAYLAND_INCLUDE_DIRS wayland-client includedir) - - pkg_get_variable(WAYLAND_SCANNER_EXECUTABLE wayland-scanner wayland_scanner) -- message(STATUS "WAYLAND_SCANNER_EXECUTABLE = ${WAYLAND_SCANNER_EXECUTABLE}") -+ message(DEBUG "WAYLAND_SCANNER_EXECUTABLE = ${WAYLAND_SCANNER_EXECUTABLE}") -+ -+ pkg_get_variable(WAYLAND_CLIENT_PATH wayland-client pkgdatadir) -+ message(DEBUG "WAYLAND_CLIENT_PATH = ${WAYLAND_CLIENT_PATH}") -+ set(WAYLAND_CODE_PROTOCOL ${WAYLAND_CLIENT_PATH}/wayland.xml) - - pkg_get_variable(WAYLAND_PROTOCOLS_PATH wayland-protocols pkgdatadir) -- message(STATUS "WAYLAND_PROTOCOLS_PATH = ${WAYLAND_PROTOCOLS_PATH}") -+ message(DEBUG "WAYLAND_PROTOCOLS_PATH = ${WAYLAND_PROTOCOLS_PATH}") - set(XDG_SHELL_PROTOCOL ${WAYLAND_PROTOCOLS_PATH}/stable/xdg-shell/xdg-shell.xml) -+ -+ add_custom_command(COMMENT "Generating wayland client protocol dispatch data" -+ OUTPUT wayland-client.c -+ COMMAND ${WAYLAND_SCANNER_EXECUTABLE} -+ private-code -+ ${WAYLAND_CODE_PROTOCOL} -+ ${CMAKE_CURRENT_BINARY_DIR}/wayland-client.c -+ MAIN_DEPENDENCY ${WAYLAND_CODE_PROTOCOL} -+ DEPENDS ${WAYLAND_CODE_PROTOCOL} ${WAYLAND_SCANNER_EXECUTABLE}) -+ - add_custom_command(COMMENT "Generating xdg-shell protocol dispatch data" - OUTPUT xdg-shell-code.c - COMMAND ${WAYLAND_SCANNER_EXECUTABLE} -@@ -121,6 +147,12 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU") - ${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-client-header.h - MAIN_DEPENDENCY ${XDG_DECORATION_PROTOCOL} - DEPENDS ${XDG_DECORATION_PROTOCOL} ${WAYLAND_SCANNER_EXECUTABLE}) -+ -+ set(WAYLAND_ADDITIONAL_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/wayland-client.c -+ ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-code.c -+ ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-header.h -+ ${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-code.c -+ ${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-client-header.h) - endif() - - if(BUILD_WSI_DIRECTFB_SUPPORT) -@@ -128,59 +160,39 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU") - endif() - endif() - -+if(BUILD_WSI_DISPLAY_SUPPORT) -+ list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_DISPLAY_KHR) -+endif() -+ - if(WIN32) -- add_definitions(-DVK_USE_PLATFORM_WIN32_KHR -DWIN32_LEAN_AND_MEAN -DNOMINMAX) -+ add_definitions(-DWIN32_LEAN_AND_MEAN -DNOMINMAX) -+ list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_WIN32_KHR) - elseif(ANDROID) -- add_definitions(-DVK_USE_PLATFORM_ANDROID_KHR) -+ list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_ANDROID_KHR) - elseif(APPLE) -- add_definitions(-DVK_USE_PLATFORM_METAL_EXT) -+ list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_METAL_EXT) - elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU") -- if(NOT CUBE_WSI_SELECTION) -- set(CUBE_WSI_SELECTION "XCB") -+ if(BUILD_WSI_XCB_SUPPORT) -+ list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_XCB_KHR) - endif() -- -- if(CUBE_WSI_SELECTION STREQUAL "XCB") -- if(NOT BUILD_WSI_XCB_SUPPORT) -- message(FATAL_ERROR "Selected XCB for vkcube build but not building Xcb support") -- endif() -- link_libraries(PkgConfig::XCB) -- set(CUBE_PLATFORM VK_USE_PLATFORM_XCB_KHR) -- elseif(CUBE_WSI_SELECTION STREQUAL "XLIB") -- if(NOT BUILD_WSI_XLIB_SUPPORT) -- message(FATAL_ERROR "Selected XLIB for vkcube build but not building Xlib support") -- endif() -- link_libraries(PkgConfig::X11) -- set(CUBE_PLATFORM VK_USE_PLATFORM_XLIB_KHR) -- elseif(CUBE_WSI_SELECTION STREQUAL "WAYLAND") -- if(NOT BUILD_WSI_WAYLAND_SUPPORT) -- message(FATAL_ERROR "Selected Wayland for vkcube build but not building Wayland support") -- endif() -- link_libraries(PkgConfig::WAYLAND_CLIENT) -- set(CUBE_PLATFORM VK_USE_PLATFORM_WAYLAND_KHR) -- set(XDG_SHELL_PROTOCOL ${WAYLAND_PROTOCOLS_PATH}/stable/xdg-shell/xdg-shell.xml) -- set(OPTIONAL_WAYLAND_DATA_FILES -- ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-code.c -- ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-header.h -- ${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-code.c -- ${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-client-header.h) -- include_directories(${CMAKE_CURRENT_BINARY_DIR}) -- elseif(CUBE_WSI_SELECTION STREQUAL "DIRECTFB") -- if(NOT BUILD_WSI_DIRECTFB_SUPPORT) -- message(FATAL_ERROR "Selected DIRECTFB for vkcube build but not building DirectFB support") -- endif() -- link_libraries(PkgConfig::DirectFB) -- set(CUBE_PLATFORM VK_USE_PLATFORM_DIRECTFB_EXT) -- elseif(CUBE_WSI_SELECTION STREQUAL "DISPLAY") -- set(CUBE_PLATFORM VK_USE_PLATFORM_DISPLAY_KHR) -- else() -- message(FATAL_ERROR "Unrecognized value for CUBE_WSI_SELECTION: ${CUBE_WSI_SELECTION}") -+ if(BUILD_WSI_XLIB_SUPPORT) -+ list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_XLIB_KHR) -+ endif() -+ if(BUILD_WSI_WAYLAND_SUPPORT) -+ list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_WAYLAND_KHR) -+ endif() -+ if(BUILD_WSI_DIRECTFB_SUPPORT) -+ list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_DIRECTFB_EXT) - endif() -- - link_libraries(${API_LOWERCASE} m) - else() - message(FATAL_ERROR "Unsupported Platform!") - endif() - -+if(NOT DEFINED ENABLED_CUBE_PLATFORMS) -+ message(FATAL_ERROR "There are no supported WSI platforms on this system, vkcube requires a WSI platform be available to be able to render its output") -+endif() -+ - if (COMPILE_CUBE_SHADERS) - # Try to find glslang in system paths or in an SDK if the VULKAN_SDK env-var is set - find_program(GLSLANG_VALIDATOR names glslang glslangValidator HINTS $ENV{GLSLANG_INSTALL_DIR} $ENV{VULKAN_SDK}/bin $ENV{VULKAN_SDK}/Bin) -@@ -226,7 +238,6 @@ elseif (ANDROID) - - add_subdirectory(android) - -- target_link_libraries(vkcube PRIVATE Vulkan::Headers volk::volk_headers) - elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU") - add_executable(vkcube) - target_sources(vkcube PRIVATE -@@ -235,15 +246,28 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU") - ${PROJECT_SOURCE_DIR}/cube/cube.frag - cube.vert.inc - cube.frag.inc -- ${OPTIONAL_WAYLAND_DATA_FILES} - ) -- target_compile_definitions(vkcube PUBLIC ${CUBE_PLATFORM}) -+ target_link_libraries(vkcube Threads::Threads) -+ if(BUILD_WSI_XCB_SUPPORT) -+ target_sources(vkcube PRIVATE xcb_loader.h) -+ target_include_directories(vkcube PRIVATE ${xcb_INCLUDE_DIRS}) -+ endif() -+ if(BUILD_WSI_XLIB_SUPPORT) -+ target_sources(vkcube PRIVATE xlib_loader.h) -+ target_include_directories(vkcube PRIVATE ${XLIB_INCLUDE_DIRS}) -+ endif() -+ if(BUILD_WSI_WAYLAND_SUPPORT) -+ target_include_directories(vkcube PRIVATE ${WAYLAND_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}) -+ target_sources(vkcube PRIVATE PRIVATE ${WAYLAND_ADDITIONAL_SOURCES}) -+ endif() -+ if(BUILD_WSI_DIRECTFB_SUPPORT) -+ target_link_libraries(vkcube PkgConfig::DirectFB) -+ endif() - include(CheckLibraryExists) - CHECK_LIBRARY_EXISTS("rt" clock_gettime "" NEED_RT) - if (NEED_RT) -- target_link_libraries(vkcube PRIVATE rt) -+ target_link_libraries(vkcube rt) - endif() -- target_link_libraries(vkcube PRIVATE Vulkan::Headers volk::volk_headers Threads::Threads) - elseif(WIN32) - add_executable(vkcube WIN32) - target_sources(vkcube PRIVATE -@@ -253,12 +277,13 @@ elseif(WIN32) - cube.vert.inc - cube.frag.inc - ) -- target_link_libraries(vkcube PRIVATE Vulkan::Headers volk::volk_headers) - else() - message(FATAL_ERROR "Unsupported Platform!") - endif() - -+target_compile_definitions(vkcube PRIVATE ${ENABLED_CUBE_PLATFORMS}) - target_include_directories(vkcube PRIVATE .) -+target_link_libraries(vkcube Vulkan::Headers volk::volk_headers) - - if (ANDROID) - install(TARGETS vkcube DESTINATION ${CMAKE_INSTALL_LIBDIR}) -@@ -280,6 +305,16 @@ if (ANDROID) - return() - endif() - -+if (XCB_LINK_LIBRARIES) -+ target_compile_definitions(vkcube PRIVATE "XCB_LIBRARY=\"${XCB_LINK_LIBRARIES}\"") -+endif() -+if (X11_LINK_LIBRARIES) -+ target_compile_definitions(vkcube PRIVATE "XLIB_LIBRARY=\"${X11_LINK_LIBRARIES}\"") -+endif() -+if (WAYLAND_CLIENT_LINK_LIBRARIES) -+ target_compile_definitions(vkcube PRIVATE "WAYLAND_LIBRARY=\"${WAYLAND_CLIENT_LINK_LIBRARIES}\"") -+endif() -+ - # ---------------------------------------------------------------------------- - # vkcubepp - -@@ -291,10 +326,24 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU") - ${PROJECT_SOURCE_DIR}/cube/cube.vert - ${PROJECT_SOURCE_DIR}/cube/cube.frag - cube.vert.inc -- cube.frag.inc -- ${OPTIONAL_WAYLAND_DATA_FILES}) -- target_link_libraries(vkcubepp Vulkan::Headers volk::volk_headers Threads::Threads) -- target_compile_definitions(vkcubepp PUBLIC ${CUBE_PLATFORM}) -+ cube.frag.inc) -+ target_link_libraries(vkcubepp Threads::Threads) -+ -+ if(BUILD_WSI_XCB_SUPPORT) -+ target_sources(vkcubepp PRIVATE xcb_loader.h) -+ target_include_directories(vkcubepp PRIVATE ${xcb_INCLUDE_DIRS}) -+ endif() -+ if(BUILD_WSI_XLIB_SUPPORT) -+ target_sources(vkcubepp PRIVATE xlib_loader.h) -+ target_include_directories(vkcubepp PRIVATE ${XLIB_INCLUDE_DIRS}) -+ endif() -+ if(BUILD_WSI_WAYLAND_SUPPORT) -+ target_include_directories(vkcubepp PRIVATE ${WAYLAND_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}) -+ target_sources(vkcubepp PRIVATE ${WAYLAND_ADDITIONAL_SOURCES}) -+ endif() -+ if(BUILD_WSI_DIRECTFB_SUPPORT) -+ target_link_libraries(vkcubepp PkgConfig::DirectFB) -+ endif() - else() - add_executable(vkcubepp - WIN32 -@@ -303,9 +352,21 @@ else() - ${PROJECT_SOURCE_DIR}/cube/cube.frag - cube.vert.inc - cube.frag.inc) -- target_link_libraries(vkcubepp Vulkan::Headers volk::volk_headers) - endif() -+ - target_include_directories(vkcubepp PRIVATE .) -+target_compile_definitions(vkcubepp PRIVATE ${ENABLED_CUBE_PLATFORMS}) -+target_link_libraries(vkcubepp Vulkan::Headers volk::volk_headers) -+ -+if (XCB_LINK_LIBRARIES ) -+ target_compile_definitions(vkcubepp PUBLIC "XCB_LIBRARY=\"${XCB_LINK_LIBRARIES}\"") -+endif() -+if (X11_LINK_LIBRARIES) -+ target_compile_definitions(vkcubepp PUBLIC "XLIB_LIBRARY=\"${X11_LINK_LIBRARIES}\"") -+endif() -+if (WAYLAND_CLIENT_LINK_LIBRARIES) -+ target_compile_definitions(vkcubepp PUBLIC "WAYLAND_LIBRARY=\"${WAYLAND_CLIENT_LINK_LIBRARIES}\"") -+endif() - - if(APPLE) - install( -@@ -320,41 +381,3 @@ if(APPLE) - else() - install(TARGETS vkcubepp) - endif() -- --# ---------------------------------------------------------------------------- --# vkcube-wayland -- --if (CMAKE_SYSTEM_NAME MATCHES "Linux|BSD") -- if(BUILD_WSI_WAYLAND_SUPPORT AND EXISTS ${WAYLAND_PROTOCOLS_PATH}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml) -- add_executable(vkcube-wayland) -- -- target_sources(vkcube-wayland PRIVATE -- cube.c -- ${PROJECT_SOURCE_DIR}/cube/cube.vert -- ${PROJECT_SOURCE_DIR}/cube/cube.frag -- cube.vert.inc -- cube.frag.inc -- ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-code.c -- ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-header.h -- ${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-code.c -- ${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-client-header.h -- ) -- target_include_directories(vkcube-wayland PRIVATE -- ${CMAKE_CURRENT_BINARY_DIR} -- . -- ) -- target_link_libraries(vkcube-wayland PRIVATE -- Vulkan::Headers -- volk::volk_headers -- Threads::Threads -- PkgConfig::WAYLAND_CLIENT -- ) -- target_compile_definitions(vkcube-wayland PRIVATE VK_USE_PLATFORM_WAYLAND_KHR) -- include(CheckLibraryExists) -- CHECK_LIBRARY_EXISTS("rt" clock_gettime "" NEED_RT) -- if (NEED_RT) -- target_link_libraries(vkcube-wayland PRIVATE rt) -- endif() -- install(TARGETS vkcube-wayland) -- endif() --endif() -diff --git a/cube/android/CMakeLists.txt b/cube/android/CMakeLists.txt -index 66f75b42..af607a55 100644 ---- a/cube/android/CMakeLists.txt -+++ b/cube/android/CMakeLists.txt -@@ -43,7 +43,7 @@ target_sources(android_glue PRIVATE - - set_target_properties(vkcube PROPERTIES OUTPUT_NAME "VkCube") - --target_link_libraries(vkcube PRIVATE -+target_link_libraries(vkcube - android_glue - log - android -diff --git a/cube/cube.c b/cube/cube.c -index 4879317c..255eb5bb 100644 ---- a/cube/cube.c -+++ b/cube/cube.c -@@ -26,6 +26,7 @@ - */ - - #define _GNU_SOURCE -+#include - #include - #include - #include -@@ -33,13 +34,18 @@ - #include - #include - #include -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) - #include --#if defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR) --#include --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+#include "xlib_loader.h" -+#endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+#include "xcb_loader.h" -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - #include --#include "xdg-shell-client-header.h" --#include "xdg-decoration-client-header.h" -+#include "wayland_loader.h" - #endif - - #ifdef _WIN32 -@@ -290,6 +296,97 @@ char const *to_string(VkPhysicalDeviceType const type) { - } - } - -+typedef enum WSI_PLATFORM { -+ WSI_PLATFORM_AUTO = 0, -+ WSI_PLATFORM_WIN32, -+ WSI_PLATFORM_METAL, -+ WSI_PLATFORM_ANDROID, -+ WSI_PLATFORM_QNX, -+ WSI_PLATFORM_XCB, -+ WSI_PLATFORM_XLIB, -+ WSI_PLATFORM_WAYLAND, -+ WSI_PLATFORM_DIRECTFB, -+ WSI_PLATFORM_DISPLAY, -+ WSI_PLATFORM_INVALID, // Sentinel just to indicate invalid user input -+} WSI_PLATFORM; -+ -+WSI_PLATFORM wsi_from_string(const char *str) { -+ if (strcmp(str, "auto") == 0) return WSI_PLATFORM_AUTO; -+#if defined(VK_USE_PLATFORM_WIN32_KHR) -+ if (strcmp(str, "win32") == 0) return WSI_PLATFORM_WIN32; -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) -+ if (strcmp(str, "metal") == 0) return WSI_PLATFORM_METAL; -+#endif -+#if defined(VK_USE_PLATFORM_ANDROID_KHR) -+ if (strcmp(str, "android") == 0) return WSI_PLATFORM_ANDROID; -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ if (strcmp(str, "qnx") == 0) return WSI_PLATFORM_QNX; -+#endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ if (strcmp(str, "xcb") == 0) return WSI_PLATFORM_XCB; -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ if (strcmp(str, "xlib") == 0) return WSI_PLATFORM_XLIB; -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ if (strcmp(str, "wayland") == 0) return WSI_PLATFORM_WAYLAND; -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ if (strcmp(str, "directfb") == 0) return WSI_PLATFORM_DIRECTFB; -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -+ if (strcmp(str, "display") == 0) return WSI_PLATFORM_DISPLAY; -+#endif -+ return WSI_PLATFORM_INVALID; -+}; -+ -+const char *wsi_to_string(WSI_PLATFORM wsi_platform) { -+ switch (wsi_platform) { -+ case (WSI_PLATFORM_AUTO): -+ return "auto"; -+#if defined(VK_USE_PLATFORM_WIN32_KHR) -+ case (WSI_PLATFORM_WIN32): -+ return "win32"; -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) -+ case (WSI_PLATFORM_METAL): -+ return "metal"; -+#endif -+#if defined(VK_USE_PLATFORM_ANDROID_KHR) -+ case (WSI_PLATFORM_ANDROID): -+ return "android"; -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ case (WSI_PLATFORM_QNX): -+ return "qnx"; -+#endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ case (WSI_PLATFORM_XCB): -+ return "xcb"; -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ case (WSI_PLATFORM_XLIB): -+ return "xlib"; -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ case (WSI_PLATFORM_WAYLAND): -+ return "wayland"; -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ case (WSI_PLATFORM_DIRECTFB): -+ return "directfb"; -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -+ case (WSI_PLATFORM_DISPLAY): -+ return "display"; -+#endif -+ default: -+ return "unknown"; -+ } -+}; -+ - typedef struct { - VkImage image; - VkCommandBuffer cmd; -@@ -309,18 +406,24 @@ struct demo { - char name[APP_NAME_STR_LEN]; // Name to put on the window/icon - HWND window; // hWnd - window handle - POINT minsize; // minimum window size --#elif defined(VK_USE_PLATFORM_XLIB_KHR) -- Display *display; -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ void *xlib_library; -+ Display *xlib_display; - Window xlib_window; - Atom xlib_wm_delete_window; --#elif defined(VK_USE_PLATFORM_XCB_KHR) -- Display *display; -+#endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ void *xcb_library; -+ Display *xcb_display; - xcb_connection_t *connection; - xcb_screen_t *screen; - xcb_window_t xcb_window; - xcb_intern_atom_reply_t *atom_wm_delete_window; --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -- struct wl_display *display; -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ void *wayland_library; // Dynamic library for wayland -+ struct wl_display *wayland_display; - struct wl_registry *registry; - struct wl_compositor *compositor; - struct wl_surface *window; -@@ -333,20 +436,24 @@ struct demo { - struct wl_seat *seat; - struct wl_pointer *pointer; - struct wl_keyboard *keyboard; --#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - IDirectFB *dfb; -- IDirectFBSurface *window; -+ IDirectFBSurface *directfb_window; - IDirectFBEventBuffer *event_buffer; --#elif defined(VK_USE_PLATFORM_ANDROID_KHR) -+#endif -+#if defined(VK_USE_PLATFORM_ANDROID_KHR) - struct ANativeWindow *window; --#elif defined(VK_USE_PLATFORM_METAL_EXT) -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) - void *caMetalLayer; --#elif defined(VK_USE_PLATFORM_SCREEN_QNX) -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) - screen_context_t screen_context; - screen_window_t screen_window; - screen_event_t screen_event; - #endif -- -+ WSI_PLATFORM wsi_platform; - VkSurfaceKHR surface; - bool prepared; - bool use_staging_buffer; -@@ -2435,35 +2542,49 @@ static void demo_cleanup(struct demo *demo) { - vkDestroySurfaceKHR(demo->inst, demo->surface, NULL); - - #if defined(VK_USE_PLATFORM_XLIB_KHR) -- XDestroyWindow(demo->display, demo->xlib_window); -- XCloseDisplay(demo->display); --#elif defined(VK_USE_PLATFORM_XCB_KHR) -- xcb_destroy_window(demo->connection, demo->xcb_window); -- xcb_disconnect(demo->connection); -- free(demo->atom_wm_delete_window); --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -- if (demo->keyboard) wl_keyboard_destroy(demo->keyboard); -- if (demo->pointer) wl_pointer_destroy(demo->pointer); -- if (demo->seat) wl_seat_destroy(demo->seat); -- xdg_toplevel_destroy(demo->xdg_toplevel); -- xdg_surface_destroy(demo->xdg_surface); -- wl_surface_destroy(demo->window); -- xdg_wm_base_destroy(demo->xdg_wm_base); -- if (demo->xdg_decoration_mgr) { -- zxdg_toplevel_decoration_v1_destroy(demo->toplevel_decoration); -- zxdg_decoration_manager_v1_destroy(demo->xdg_decoration_mgr); -- } -- wl_compositor_destroy(demo->compositor); -- wl_registry_destroy(demo->registry); -- wl_display_disconnect(demo->display); --#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) -- demo->event_buffer->Release(demo->event_buffer); -- demo->window->Release(demo->window); -- demo->dfb->Release(demo->dfb); --#elif defined(VK_USE_PLATFORM_SCREEN_QNX) -- screen_destroy_event(demo->screen_event); -- screen_destroy_window(demo->screen_window); -- screen_destroy_context(demo->screen_context); -+ if (demo->wsi_platform == WSI_PLATFORM_XLIB) { -+ XDestroyWindow(demo->xlib_display, demo->xlib_window); -+ XCloseDisplay(demo->xlib_display); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_XCB) { -+ xcb_destroy_window(demo->connection, demo->xcb_window); -+ xcb_disconnect(demo->connection); -+ free(demo->atom_wm_delete_window); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_WAYLAND) { -+ if (demo->keyboard) wl_keyboard_destroy(demo->keyboard); -+ if (demo->pointer) wl_pointer_destroy(demo->pointer); -+ if (demo->seat) wl_seat_destroy(demo->seat); -+ xdg_toplevel_destroy(demo->xdg_toplevel); -+ xdg_surface_destroy(demo->xdg_surface); -+ wl_surface_destroy(demo->window); -+ xdg_wm_base_destroy(demo->xdg_wm_base); -+ if (demo->xdg_decoration_mgr) { -+ zxdg_toplevel_decoration_v1_destroy(demo->toplevel_decoration); -+ zxdg_decoration_manager_v1_destroy(demo->xdg_decoration_mgr); -+ } -+ wl_compositor_destroy(demo->compositor); -+ wl_registry_destroy(demo->registry); -+ wl_display_disconnect(demo->wayland_display); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ if (demo->wsi_platform == WSI_PLATFORM_DIRECTFB) { -+ demo->event_buffer->Release(demo->event_buffer); -+ demo->directfb_window->Release(demo->directfb_window); -+ demo->dfb->Release(demo->dfb); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ if (demo->wsi_platform == WSI_PLATFORM_QNX) { -+ screen_destroy_event(demo->screen_event); -+ screen_destroy_window(demo->screen_window); -+ screen_destroy_context(demo->screen_context); -+ } - #endif - - vkDestroyInstance(demo->inst, NULL); -@@ -2640,7 +2761,8 @@ static void demo_create_window(struct demo *demo) { - demo->minsize.x = GetSystemMetrics(SM_CXMINTRACK); - demo->minsize.y = GetSystemMetrics(SM_CYMINTRACK) + 1; - } --#elif defined(VK_USE_PLATFORM_XLIB_KHR) -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) - static void demo_create_xlib_window(struct demo *demo) { - const char *display_envar = getenv("DISPLAY"); - if (display_envar == NULL || display_envar[0] == '\0') { -@@ -2650,15 +2772,15 @@ static void demo_create_xlib_window(struct demo *demo) { - } - - XInitThreads(); -- demo->display = XOpenDisplay(NULL); -+ demo->xlib_display = XOpenDisplay(NULL); - long visualMask = VisualScreenMask; - int numberOfVisuals; - XVisualInfo vInfoTemplate = {}; -- vInfoTemplate.screen = DefaultScreen(demo->display); -- XVisualInfo *visualInfo = XGetVisualInfo(demo->display, visualMask, &vInfoTemplate, &numberOfVisuals); -+ vInfoTemplate.screen = DefaultScreen(demo->xlib_display); -+ XVisualInfo *visualInfo = XGetVisualInfo(demo->xlib_display, visualMask, &vInfoTemplate, &numberOfVisuals); - - Colormap colormap = -- XCreateColormap(demo->display, RootWindow(demo->display, vInfoTemplate.screen), visualInfo->visual, AllocNone); -+ XCreateColormap(demo->xlib_display, RootWindow(demo->xlib_display, vInfoTemplate.screen), visualInfo->visual, AllocNone); - - XSetWindowAttributes windowAttributes = {}; - windowAttributes.colormap = colormap; -@@ -2666,14 +2788,14 @@ static void demo_create_xlib_window(struct demo *demo) { - windowAttributes.border_pixel = 0; - windowAttributes.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask | ExposureMask; - -- demo->xlib_window = XCreateWindow(demo->display, RootWindow(demo->display, vInfoTemplate.screen), 0, 0, demo->width, -+ demo->xlib_window = XCreateWindow(demo->xlib_display, RootWindow(demo->xlib_display, vInfoTemplate.screen), 0, 0, demo->width, - demo->height, 0, visualInfo->depth, InputOutput, visualInfo->visual, - CWBackPixel | CWBorderPixel | CWEventMask | CWColormap, &windowAttributes); - -- XSelectInput(demo->display, demo->xlib_window, ExposureMask | KeyPressMask); -- XMapWindow(demo->display, demo->xlib_window); -- XFlush(demo->display); -- demo->xlib_wm_delete_window = XInternAtom(demo->display, "WM_DELETE_WINDOW", False); -+ XSelectInput(demo->xlib_display, demo->xlib_window, ExposureMask | KeyPressMask); -+ XMapWindow(demo->xlib_display, demo->xlib_window); -+ XFlush(demo->xlib_display); -+ demo->xlib_wm_delete_window = XInternAtom(demo->xlib_display, "WM_DELETE_WINDOW", False); - } - static void demo_handle_xlib_event(struct demo *demo, const XEvent *event) { - switch (event->type) { -@@ -2713,11 +2835,11 @@ static void demo_run_xlib(struct demo *demo) { - XEvent event; - - if (demo->pause) { -- XNextEvent(demo->display, &event); -+ XNextEvent(demo->xlib_display, &event); - demo_handle_xlib_event(demo, &event); - } -- while (XPending(demo->display) > 0) { -- XNextEvent(demo->display, &event); -+ while (XPending(demo->xlib_display) > 0) { -+ XNextEvent(demo->xlib_display, &event); - demo_handle_xlib_event(demo, &event); - } - -@@ -2726,7 +2848,8 @@ static void demo_run_xlib(struct demo *demo) { - if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount) demo->quit = true; - } - } --#elif defined(VK_USE_PLATFORM_XCB_KHR) -+#endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) - static void demo_handle_xcb_event(struct demo *demo, const xcb_generic_event_t *event) { - uint8_t event_code = event->response_type & 0x7f; - switch (event_code) { -@@ -2823,26 +2946,27 @@ static void demo_create_xcb_window(struct demo *demo) { - xcb_configure_window(demo->connection, demo->xcb_window, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, coords); - } - // VK_USE_PLATFORM_XCB_KHR --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - static void demo_run(struct demo *demo) { - while (!demo->quit) { - // Flush any commands to the server -- wl_display_flush(demo->display); -+ wl_display_flush(demo->wayland_display); - - if (demo->pause) { - // block and wait for input -- wl_display_dispatch(demo->display); -+ wl_display_dispatch(demo->wayland_display); - } else { - // Lock the display event queue in case the driver is doing something on another thread - // while we wait, keep pumping events -- while (wl_display_prepare_read(demo->display) != 0) { -- wl_display_dispatch_pending(demo->display); -+ while (wl_display_prepare_read(demo->wayland_display) != 0) { -+ wl_display_dispatch_pending(demo->wayland_display); - } - // Actually do the read from the socket -- wl_display_read_events(demo->display); -+ wl_display_read_events(demo->wayland_display); - - // Pump events -- wl_display_dispatch_pending(demo->display); -+ wl_display_dispatch_pending(demo->wayland_display); - - demo_draw(demo); - demo->curFrame++; -@@ -2883,7 +3007,7 @@ static void handle_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel - - static const struct xdg_toplevel_listener xdg_toplevel_listener = {handle_toplevel_configure, handle_toplevel_close}; - --static void demo_create_window(struct demo *demo) { -+static void demo_create_wayland_window(struct demo *demo) { - if (!demo->xdg_wm_base) { - printf("Compositor did not provide the standard protocol xdg-wm-base\n"); - fflush(stdout); -@@ -2921,7 +3045,8 @@ static void demo_create_window(struct demo *demo) { - - wl_surface_commit(demo->window); - } --#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - static void demo_create_directfb_window(struct demo *demo) { - DFBResult ret; - -@@ -2944,7 +3069,7 @@ static void demo_create_directfb_window(struct demo *demo) { - desc.caps = DSCAPS_PRIMARY; - desc.width = demo->width; - desc.height = demo->height; -- ret = demo->dfb->CreateSurface(demo->dfb, &desc, &demo->window); -+ ret = demo->dfb->CreateSurface(demo->dfb, &desc, &demo->directfb_window); - if (ret) { - printf("CreateSurface failed to create DirectFB surface interface!\n"); - fflush(stdout); -@@ -2995,14 +3120,16 @@ static void demo_run_directfb(struct demo *demo) { - } - } - } --#elif defined(VK_USE_PLATFORM_ANDROID_KHR) -+#endif -+#if defined(VK_USE_PLATFORM_ANDROID_KHR) - static void demo_run(struct demo *demo) { - if (!demo->prepared) return; - - demo_draw(demo); - demo->curFrame++; - } --#elif defined(VK_USE_PLATFORM_METAL_EXT) -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) - static void demo_run(struct demo *demo) { - demo_draw(demo); - demo->curFrame++; -@@ -3010,7 +3137,8 @@ static void demo_run(struct demo *demo) { - demo->quit = TRUE; - } - } --#elif defined(VK_USE_PLATFORM_DISPLAY_KHR) -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - static VkResult demo_create_display_surface(struct demo *demo) { - VkResult U_ASSERT_ONLY err; - uint32_t display_count; -@@ -3105,8 +3233,6 @@ static VkResult demo_create_display_surface(struct demo *demo) { - exit(1); - } - -- free(plane_props); -- - VkDisplayPlaneCapabilitiesKHR planeCaps; - vkGetDisplayPlaneCapabilitiesKHR(demo->gpu, mode_props.displayMode, plane_index, &planeCaps); - // Find a supported alpha mode -@@ -3137,6 +3263,8 @@ static VkResult demo_create_display_surface(struct demo *demo) { - create_info.globalAlpha = 1.0f; - create_info.imageExtent = image_extent; - -+ free(plane_props); -+ - return vkCreateDisplayPlaneSurfaceKHR(demo->inst, &create_info, NULL, &demo->surface); - } - -@@ -3150,7 +3278,8 @@ static void demo_run_display(struct demo *demo) { - } - } - } --#elif defined(VK_USE_PLATFORM_SCREEN_QNX) -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) - - #include - -@@ -3256,7 +3385,7 @@ static void demo_run(struct demo *demo) { - } - } - --static void demo_create_window(struct demo *demo) { -+static void demo_create_screen_window(struct demo *demo) { - const char *idstr = APP_SHORT_NAME; - int size[2]; - int usage = SCREEN_USAGE_VULKAN; -@@ -3360,199 +3489,599 @@ int find_display_gpu(int gpu_number, uint32_t gpu_count, VkPhysicalDevice *physi - return -1; - } - #endif --static void demo_init_vk(struct demo *demo) { -- VkResult err; -- uint32_t instance_extension_count = 0; -- uint32_t instance_layer_count = 0; -- char *instance_validation_layers[] = {"VK_LAYER_KHRONOS_validation"}; -- demo->enabled_extension_count = 0; -- demo->enabled_layer_count = 0; -- demo->is_minimized = false; -- demo->cmd_pool = VK_NULL_HANDLE; - -- err = volkInitialize(); -- if (err != VK_SUCCESS) { -- ERR_EXIT( -- "Unable to find the Vulkan runtime on the system.\n\n" -- "This likely indicates that no Vulkan capable drivers are installed.", -- "Installation Failure"); -- } -- // Look for validation layers -- VkBool32 validation_found = 0; -- if (demo->validate) { -- err = vkEnumerateInstanceLayerProperties(&instance_layer_count, NULL); -- assert(!err); -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+static void pointer_handle_enter(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t sx, -+ wl_fixed_t sy) {} - -- if (instance_layer_count > 0) { -- VkLayerProperties *instance_layers = malloc(sizeof(VkLayerProperties) * instance_layer_count); -- err = vkEnumerateInstanceLayerProperties(&instance_layer_count, instance_layers); -- assert(!err); -+static void pointer_handle_leave(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface) {} - -- validation_found = demo_check_layers(ARRAY_SIZE(instance_validation_layers), instance_validation_layers, -- instance_layer_count, instance_layers); -- if (validation_found) { -- demo->enabled_layer_count = ARRAY_SIZE(instance_validation_layers); -- demo->enabled_layers[0] = "VK_LAYER_KHRONOS_validation"; -- } -- free(instance_layers); -- } -+static void pointer_handle_motion(void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy) {} - -- if (!validation_found) { -- ERR_EXIT( -- "vkEnumerateInstanceLayerProperties failed to find required validation layer.\n\n" -- "Please look at the Getting Started guide for additional information.\n", -- "vkCreateInstance Failure"); -- } -+static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, -+ uint32_t state) { -+ struct demo *demo = data; -+ if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED) { -+ xdg_toplevel_move(demo->xdg_toplevel, demo->seat, serial); - } -+} - -- /* Look for instance extensions */ -- VkBool32 surfaceExtFound = 0; -- VkBool32 platformSurfaceExtFound = 0; -- bool portabilityEnumerationActive = false; -- memset(demo->extension_names, 0, sizeof(demo->extension_names)); -+static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) {} - -- err = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, NULL); -- assert(!err); -+static const struct wl_pointer_listener pointer_listener = { -+ pointer_handle_enter, pointer_handle_leave, pointer_handle_motion, pointer_handle_button, pointer_handle_axis, -+}; - -- if (instance_extension_count > 0) { -- VkExtensionProperties *instance_extensions = malloc(sizeof(VkExtensionProperties) * instance_extension_count); -- err = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, instance_extensions); -- assert(!err); -- for (uint32_t i = 0; i < instance_extension_count; i++) { -- if (!strcmp(VK_KHR_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName)) { -- surfaceExtFound = 1; -- demo->extension_names[demo->enabled_extension_count++] = VK_KHR_SURFACE_EXTENSION_NAME; -- } --#if defined(VK_USE_PLATFORM_WIN32_KHR) -- if (!strcmp(VK_KHR_WIN32_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName)) { -- platformSurfaceExtFound = 1; -- demo->extension_names[demo->enabled_extension_count++] = VK_KHR_WIN32_SURFACE_EXTENSION_NAME; -- } --#elif defined(VK_USE_PLATFORM_XLIB_KHR) -- if (!strcmp(VK_KHR_XLIB_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName)) { -- platformSurfaceExtFound = 1; -- demo->extension_names[demo->enabled_extension_count++] = VK_KHR_XLIB_SURFACE_EXTENSION_NAME; -- } --#elif defined(VK_USE_PLATFORM_XCB_KHR) -- if (!strcmp(VK_KHR_XCB_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName)) { -- platformSurfaceExtFound = 1; -- demo->extension_names[demo->enabled_extension_count++] = VK_KHR_XCB_SURFACE_EXTENSION_NAME; -- } --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -- if (!strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName)) { -- platformSurfaceExtFound = 1; -- demo->extension_names[demo->enabled_extension_count++] = VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME; -- } --#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) -- if (!strcmp(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName)) { -- platformSurfaceExtFound = 1; -- demo->extension_names[demo->enabled_extension_count++] = VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME; -- } --#elif defined(VK_USE_PLATFORM_DISPLAY_KHR) -- if (!strcmp(VK_KHR_DISPLAY_EXTENSION_NAME, instance_extensions[i].extensionName)) { -- platformSurfaceExtFound = 1; -- demo->extension_names[demo->enabled_extension_count++] = VK_KHR_DISPLAY_EXTENSION_NAME; -- } --#elif defined(VK_USE_PLATFORM_ANDROID_KHR) -- if (!strcmp(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName)) { -- platformSurfaceExtFound = 1; -- demo->extension_names[demo->enabled_extension_count++] = VK_KHR_ANDROID_SURFACE_EXTENSION_NAME; -- } --#elif defined(VK_USE_PLATFORM_METAL_EXT) -- if (!strcmp(VK_EXT_METAL_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName)) { -- platformSurfaceExtFound = 1; -- demo->extension_names[demo->enabled_extension_count++] = VK_EXT_METAL_SURFACE_EXTENSION_NAME; -- } --#elif defined(VK_USE_PLATFORM_SCREEN_QNX) -- if (!strcmp(VK_QNX_SCREEN_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName)) { -- platformSurfaceExtFound = 1; -- demo->extension_names[demo->enabled_extension_count++] = VK_QNX_SCREEN_SURFACE_EXTENSION_NAME; -- } --#endif -- if (!strcmp(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, instance_extensions[i].extensionName)) { -- demo->extension_names[demo->enabled_extension_count++] = VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; -- } -- if (!strcmp(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, instance_extensions[i].extensionName)) { -- if (demo->validate) { -- demo->extension_names[demo->enabled_extension_count++] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME; -- } -- } -- // We want cube to be able to enumerate drivers that support the portability_subset extension, so we have to enable the -- // portability enumeration extension. -- if (!strcmp(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, instance_extensions[i].extensionName)) { -- portabilityEnumerationActive = true; -- demo->extension_names[demo->enabled_extension_count++] = VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME; -- } -- assert(demo->enabled_extension_count < 64); -- } -+static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size) {} - -- free(instance_extensions); -+static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface, -+ struct wl_array *keys) {} -+ -+static void keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface) {} -+ -+static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, -+ uint32_t state) { -+ if (state != WL_KEYBOARD_KEY_STATE_RELEASED) return; -+ struct demo *demo = data; -+ switch (key) { -+ case KEY_ESC: // Escape -+ demo->quit = true; -+ break; -+ case KEY_LEFT: // left arrow key -+ demo->spin_angle -= demo->spin_increment; -+ break; -+ case KEY_RIGHT: // right arrow key -+ demo->spin_angle += demo->spin_increment; -+ break; -+ case KEY_SPACE: // space bar -+ demo->pause = !demo->pause; -+ break; - } -+} - -- if (!surfaceExtFound) { -- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_SURFACE_EXTENSION_NAME -- " extension.\n\n" -- "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -- "Please look at the Getting Started guide for additional information.\n", -- "vkCreateInstance Failure"); -+static void keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, -+ uint32_t mods_latched, uint32_t mods_locked, uint32_t group) {} -+ -+static const struct wl_keyboard_listener keyboard_listener = { -+ keyboard_handle_keymap, keyboard_handle_enter, keyboard_handle_leave, keyboard_handle_key, keyboard_handle_modifiers, -+}; -+ -+static void seat_handle_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps) { -+ // Subscribe to pointer events -+ struct demo *demo = data; -+ if ((caps & WL_SEAT_CAPABILITY_POINTER) && !demo->pointer) { -+ demo->pointer = wl_seat_get_pointer(seat); -+ wl_pointer_add_listener(demo->pointer, &pointer_listener, demo); -+ } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && demo->pointer) { -+ wl_pointer_destroy(demo->pointer); -+ demo->pointer = NULL; - } -- if (!platformSurfaceExtFound) { --#if defined(VK_USE_PLATFORM_WIN32_KHR) -- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_WIN32_SURFACE_EXTENSION_NAME -- " extension.\n\n" -- "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -- "Please look at the Getting Started guide for additional information.\n", -- "vkCreateInstance Failure"); --#elif defined(VK_USE_PLATFORM_METAL_EXT) -- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_EXT_METAL_SURFACE_EXTENSION_NAME -- " extension.\n\n" -- "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -- "Please look at the Getting Started guide for additional information.\n", -- "vkCreateInstance Failure"); --#elif defined(VK_USE_PLATFORM_XCB_KHR) -- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_XCB_SURFACE_EXTENSION_NAME -- " extension.\n\n" -- "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -- "Please look at the Getting Started guide for additional information.\n", -- "vkCreateInstance Failure"); --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME -- " extension.\n\n" -- "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -- "Please look at the Getting Started guide for additional information.\n", -- "vkCreateInstance Failure"); --#elif defined(VK_USE_PLATFORM_DISPLAY_KHR) -- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_DISPLAY_EXTENSION_NAME -- " extension.\n\n" -- "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -- "Please look at the Getting Started guide for additional information.\n", -- "vkCreateInstance Failure"); --#elif defined(VK_USE_PLATFORM_ANDROID_KHR) -- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_ANDROID_SURFACE_EXTENSION_NAME -- " extension.\n\n" -- "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -- "Please look at the Getting Started guide for additional information.\n", -- "vkCreateInstance Failure"); --#elif defined(VK_USE_PLATFORM_XLIB_KHR) -- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_XLIB_SURFACE_EXTENSION_NAME -- " extension.\n\n" -- "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -- "Please look at the Getting Started guide for additional information.\n", -- "vkCreateInstance Failure"); --#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) -- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME -- " extension.\n\n" -- "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -- "Please look at the Getting Started guide for additional information.\n", -- "vkCreateInstance Failure"); --#elif defined(VK_USE_PLATFORM_SCREEN_QNX) -- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_QNX_SCREEN_SURFACE_EXTENSION_NAME -+ // Subscribe to keyboard events -+ if (caps & WL_SEAT_CAPABILITY_KEYBOARD) { -+ demo->keyboard = wl_seat_get_keyboard(seat); -+ wl_keyboard_add_listener(demo->keyboard, &keyboard_listener, demo); -+ } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && demo->keyboard) { -+ wl_keyboard_destroy(demo->keyboard); -+ demo->keyboard = NULL; -+ } -+} -+ -+static const struct wl_seat_listener seat_listener = { -+ seat_handle_capabilities, -+}; -+ -+static void wm_base_ping(void *data UNUSED, struct xdg_wm_base *xdg_wm_base, uint32_t serial) { -+ xdg_wm_base_pong(xdg_wm_base, serial); -+} -+ -+static const struct xdg_wm_base_listener wm_base_listener = {wm_base_ping}; -+ -+static void registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface, -+ uint32_t version UNUSED) { -+ struct demo *demo = data; -+ // pickup wayland objects when they appear -+ if (strcmp(interface, wl_compositor_interface.name) == 0) { -+ uint32_t minVersion = version < 4 ? version : 4; -+ demo->compositor = wl_registry_bind(registry, id, &wl_compositor_interface, minVersion); -+ if (demo->VK_KHR_incremental_present_enabled && minVersion < 4) { -+ fprintf(stderr, "Wayland compositor doesn't support VK_KHR_incremental_present, disabling.\n"); -+ demo->VK_KHR_incremental_present_enabled = false; -+ } -+ } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) { -+ demo->xdg_wm_base = wl_registry_bind(registry, id, &xdg_wm_base_interface, 1); -+ xdg_wm_base_add_listener(demo->xdg_wm_base, &wm_base_listener, NULL); -+ } else if (strcmp(interface, wl_seat_interface.name) == 0) { -+ demo->seat = wl_registry_bind(registry, id, &wl_seat_interface, 1); -+ wl_seat_add_listener(demo->seat, &seat_listener, demo); -+ } else if (strcmp(interface, zxdg_decoration_manager_v1_interface.name) == 0) { -+ demo->xdg_decoration_mgr = wl_registry_bind(registry, id, &zxdg_decoration_manager_v1_interface, 1); -+ } -+} -+ -+static void registry_handle_global_remove(void *data UNUSED, struct wl_registry *registry UNUSED, uint32_t name UNUSED) {} -+ -+static const struct wl_registry_listener registry_listener = {registry_handle_global, registry_handle_global_remove}; -+#endif -+ -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+static const char *demo_init_xcb_connection(struct demo *demo) { -+ demo->xcb_library = initialize_xcb(); -+ if (NULL == demo->xcb_library) { -+ return "Cannot load XCB dynamic library."; -+ } -+ -+ const xcb_setup_t *setup; -+ xcb_screen_iterator_t iter; -+ int scr; -+ -+ const char *display_envar = getenv("DISPLAY"); -+ if (display_envar == NULL || display_envar[0] == '\0') { -+ return "Environment variable DISPLAY requires a valid value.n"; -+ } -+ -+ demo->connection = xcb_connect(NULL, &scr); -+ if (xcb_connection_has_error(demo->connection) > 0) { -+ return "Cannot connect to XCB."; -+ } -+ -+ setup = xcb_get_setup(demo->connection); -+ iter = xcb_setup_roots_iterator(setup); -+ while (scr-- > 0) xcb_screen_next(&iter); -+ -+ demo->screen = iter.data; -+ return NULL; -+} -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+static const char *demo_init_xlib_connection(struct demo *demo) { -+ demo->xlib_library = initialize_xlib(); -+ if (NULL == demo->xlib_library) { -+ return "Cannot load XLIB dynamic library."; -+ } -+ return NULL; -+} -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+static const char *demo_init_wayland_connection(struct demo *demo) { -+ demo->wayland_library = initialize_wayland(); -+ if (NULL == demo->wayland_library) { -+ return "Cannot load wayland dynamic library."; -+ } -+ -+ demo->wayland_display = wl_display_connect(NULL); -+ -+ if (demo->wayland_display == NULL) { -+ return "Cannot connect to wayland."; -+ } -+ -+ demo->registry = wl_display_get_registry(demo->wayland_display); -+ wl_registry_add_listener(demo->registry, ®istry_listener, demo); -+ wl_display_roundtrip(demo->wayland_display); -+ return NULL; -+} -+#endif -+ -+// Check that WSI platforms are available - only necessary when multiple WSI platforms exist, like on linux -+// If the wsi_platform is AUTO, this function also sets wsi_platform to the first available WSI platform -+// Otherwise, it errors out if the specified wsi_platform isn't available -+static void demo_check_and_set_wsi_platform(struct demo *demo) { -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_XCB || demo->wsi_platform == WSI_PLATFORM_AUTO) { -+ bool xcb_extension_available = false; -+ for (uint32_t i = 0; i < demo->enabled_extension_count; i++) { -+ if (strcmp(demo->extension_names[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) { -+ xcb_extension_available = true; -+ break; -+ } -+ } -+ if (xcb_extension_available) { -+ const char *error_msg = demo_init_xcb_connection(demo); -+ if (error_msg != NULL) { -+ if (demo->wsi_platform == WSI_PLATFORM_XCB) { -+ fprintf(stderr, "%s\nExiting ...\n", error_msg); -+ fflush(stdout); -+ exit(1); -+ } -+ } else { -+ demo->wsi_platform = WSI_PLATFORM_XCB; -+ return; -+ } -+ } -+ } -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_XLIB || demo->wsi_platform == WSI_PLATFORM_AUTO) { -+ bool xlib_extension_available = false; -+ for (uint32_t i = 0; i < demo->enabled_extension_count; i++) { -+ if (strcmp(demo->extension_names[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) { -+ xlib_extension_available = true; -+ break; -+ } -+ } -+ if (xlib_extension_available) { -+ const char *error_msg = demo_init_xlib_connection(demo); -+ if (error_msg != NULL) { -+ if (demo->wsi_platform == WSI_PLATFORM_XLIB) { -+ fprintf(stderr, "%s\nExiting ...\n", error_msg); -+ fflush(stdout); -+ exit(1); -+ } -+ } else { -+ demo->wsi_platform = WSI_PLATFORM_XLIB; -+ return; -+ } -+ } -+ } -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_WAYLAND || demo->wsi_platform == WSI_PLATFORM_AUTO) { -+ bool wayland_extension_available = false; -+ for (uint32_t i = 0; i < demo->enabled_extension_count; i++) { -+ if (strcmp(demo->extension_names[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) { -+ wayland_extension_available = true; -+ break; -+ } -+ } -+ if (wayland_extension_available) { -+ const char *error_msg = demo_init_wayland_connection(demo); -+ if (error_msg != NULL) { -+ if (demo->wsi_platform == WSI_PLATFORM_WAYLAND) { -+ fprintf(stderr, "%s\nExiting ...\n", error_msg); -+ fflush(stdout); -+ exit(1); -+ } -+ } else { -+ demo->wsi_platform = WSI_PLATFORM_WAYLAND; -+ return; -+ } -+ } -+ } -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ if (demo->wsi_platform == WSI_PLATFORM_DIRECTFB || demo->wsi_platform == WSI_PLATFORM_AUTO) { -+ bool direftfb_extension_available = false; -+ for (uint32_t i = 0; i < demo->enabled_extension_count; i++) { -+ if (strcmp(demo->extension_names[i], VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME) == 0) { -+ direftfb_extension_available = true; -+ break; -+ } -+ } -+ if (direftfb_extension_available) { -+ // Because DirectFB is still linked in, we can assume that it works if we got here -+ demo->wsi_platform = WSI_PLATFORM_DIRECTFB; -+ return; -+ } -+ } -+#endif -+#if defined(VK_USE_PLATFORM_WIN32_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_WIN32 || demo->wsi_platform == WSI_PLATFORM_AUTO) { -+ bool win32_extension_available = false; -+ for (uint32_t i = 0; i < demo->enabled_extension_count; i++) { -+ if (strcmp(demo->extension_names[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) { -+ win32_extension_available = true; -+ break; -+ } -+ } -+ if (win32_extension_available) { -+ demo->wsi_platform = WSI_PLATFORM_WIN32; -+ return; -+ } -+ } -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) -+ if (demo->wsi_platform == WSI_PLATFORM_METAL || demo->wsi_platform == WSI_PLATFORM_AUTO) { -+ bool metal_extension_available = false; -+ for (uint32_t i = 0; i < demo->enabled_extension_count; i++) { -+ if (strcmp(demo->extension_names[i], VK_EXT_METAL_SURFACE_EXTENSION_NAME) == 0) { -+ metal_extension_available = true; -+ break; -+ } -+ } -+ if (metal_extension_available) { -+ demo->wsi_platform = WSI_PLATFORM_METAL; -+ return; -+ } -+ } -+#endif -+#if defined(VK_USE_PLATFORM_ANDROID_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_ANDROID || demo->wsi_platform == WSI_PLATFORM_AUTO) { -+ bool android_extension_available = false; -+ for (uint32_t i = 0; i < demo->enabled_extension_count; i++) { -+ if (strcmp(demo->extension_names[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) { -+ android_extension_available = true; -+ break; -+ } -+ } -+ if (android_extension_available) { -+ demo->wsi_platform = WSI_PLATFORM_ANDROID; -+ return; -+ } -+ } -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ if (demo->wsi_platform == WSI_PLATFORM_QNX || demo->wsi_platform == WSI_PLATFORM_AUTO) { -+ bool qnx_extension_available = false; -+ for (uint32_t i = 0; i < demo->enabled_extension_count; i++) { -+ if (strcmp(demo->extension_names[i], VK_QNX_SCREEN_SURFACE_EXTENSION_NAME) == 0) { -+ qnx_extension_available = true; -+ break; -+ } -+ } -+ if (qnx_extension_available) { -+ demo->wsi_platform = WSI_PLATFORM_ANDROID; -+ return; -+ } -+ } -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_DISPLAY || demo->wsi_platform == WSI_PLATFORM_AUTO) { -+ bool display_extension_available = false; -+ for (uint32_t i = 0; i < demo->enabled_extension_count; i++) { -+ if (strcmp(demo->extension_names[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) { -+ display_extension_available = true; -+ break; -+ } -+ } -+ if (display_extension_available) { -+ // Because DISPLAY doesn't require additional libraries, we can assume that it works if we got here -+ demo->wsi_platform = WSI_PLATFORM_DISPLAY; -+ return; -+ } -+ } -+#endif -+} -+ -+static void demo_init_vk(struct demo *demo) { -+ VkResult err; -+ uint32_t instance_extension_count = 0; -+ uint32_t instance_layer_count = 0; -+ char *instance_validation_layers[] = {"VK_LAYER_KHRONOS_validation"}; -+ demo->enabled_extension_count = 0; -+ demo->enabled_layer_count = 0; -+ demo->is_minimized = false; -+ demo->cmd_pool = VK_NULL_HANDLE; -+ -+ err = volkInitialize(); -+ if (err != VK_SUCCESS) { -+ ERR_EXIT( -+ "Unable to find the Vulkan runtime on the system.\n\n" -+ "This likely indicates that no Vulkan capable drivers are installed.", -+ "Installation Failure"); -+ } -+ // Look for validation layers -+ VkBool32 validation_found = 0; -+ if (demo->validate) { -+ err = vkEnumerateInstanceLayerProperties(&instance_layer_count, NULL); -+ assert(!err); -+ -+ if (instance_layer_count > 0) { -+ VkLayerProperties *instance_layers = malloc(sizeof(VkLayerProperties) * instance_layer_count); -+ err = vkEnumerateInstanceLayerProperties(&instance_layer_count, instance_layers); -+ assert(!err); -+ -+ validation_found = demo_check_layers(ARRAY_SIZE(instance_validation_layers), instance_validation_layers, -+ instance_layer_count, instance_layers); -+ if (validation_found) { -+ demo->enabled_layer_count = ARRAY_SIZE(instance_validation_layers); -+ demo->enabled_layers[0] = "VK_LAYER_KHRONOS_validation"; -+ } -+ free(instance_layers); -+ } -+ -+ if (!validation_found) { -+ ERR_EXIT( -+ "vkEnumerateInstanceLayerProperties failed to find required validation layer.\n\n" -+ "Please look at the Getting Started guide for additional information.\n", -+ "vkCreateInstance Failure"); -+ } -+ } -+ -+ /* Look for instance extensions */ -+ VkBool32 surfaceExtFound = false; -+ VkBool32 platformSurfaceExtFound = false; -+ bool portabilityEnumerationActive = false; -+ memset(demo->extension_names, 0, sizeof(demo->extension_names)); -+ -+ err = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, NULL); -+ assert(!err); -+ -+ if (instance_extension_count > 0) { -+ VkExtensionProperties *instance_extensions = malloc(sizeof(VkExtensionProperties) * instance_extension_count); -+ err = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, instance_extensions); -+ assert(!err); -+ for (uint32_t i = 0; i < instance_extension_count; i++) { -+ if (!strcmp(VK_KHR_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName)) { -+ surfaceExtFound = true; -+ demo->extension_names[demo->enabled_extension_count++] = VK_KHR_SURFACE_EXTENSION_NAME; -+ } -+#if defined(VK_USE_PLATFORM_WIN32_KHR) -+ if (!strcmp(VK_KHR_WIN32_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName) && -+ (demo->wsi_platform == WSI_PLATFORM_AUTO || demo->wsi_platform == WSI_PLATFORM_WIN32)) { -+ platformSurfaceExtFound = true; -+ demo->extension_names[demo->enabled_extension_count++] = VK_KHR_WIN32_SURFACE_EXTENSION_NAME; -+ } -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ if (!strcmp(VK_KHR_XLIB_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName) && -+ (demo->wsi_platform == WSI_PLATFORM_AUTO || demo->wsi_platform == WSI_PLATFORM_XLIB)) { -+ platformSurfaceExtFound = true; -+ demo->extension_names[demo->enabled_extension_count++] = VK_KHR_XLIB_SURFACE_EXTENSION_NAME; -+ } -+#endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ if (!strcmp(VK_KHR_XCB_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName) && -+ (demo->wsi_platform == WSI_PLATFORM_AUTO || demo->wsi_platform == WSI_PLATFORM_XCB)) { -+ platformSurfaceExtFound = true; -+ demo->extension_names[demo->enabled_extension_count++] = VK_KHR_XCB_SURFACE_EXTENSION_NAME; -+ } -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ if (!strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName) && -+ (demo->wsi_platform == WSI_PLATFORM_AUTO || demo->wsi_platform == WSI_PLATFORM_WAYLAND)) { -+ platformSurfaceExtFound = true; -+ demo->extension_names[demo->enabled_extension_count++] = VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME; -+ } -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ if (!strcmp(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName) && -+ (demo->wsi_platform == WSI_PLATFORM_AUTO || demo->wsi_platform == WSI_PLATFORM_DIRECTFB)) { -+ platformSurfaceExtFound = true; -+ demo->extension_names[demo->enabled_extension_count++] = VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME; -+ } -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -+ if (!strcmp(VK_KHR_DISPLAY_EXTENSION_NAME, instance_extensions[i].extensionName) && -+ (demo->wsi_platform == WSI_PLATFORM_AUTO || demo->wsi_platform == WSI_PLATFORM_DISPLAY)) { -+ platformSurfaceExtFound = true; -+ demo->extension_names[demo->enabled_extension_count++] = VK_KHR_DISPLAY_EXTENSION_NAME; -+ } -+#endif -+#if defined(VK_USE_PLATFORM_ANDROID_KHR) -+ if (!strcmp(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName) && -+ (demo->wsi_platform == WSI_PLATFORM_AUTO || demo->wsi_platform == WSI_PLATFORM_ANDROID)) { -+ platformSurfaceExtFound = true; -+ demo->extension_names[demo->enabled_extension_count++] = VK_KHR_ANDROID_SURFACE_EXTENSION_NAME; -+ } -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) -+ if (!strcmp(VK_EXT_METAL_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName) && -+ (demo->wsi_platform == WSI_PLATFORM_AUTO || demo->wsi_platform == WSI_PLATFORM_METAL)) { -+ platformSurfaceExtFound = true; -+ demo->extension_names[demo->enabled_extension_count++] = VK_EXT_METAL_SURFACE_EXTENSION_NAME; -+ } -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ if (!strcmp(VK_QNX_SCREEN_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName) && -+ (demo->wsi_platform == WSI_PLATFORM_AUTO || demo->wsi_platform == WSI_PLATFORM_QNX)) { -+ platformSurfaceExtFound = true; -+ demo->extension_names[demo->enabled_extension_count++] = VK_QNX_SCREEN_SURFACE_EXTENSION_NAME; -+ } -+#endif -+ if (!strcmp(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, instance_extensions[i].extensionName)) { -+ demo->extension_names[demo->enabled_extension_count++] = VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; -+ } -+ if (!strcmp(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, instance_extensions[i].extensionName)) { -+ if (demo->validate) { -+ demo->extension_names[demo->enabled_extension_count++] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME; -+ } -+ } -+ // We want cube to be able to enumerate drivers that support the portability_subset extension, so we have to enable -+ // the portability enumeration extension. -+ if (!strcmp(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, instance_extensions[i].extensionName)) { -+ portabilityEnumerationActive = true; -+ demo->extension_names[demo->enabled_extension_count++] = VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME; -+ } -+ assert(demo->enabled_extension_count < 64); -+ } -+ -+ free(instance_extensions); -+ } -+ -+ if (!surfaceExtFound) { -+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_SURFACE_EXTENSION_NAME - " extension.\n\n" - "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" - "Please look at the Getting Started guide for additional information.\n", - "vkCreateInstance Failure"); -+ } -+ if (!platformSurfaceExtFound) { -+#if defined(VK_USE_PLATFORM_WIN32_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_WIN32) { -+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_WIN32_SURFACE_EXTENSION_NAME -+ " extension.\n\n" -+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -+ "Please look at the Getting Started guide for additional information.\n", -+ "vkCreateInstance Failure"); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) -+ if (demo->wsi_platform == WSI_PLATFORM_METAL) { -+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_EXT_METAL_SURFACE_EXTENSION_NAME -+ " extension.\n\n" -+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -+ "Please look at the Getting Started guide for additional information.\n", -+ "vkCreateInstance Failure"); -+ } - #endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_XCB) { -+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_XCB_SURFACE_EXTENSION_NAME -+ " extension.\n\n" -+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -+ "Please look at the Getting Started guide for additional information.\n", -+ "vkCreateInstance Failure"); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_WAYLAND) { -+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME -+ " extension.\n\n" -+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -+ "Please look at the Getting Started guide for additional information.\n", -+ "vkCreateInstance Failure"); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_DISPLAY) { -+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_DISPLAY_EXTENSION_NAME -+ " extension.\n\n" -+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -+ "Please look at the Getting Started guide for additional information.\n", -+ "vkCreateInstance Failure"); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_ANDROID_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_ANDROID) { -+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_ANDROID_SURFACE_EXTENSION_NAME -+ " extension.\n\n" -+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -+ "Please look at the Getting Started guide for additional information.\n", -+ "vkCreateInstance Failure"); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_XLIB) { -+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_XLIB_SURFACE_EXTENSION_NAME -+ " extension.\n\n" -+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -+ "Please look at the Getting Started guide for additional information.\n", -+ "vkCreateInstance Failure"); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ if (demo->wsi_platform == WSI_PLATFORM_DIRECTFB) { -+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME -+ " extension.\n\n" -+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -+ "Please look at the Getting Started guide for additional information.\n", -+ "vkCreateInstance Failure"); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ if (demo->wsi_platform == WSI_PLATFORM_WIN32) { -+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_QNX_SCREEN_SURFACE_EXTENSION_NAME -+ " extension.\n\n" -+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -+ "Please look at the Getting Started guide for additional information.\n", -+ "vkCreateInstance Failure"); -+ } -+#endif -+ ERR_EXIT( -+ "vkEnumerateInstanceExtensionProperties failed to find any supported WSI surface extension.\n\n" -+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -+ "Please look at the Getting Started guide for additional information.\n", -+ "vkCreateInstance Failure"); -+ } -+ -+ bool auto_wsi_platform = demo->wsi_platform == WSI_PLATFORM_AUTO; -+ -+ demo_check_and_set_wsi_platform(demo); -+ -+ // Print a message to indicate the automatically set WSI platform -+ if (auto_wsi_platform && demo->wsi_platform != WSI_PLATFORM_AUTO) { -+ fprintf(stderr, "Selected WSI platform: %s\n", wsi_to_string(demo->wsi_platform)); - } -+ - const VkApplicationInfo app = { - .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, - .pNext = NULL, -@@ -3636,48 +4165,55 @@ static void demo_init_vk(struct demo *demo) { - ERR_EXIT("Specified GPU number is not present", "User Error"); - } - -+ if (demo->wsi_platform == WSI_PLATFORM_DISPLAY) { - #if defined(VK_USE_PLATFORM_DISPLAY_KHR) -- demo->gpu_number = find_display_gpu(demo->gpu_number, gpu_count, physical_devices); -- if (demo->gpu_number < 0) { -- printf("Cannot find any display!\n"); -+ demo->gpu_number = find_display_gpu(demo->gpu_number, gpu_count, physical_devices); -+ if (demo->gpu_number < 0) { -+ printf("Cannot find any display!\n"); -+ fflush(stdout); -+ exit(1); -+ } -+#else -+ printf("WSI selection was set to DISPLAY but vkcube was not compiled with support for the DISPLAY platform, exiting \n"); - fflush(stdout); - exit(1); -- } --#else -- /* Try to auto select most suitable device */ -- if (demo->gpu_number == -1) { -- uint32_t count_device_type[VK_PHYSICAL_DEVICE_TYPE_CPU + 1]; -- memset(count_device_type, 0, sizeof(count_device_type)); -- -- VkPhysicalDeviceProperties physicalDeviceProperties; -- for (uint32_t i = 0; i < gpu_count; i++) { -- vkGetPhysicalDeviceProperties(physical_devices[i], &physicalDeviceProperties); -- assert(physicalDeviceProperties.deviceType <= VK_PHYSICAL_DEVICE_TYPE_CPU); -- count_device_type[physicalDeviceProperties.deviceType]++; -- } -- -- VkPhysicalDeviceType search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; -- if (count_device_type[VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU]) { -- search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; -- } else if (count_device_type[VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU]) { -- search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU; -- } else if (count_device_type[VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU]) { -- search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU; -- } else if (count_device_type[VK_PHYSICAL_DEVICE_TYPE_CPU]) { -- search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_CPU; -- } else if (count_device_type[VK_PHYSICAL_DEVICE_TYPE_OTHER]) { -- search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_OTHER; -- } -+#endif -+ } else { -+ /* Try to auto select most suitable device */ -+ if (demo->gpu_number == -1) { -+ uint32_t count_device_type[VK_PHYSICAL_DEVICE_TYPE_CPU + 1]; -+ memset(count_device_type, 0, sizeof(count_device_type)); -+ -+ VkPhysicalDeviceProperties physicalDeviceProperties; -+ for (uint32_t i = 0; i < gpu_count; i++) { -+ vkGetPhysicalDeviceProperties(physical_devices[i], &physicalDeviceProperties); -+ assert(physicalDeviceProperties.deviceType <= VK_PHYSICAL_DEVICE_TYPE_CPU); -+ count_device_type[physicalDeviceProperties.deviceType]++; -+ } - -- for (uint32_t i = 0; i < gpu_count; i++) { -- vkGetPhysicalDeviceProperties(physical_devices[i], &physicalDeviceProperties); -- if (physicalDeviceProperties.deviceType == search_for_device_type) { -- demo->gpu_number = i; -- break; -+ VkPhysicalDeviceType search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; -+ if (count_device_type[VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU]) { -+ search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; -+ } else if (count_device_type[VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU]) { -+ search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU; -+ } else if (count_device_type[VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU]) { -+ search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU; -+ } else if (count_device_type[VK_PHYSICAL_DEVICE_TYPE_CPU]) { -+ search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_CPU; -+ } else if (count_device_type[VK_PHYSICAL_DEVICE_TYPE_OTHER]) { -+ search_for_device_type = VK_PHYSICAL_DEVICE_TYPE_OTHER; -+ } -+ -+ for (uint32_t i = 0; i < gpu_count; i++) { -+ vkGetPhysicalDeviceProperties(physical_devices[i], &physicalDeviceProperties); -+ if (physicalDeviceProperties.deviceType == search_for_device_type) { -+ demo->gpu_number = i; -+ break; -+ } - } - } - } --#endif -+ - assert(demo->gpu_number >= 0); - demo->gpu = physical_devices[demo->gpu_number]; - { -@@ -3828,81 +4364,108 @@ static void demo_create_device(struct demo *demo) { - } - - static void demo_create_surface(struct demo *demo) { -- VkResult U_ASSERT_ONLY err; -+ VkResult U_ASSERT_ONLY err = VK_SUCCESS; - - // Create a WSI surface for the window: - #if defined(VK_USE_PLATFORM_WIN32_KHR) -- VkWin32SurfaceCreateInfoKHR createInfo; -- createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; -- createInfo.pNext = NULL; -- createInfo.flags = 0; -- createInfo.hinstance = demo->connection; -- createInfo.hwnd = demo->window; -- -- err = vkCreateWin32SurfaceKHR(demo->inst, &createInfo, NULL, &demo->surface); --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -- VkWaylandSurfaceCreateInfoKHR createInfo; -- createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; -- createInfo.pNext = NULL; -- createInfo.flags = 0; -- createInfo.display = demo->display; -- createInfo.surface = demo->window; -- -- err = vkCreateWaylandSurfaceKHR(demo->inst, &createInfo, NULL, &demo->surface); --#elif defined(VK_USE_PLATFORM_ANDROID_KHR) -- VkAndroidSurfaceCreateInfoKHR createInfo; -- createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; -- createInfo.pNext = NULL; -- createInfo.flags = 0; -- createInfo.window = (struct ANativeWindow *)(demo->window); -- -- err = vkCreateAndroidSurfaceKHR(demo->inst, &createInfo, NULL, &demo->surface); --#elif defined(VK_USE_PLATFORM_XLIB_KHR) -- VkXlibSurfaceCreateInfoKHR createInfo; -- createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; -- createInfo.pNext = NULL; -- createInfo.flags = 0; -- createInfo.dpy = demo->display; -- createInfo.window = demo->xlib_window; -- -- err = vkCreateXlibSurfaceKHR(demo->inst, &createInfo, NULL, &demo->surface); --#elif defined(VK_USE_PLATFORM_XCB_KHR) -- VkXcbSurfaceCreateInfoKHR createInfo; -- createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; -- createInfo.pNext = NULL; -- createInfo.flags = 0; -- createInfo.connection = demo->connection; -- createInfo.window = demo->xcb_window; -- -- err = vkCreateXcbSurfaceKHR(demo->inst, &createInfo, NULL, &demo->surface); --#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) -- VkDirectFBSurfaceCreateInfoEXT createInfo; -- createInfo.sType = VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT; -- createInfo.pNext = NULL; -- createInfo.flags = 0; -- createInfo.dfb = demo->dfb; -- createInfo.surface = demo->window; -- -- err = vkCreateDirectFBSurfaceEXT(demo->inst, &createInfo, NULL, &demo->surface); --#elif defined(VK_USE_PLATFORM_DISPLAY_KHR) -- err = demo_create_display_surface(demo); --#elif defined(VK_USE_PLATFORM_METAL_EXT) -- VkMetalSurfaceCreateInfoEXT surface; -- surface.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; -- surface.pNext = NULL; -- surface.flags = 0; -- surface.pLayer = demo->caMetalLayer; -- -- err = vkCreateMetalSurfaceEXT(demo->inst, &surface, NULL, &demo->surface); --#elif defined(VK_USE_PLATFORM_SCREEN_QNX) -- VkScreenSurfaceCreateInfoQNX createInfo; -- createInfo.sType = VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX; -- createInfo.pNext = NULL; -- createInfo.flags = 0; -- createInfo.context = demo->screen_context; -- createInfo.window = demo->screen_window; -- -- err = vkCreateScreenSurfaceQNX(demo->inst, &createInfo, NULL, &demo->surface); -+ if (demo->wsi_platform == WSI_PLATFORM_WIN32) { -+ VkWin32SurfaceCreateInfoKHR win32_createInfo; -+ win32_createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; -+ win32_createInfo.pNext = NULL; -+ win32_createInfo.flags = 0; -+ win32_createInfo.hinstance = demo->connection; -+ win32_createInfo.hwnd = demo->window; -+ -+ err = vkCreateWin32SurfaceKHR(demo->inst, &win32_createInfo, NULL, &demo->surface); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_WAYLAND) { -+ VkWaylandSurfaceCreateInfoKHR wayland_createInfo; -+ wayland_createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; -+ wayland_createInfo.pNext = NULL; -+ wayland_createInfo.flags = 0; -+ wayland_createInfo.display = demo->wayland_display; -+ wayland_createInfo.surface = demo->window; -+ -+ err = vkCreateWaylandSurfaceKHR(demo->inst, &wayland_createInfo, NULL, &demo->surface); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_ANDROID_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_ANDROID) { -+ VkAndroidSurfaceCreateInfoKHR android_createInfo; -+ android_createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; -+ android_createInfo.pNext = NULL; -+ android_createInfo.flags = 0; -+ android_createInfo.window = (struct ANativeWindow *)(demo->window); -+ -+ err = vkCreateAndroidSurfaceKHR(demo->inst, &android_createInfo, NULL, &demo->surface); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_XLIB) { -+ VkXlibSurfaceCreateInfoKHR xlib_createInfo; -+ xlib_createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; -+ xlib_createInfo.pNext = NULL; -+ xlib_createInfo.flags = 0; -+ xlib_createInfo.dpy = demo->xlib_display; -+ xlib_createInfo.window = demo->xlib_window; -+ -+ err = vkCreateXlibSurfaceKHR(demo->inst, &xlib_createInfo, NULL, &demo->surface); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_XCB) { -+ 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 = demo->connection; -+ xcb_createInfo.window = demo->xcb_window; -+ -+ err = vkCreateXcbSurfaceKHR(demo->inst, &xcb_createInfo, NULL, &demo->surface); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ if (demo->wsi_platform == WSI_PLATFORM_DIRECTFB) { -+ VkDirectFBSurfaceCreateInfoEXT directfb_createInfo; -+ directfb_createInfo.sType = VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT; -+ directfb_createInfo.pNext = NULL; -+ directfb_createInfo.flags = 0; -+ directfb_createInfo.dfb = demo->dfb; -+ directfb_createInfo.surface = demo->directfb_window; -+ -+ err = vkCreateDirectFBSurfaceEXT(demo->inst, &directfb_createInfo, NULL, &demo->surface); -+ } -+ -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -+ if (demo->wsi_platform == WSI_PLATFORM_DISPLAY) { -+ err = demo_create_display_surface(demo); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) -+ if (demo->wsi_platform == WSI_PLATFORM_METAL) { -+ VkMetalSurfaceCreateInfoEXT metal_createInfo; -+ metal_createInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; -+ metal_createInfo.pNext = NULL; -+ metal_createInfo.flags = 0; -+ metal_createInfo.pLayer = demo->caMetalLayer; -+ -+ err = vkCreateMetalSurfaceEXT(demo->inst, &metal_createInfo, NULL, &demo->surface); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ if (demo->wsi_platform == WSI_PLATFORM_QNX) { -+ VkScreenSurfaceCreateInfoQNX qnx_createInfo; -+ qnx_createInfo.sType = VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX; -+ qnx_createInfo.pNext = NULL; -+ qnx_createInfo.flags = 0; -+ qnx_createInfo.context = demo->screen_context; -+ qnx_createInfo.window = demo->screen_window; -+ -+ err = vkCreateScreenSurfaceQNX(demo->inst, &qnx_createInfo, NULL, &demo->surface); -+ } - #endif - assert(!err); - } -@@ -4038,159 +4601,6 @@ static void demo_init_vk_swapchain(struct demo *demo) { - vkGetPhysicalDeviceMemoryProperties(demo->gpu, &demo->memory_properties); - } - --#if defined(VK_USE_PLATFORM_WAYLAND_KHR) --static void pointer_handle_enter(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t sx, -- wl_fixed_t sy) {} -- --static void pointer_handle_leave(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface) {} -- --static void pointer_handle_motion(void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy) {} -- --static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, -- uint32_t state) { -- struct demo *demo = data; -- if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED) { -- xdg_toplevel_move(demo->xdg_toplevel, demo->seat, serial); -- } --} -- --static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) {} -- --static const struct wl_pointer_listener pointer_listener = { -- pointer_handle_enter, pointer_handle_leave, pointer_handle_motion, pointer_handle_button, pointer_handle_axis, --}; -- --static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size) {} -- --static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface, -- struct wl_array *keys) {} -- --static void keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface) {} -- --static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, -- uint32_t state) { -- if (state != WL_KEYBOARD_KEY_STATE_RELEASED) return; -- struct demo *demo = data; -- switch (key) { -- case KEY_ESC: // Escape -- demo->quit = true; -- break; -- case KEY_LEFT: // left arrow key -- demo->spin_angle -= demo->spin_increment; -- break; -- case KEY_RIGHT: // right arrow key -- demo->spin_angle += demo->spin_increment; -- break; -- case KEY_SPACE: // space bar -- demo->pause = !demo->pause; -- break; -- } --} -- --static void keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, -- uint32_t mods_latched, uint32_t mods_locked, uint32_t group) {} -- --static const struct wl_keyboard_listener keyboard_listener = { -- keyboard_handle_keymap, keyboard_handle_enter, keyboard_handle_leave, keyboard_handle_key, keyboard_handle_modifiers, --}; -- --static void seat_handle_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps) { -- // Subscribe to pointer events -- struct demo *demo = data; -- if ((caps & WL_SEAT_CAPABILITY_POINTER) && !demo->pointer) { -- demo->pointer = wl_seat_get_pointer(seat); -- wl_pointer_add_listener(demo->pointer, &pointer_listener, demo); -- } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && demo->pointer) { -- wl_pointer_destroy(demo->pointer); -- demo->pointer = NULL; -- } -- // Subscribe to keyboard events -- if (caps & WL_SEAT_CAPABILITY_KEYBOARD) { -- demo->keyboard = wl_seat_get_keyboard(seat); -- wl_keyboard_add_listener(demo->keyboard, &keyboard_listener, demo); -- } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && demo->keyboard) { -- wl_keyboard_destroy(demo->keyboard); -- demo->keyboard = NULL; -- } --} -- --static const struct wl_seat_listener seat_listener = { -- seat_handle_capabilities, --}; -- --static void wm_base_ping(void *data UNUSED, struct xdg_wm_base *xdg_wm_base, uint32_t serial) { -- xdg_wm_base_pong(xdg_wm_base, serial); --} -- --static const struct xdg_wm_base_listener wm_base_listener = {wm_base_ping}; -- --static void registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface, -- uint32_t version UNUSED) { -- struct demo *demo = data; -- // pickup wayland objects when they appear -- if (strcmp(interface, wl_compositor_interface.name) == 0) { -- uint32_t minVersion = version < 4 ? version : 4; -- demo->compositor = wl_registry_bind(registry, id, &wl_compositor_interface, minVersion); -- if (demo->VK_KHR_incremental_present_enabled && minVersion < 4) { -- fprintf(stderr, "Wayland compositor doesn't support VK_KHR_incremental_present, disabling.\n"); -- demo->VK_KHR_incremental_present_enabled = false; -- } -- } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) { -- demo->xdg_wm_base = wl_registry_bind(registry, id, &xdg_wm_base_interface, 1); -- xdg_wm_base_add_listener(demo->xdg_wm_base, &wm_base_listener, NULL); -- } else if (strcmp(interface, wl_seat_interface.name) == 0) { -- demo->seat = wl_registry_bind(registry, id, &wl_seat_interface, 1); -- wl_seat_add_listener(demo->seat, &seat_listener, demo); -- } else if (strcmp(interface, zxdg_decoration_manager_v1_interface.name) == 0) { -- demo->xdg_decoration_mgr = wl_registry_bind(registry, id, &zxdg_decoration_manager_v1_interface, 1); -- } --} -- --static void registry_handle_global_remove(void *data UNUSED, struct wl_registry *registry UNUSED, uint32_t name UNUSED) {} -- --static const struct wl_registry_listener registry_listener = {registry_handle_global, registry_handle_global_remove}; --#endif -- --static void demo_init_connection(struct demo *demo) { --#if defined(VK_USE_PLATFORM_XCB_KHR) -- const xcb_setup_t *setup; -- xcb_screen_iterator_t iter; -- int scr; -- -- const char *display_envar = getenv("DISPLAY"); -- if (display_envar == NULL || display_envar[0] == '\0') { -- printf("Environment variable DISPLAY requires a valid value.\nExiting ...\n"); -- fflush(stdout); -- exit(1); -- } -- -- demo->connection = xcb_connect(NULL, &scr); -- if (xcb_connection_has_error(demo->connection) > 0) { -- printf("Cannot connect to XCB.\nExiting ...\n"); -- fflush(stdout); -- exit(1); -- } -- -- setup = xcb_get_setup(demo->connection); -- iter = xcb_setup_roots_iterator(setup); -- while (scr-- > 0) xcb_screen_next(&iter); -- -- demo->screen = iter.data; --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -- demo->display = wl_display_connect(NULL); -- -- if (demo->display == NULL) { -- printf("Cannot connect to wayland.\nExiting ...\n"); -- fflush(stdout); -- exit(1); -- } -- -- demo->registry = wl_display_get_registry(demo->display); -- wl_registry_add_listener(demo->registry, ®istry_listener, demo); -- wl_display_roundtrip(demo->display); --#endif --} -- - static void demo_init(struct demo *demo, int argc, char **argv) { - vec3 eye = {0.0f, 3.0f, 5.0f}; - vec3 origin = {0, 0, 0}; -@@ -4223,7 +4633,7 @@ static void demo_init(struct demo *demo, int argc, char **argv) { - continue; - } - if (strcmp(argv[i], "--xlib") == 0) { -- fprintf(stderr, "--xlib is deprecated and no longer does anything"); -+ fprintf(stderr, "--xlib is deprecated and no longer does anything\n"); - continue; - } - if (strcmp(argv[i], "--c") == 0 && demo->frameCount == INT32_MAX && i < argc - 1 && -@@ -4275,10 +4685,85 @@ static void demo_init(struct demo *demo, int argc, char **argv) { - demo->force_errors = true; - continue; - } -- -+ if ((strcmp(argv[i], "--wsi") == 0) && (i < argc - 1)) { -+ size_t argc_len = strlen(argv[i + 1]); -+ for (size_t argc_i = 0; argc_i < argc_len; argc_i++) { -+ argv[i + 1][argc_i] = tolower(argv[i + 1][argc_i]); -+ } -+ WSI_PLATFORM selection = wsi_from_string(argv[i + 1]); -+ if (selection == WSI_PLATFORM_INVALID) { -+ printf( -+ "The --wsi parameter %s is not a supported WSI platform. The list of available platforms is available from " -+ "--help\n", -+ (const char *)&(argv[i + 1][0])); -+ fflush(stdout); -+ exit(1); -+ } -+ demo->wsi_platform = selection; -+ i++; -+ continue; -+ } - #if defined(ANDROID) - ERR_EXIT("Usage: vkcube [--validate]\n", "Usage"); - #else -+ -+ // Making the help for --wsi nice requires a little extra work since the list depends on what is available at -+ // compile time -+ size_t max_str_len = 100; -+ char *available_wsi_platforms = (char *)malloc(max_str_len); -+ memset(available_wsi_platforms, 0, max_str_len); -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ strncat(available_wsi_platforms, "xcb", max_str_len); -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ if (strlen(available_wsi_platforms) > 0) { -+ strncat(available_wsi_platforms, "|", max_str_len); -+ } -+ strncat(available_wsi_platforms, "xlib", max_str_len); -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ if (strlen(available_wsi_platforms) > 0) { -+ strncat(available_wsi_platforms, "|", max_str_len); -+ } -+ strncat(available_wsi_platforms, "wayland", max_str_len); -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ if (strlen(available_wsi_platforms) > 0) { -+ strncat(available_wsi_platforms, "|", max_str_len); -+ } -+ strncat(available_wsi_platforms, "directfb", max_str_len); -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -+ if (strlen(available_wsi_platforms) > 0) { -+ strncat(available_wsi_platforms, "|", max_str_len); -+ } -+ strncat(available_wsi_platforms, "display", max_str_len); -+#endif -+#if defined(VK_USE_PLATFORM_WIN32_KHR) -+ if (strlen(available_wsi_platforms) > 0) { -+ strncat(available_wsi_platforms, "|", max_str_len); -+ } -+ strncat(available_wsi_platforms, "win32", max_str_len); -+#endif -+#if defined(VK_USE_PLATFORM_ANDROID_KHR) -+ if (strlen(available_wsi_platforms) > 0) { -+ strncat(available_wsi_platforms, "|", max_str_len); -+ } -+ strncat(available_wsi_platforms, "android", max_str_len); -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) -+ if (strlen(available_wsi_platforms) > 0) { -+ strncat(available_wsi_platforms, "|", max_str_len); -+ } -+ strncat(available_wsi_platforms, "metal", max_str_len); -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ if (strlen(available_wsi_platforms) > 0) { -+ strncat(available_wsi_platforms, "|", max_str_len); -+ } -+ strncat(available_wsi_platforms, "qnx", max_str_len); -+#endif -+ - char *message = - "Usage:\n %s\t[--use_staging] [--validate]\n" - "\t[--break] [--c ] [--suppress_popups]\n" -@@ -4287,19 +4772,20 @@ static void demo_init(struct demo *demo, int argc, char **argv) { - "\t[--present_mode ]\n" - "\t[--width ] [--height ]\n" - "\t[--force_errors]\n" -+ "\t[--wsi <%s>]\n" - "\t\n" - "\t\tVK_PRESENT_MODE_IMMEDIATE_KHR = %d\n" - "\t\tVK_PRESENT_MODE_MAILBOX_KHR = %d\n" - "\t\tVK_PRESENT_MODE_FIFO_KHR = %d\n" - "\t\tVK_PRESENT_MODE_FIFO_RELAXED_KHR = %d\n"; -- int length = snprintf(NULL, 0, message, APP_SHORT_NAME, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR, -- VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_FIFO_RELAXED_KHR); -+ int length = snprintf(NULL, 0, message, APP_SHORT_NAME, available_wsi_platforms, VK_PRESENT_MODE_IMMEDIATE_KHR, -+ VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_FIFO_RELAXED_KHR); - char *usage = (char *)malloc(length + 1); - if (!usage) { - exit(1); - } -- snprintf(usage, length + 1, message, APP_SHORT_NAME, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR, -- VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_FIFO_RELAXED_KHR); -+ snprintf(usage, length + 1, message, APP_SHORT_NAME, available_wsi_platforms, VK_PRESENT_MODE_IMMEDIATE_KHR, -+ VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_FIFO_RELAXED_KHR); - #if defined(_WIN32) - if (!demo->suppress_popups) MessageBox(NULL, usage, "Usage Error", MB_OK); - #else -@@ -4311,8 +4797,6 @@ static void demo_init(struct demo *demo, int argc, char **argv) { - #endif - } - -- demo_init_connection(demo); -- - demo_init_vk(demo); - - demo->spin_angle = 4.0f; -@@ -4418,7 +4902,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, - return (int)msg.wParam; - } - --#elif defined(VK_USE_PLATFORM_METAL_EXT) -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) - static void demo_main(struct demo *demo, void *caMetalLayer, int argc, const char *argv[]) { - demo_init(demo, argc, (char **)argv); - demo->caMetalLayer = caMetalLayer; -@@ -4427,7 +4912,8 @@ static void demo_main(struct demo *demo, void *caMetalLayer, int argc, const cha - demo->spin_angle = 0.4f; - } - --#elif defined(VK_USE_PLATFORM_ANDROID_KHR) -+#endif -+#if defined(VK_USE_PLATFORM_ANDROID_KHR) - #include - #include - #include "android_util.h" -@@ -4514,40 +5000,94 @@ void android_main(struct android_app *app) { - } - } - } --#else -+#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__QNX__) || defined(__GNU__) - int main(int argc, char **argv) { - struct demo demo; - - demo_init(&demo, argc, argv); -+ switch (demo.wsi_platform) { -+ default: -+ case (WSI_PLATFORM_AUTO): -+ fprintf(stderr, -+ "WSI platform should have already been set, indicating a bug. Please set a WSI platform manually with " -+ "--wsi\n"); -+ exit(1); -+ break; - #if defined(VK_USE_PLATFORM_XCB_KHR) -- demo_create_xcb_window(&demo); --#elif defined(VK_USE_PLATFORM_XLIB_KHR) -- demo_create_xlib_window(&demo); --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -- demo_create_window(&demo); --#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) -- demo_create_directfb_window(&demo); --#elif defined(VK_USE_PLATFORM_SCREEN_QNX) -- demo_create_window(&demo); -+ case (WSI_PLATFORM_XCB): -+ demo_create_xcb_window(&demo); -+ break; -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ case (WSI_PLATFORM_XLIB): -+ demo_create_xlib_window(&demo); -+ break; -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ case (WSI_PLATFORM_WAYLAND): -+ demo_create_wayland_window(&demo); -+ break; -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ case (WSI_PLATFORM_DIRECTFB): -+ demo_create_directfb_window(&demo); -+ break; -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ case (WSI_PLATFORM_QNX): -+ demo_create_screen_window(&demo); -+ break; - #endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -+ case (WSI_PLATFORM_DISPLAY): -+ // nothing to do here -+ break; -+#endif -+ } - - demo_init_vk_swapchain(&demo); - - demo_prepare(&demo); - -+ switch (demo.wsi_platform) { -+ default: -+ case (WSI_PLATFORM_AUTO): -+ fprintf(stderr, -+ "WSI platform should have already been set, indicating a bug. Please set a WSI platform manually with " -+ "--wsi\n"); -+ exit(1); -+ break; - #if defined(VK_USE_PLATFORM_XCB_KHR) -- demo_run_xcb(&demo); --#elif defined(VK_USE_PLATFORM_XLIB_KHR) -- demo_run_xlib(&demo); --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -- demo_run(&demo); --#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) -- demo_run_directfb(&demo); --#elif defined(VK_USE_PLATFORM_DISPLAY_KHR) -- demo_run_display(&demo); --#elif defined(VK_USE_PLATFORM_SCREEN_QNX) -- demo_run(&demo); -+ case (WSI_PLATFORM_XCB): -+ demo_run_xcb(&demo); -+ break; - #endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ case (WSI_PLATFORM_XLIB): -+ demo_run_xlib(&demo); -+ break; -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ case (WSI_PLATFORM_WAYLAND): -+ demo_run(&demo); -+ break; -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ case (WSI_PLATFORM_DIRECTFB): -+ demo_run_directfb(&demo); -+ break; -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -+ case (WSI_PLATFORM_DISPLAY): -+ demo_run_display(&demo); -+ break; -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ case (WSI_PLATFORM_QNX): -+ demo_run(&demo); -+ break; -+#endif -+ } - - demo_cleanup(&demo); - -diff --git a/cube/cube.cpp b/cube/cube.cpp -index 46b6fdb3..024d3eac 100644 ---- a/cube/cube.cpp -+++ b/cube/cube.cpp -@@ -19,14 +19,6 @@ - * Author: Charles Giessen - */ - --#if defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR) --#include --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) --#include --#include "xdg-shell-client-header.h" --#include "xdg-decoration-client-header.h" --#endif -- - #include - #include - #include -@@ -38,6 +30,17 @@ - #include - #include - -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+#include "xlib_loader.h" -+#endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+#include "xcb_loader.h" -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+#include -+#include "wayland_loader.h" -+#endif -+ - #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 - #define VULKAN_HPP_NO_EXCEPTIONS - #define VULKAN_HPP_TYPESAFE_CONVERSION 1 -@@ -197,6 +200,96 @@ static const float g_uv_buffer_data[] = { - 1.0f, 0.0f, - }; - // clang-format on -+enum class WsiPlatform { -+ auto_ = 0, -+ win32, -+ metal, -+ android, -+ qnx, -+ xcb, -+ xlib, -+ wayland, -+ directfb, -+ display, -+ invalid, // Sentinel just to indicate invalid user input -+}; -+ -+WsiPlatform wsi_from_string(std::string const &str) { -+ if (str == "auto") return WsiPlatform::auto_; -+#if defined(VK_USE_PLATFORM_WIN32_KHR) -+ if (str == "win32") return WsiPlatform::win32; -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) -+ if (str == "metal") return WsiPlatform::metal; -+#endif -+#if defined(VK_USE_PLATFORM_ANDROID_KHR) -+ if (str == "android") return WsiPlatform::android; -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ if (str == "qnx") return WsiPlatform::qnx; -+#endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ if (str == "xcb") return WsiPlatform::xcb; -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ if (str == "xlib") return WsiPlatform::xlib; -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ if (str == "wayland") return WsiPlatform::wayland; -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ if (str == "directfb") return WsiPlatform::directfb; -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -+ if (str == "display") return WsiPlatform::display; -+#endif -+ return WsiPlatform::invalid; -+}; -+ -+const char *wsi_to_string(WsiPlatform wsi_platform) { -+ switch (wsi_platform) { -+ case (WsiPlatform::auto_): -+ return "auto"; -+#if defined(VK_USE_PLATFORM_WIN32_KHR) -+ case (WsiPlatform::win32): -+ return "win32"; -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) -+ case (WsiPlatform::metal): -+ return "metal"; -+#endif -+#if defined(VK_USE_PLATFORM_ANDROID_KHR) -+ case (WsiPlatform::android): -+ return "android"; -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ case (WsiPlatform::qnx): -+ return "qnx"; -+#endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ case (WsiPlatform::xcb): -+ return "xcb"; -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ case (WsiPlatform::xlib): -+ return "xlib"; -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ case (WsiPlatform::wayland): -+ return "wayland"; -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ case (WsiPlatform::directfb): -+ return "directfb"; -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -+ case (WsiPlatform::display): -+ return "display"; -+#endif -+ default: -+ return "unknown"; -+ } -+}; - - struct SwapchainImageResources { - vk::Image image; -@@ -222,7 +315,7 @@ struct Demo { - void prepare_init_cmd(); - void flush_init_cmd(); - void init(int argc, char **argv); -- void init_connection(); -+ void check_and_set_wsi_platform(); - void init_vk(); - void init_vk_swapchain(); - void prepare(); -@@ -260,27 +353,37 @@ struct Demo { - #if defined(VK_USE_PLATFORM_WIN32_KHR) - void run(); - void create_window(); --#elif defined(VK_USE_PLATFORM_XLIB_KHR) -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ const char *init_xlib_connection(); - void create_xlib_window(); - void handle_xlib_event(const XEvent *event); - void run_xlib(); --#elif defined(VK_USE_PLATFORM_XCB_KHR) -+#endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ const char *init_xcb_connection(); - void handle_xcb_event(const xcb_generic_event_t *event); - void run_xcb(); - void create_xcb_window(); --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -- void run(); -- void create_window(); --#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ const char *init_wayland_connection(); -+ void run_wayland(); -+ void create_wayland_window(); -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - void handle_directfb_event(const DFBInputEvent *event); - void run_directfb(); - void create_directfb_window(); --#elif defined(VK_USE_PLATFORM_METAL_EXT) -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) - void run(); --#elif defined(VK_USE_PLATFORM_DISPLAY_KHR) -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - vk::Result create_display_surface(); - void run_display(); --#elif defined(VK_USE_PLATFORM_SCREEN_QNX) -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) - void run(); - void create_window(); - #endif -@@ -290,20 +393,26 @@ struct Demo { - HINSTANCE connection = nullptr; // hInstance - Windows Instance - HWND window = nullptr; // hWnd - window handle - POINT minsize = {0, 0}; // minimum window size --#elif defined(VK_USE_PLATFORM_XLIB_KHR) -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ void *xlib_library; - Window xlib_window = 0; - Atom xlib_wm_delete_window = 0; -- Display *display = nullptr; --#elif defined(VK_USE_PLATFORM_XCB_KHR) -+ Display *xlib_display = nullptr; -+#endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ void *xcb_library; - xcb_window_t xcb_window = 0; - xcb_screen_t *screen = nullptr; - xcb_connection_t *connection = nullptr; - xcb_intern_atom_reply_t *atom_wm_delete_window = nullptr; --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -- wl_display *display = nullptr; -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ void *wayland_library = nullptr; -+ wl_display *wayland_display = nullptr; - wl_registry *registry = nullptr; - wl_compositor *compositor = nullptr; -- wl_surface *window = nullptr; -+ wl_surface *wayland_window = nullptr; - xdg_wm_base *wm_base = nullptr; - zxdg_decoration_manager_v1 *xdg_decoration_mgr = nullptr; - zxdg_toplevel_decoration_v1 *toplevel_decoration = nullptr; -@@ -313,18 +422,21 @@ struct Demo { - wl_seat *seat = nullptr; - wl_pointer *pointer = nullptr; - wl_keyboard *keyboard = nullptr; --#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - IDirectFB *dfb = nullptr; -- IDirectFBSurface *window = nullptr; -+ IDirectFBSurface *directfb_window = nullptr; - IDirectFBEventBuffer *event_buffer = nullptr; --#elif defined(VK_USE_PLATFORM_METAL_EXT) -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) - void *caMetalLayer; --#elif defined(VK_USE_PLATFORM_SCREEN_QNX) -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) - screen_context_t screen_context = nullptr; - screen_window_t screen_window = nullptr; - screen_event_t screen_event = nullptr; - #endif -- -+ WsiPlatform wsi_platform = WsiPlatform::auto_; - vk::SurfaceKHR surface; - bool prepared = false; - bool use_staging_buffer = false; -@@ -596,32 +708,44 @@ void Demo::cleanup() { - inst.destroySurfaceKHR(surface); - - #if defined(VK_USE_PLATFORM_XLIB_KHR) -- XDestroyWindow(display, xlib_window); -- XCloseDisplay(display); --#elif defined(VK_USE_PLATFORM_XCB_KHR) -- xcb_destroy_window(connection, xcb_window); -- xcb_disconnect(connection); -- free(atom_wm_delete_window); --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -- if (keyboard) wl_keyboard_destroy(keyboard); -- if (pointer) wl_pointer_destroy(pointer); -- if (seat) wl_seat_destroy(seat); -- xdg_toplevel_destroy(window_toplevel); -- xdg_surface_destroy(window_surface); -- wl_surface_destroy(window); -- xdg_wm_base_destroy(wm_base); -- if (xdg_decoration_mgr) { -- zxdg_toplevel_decoration_v1_destroy(toplevel_decoration); -- zxdg_decoration_manager_v1_destroy(xdg_decoration_mgr); -- } -- wl_compositor_destroy(compositor); -- wl_registry_destroy(registry); -- wl_display_disconnect(display); --#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) -- event_buffer->Release(event_buffer); -- window->Release(window); -- dfb->Release(dfb); --#elif defined(VK_USE_PLATFORM_SCREEN_QNX) -+ if (wsi_platform == WsiPlatform::xlib) { -+ XDestroyWindow(xlib_display, xlib_window); -+ XCloseDisplay(xlib_display); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ if (wsi_platform == WsiPlatform::xcb) { -+ xcb_destroy_window(connection, xcb_window); -+ xcb_disconnect(connection); -+ free(atom_wm_delete_window); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ if (wsi_platform == WsiPlatform::wayland) { -+ if (keyboard) wl_keyboard_destroy(keyboard); -+ if (pointer) wl_pointer_destroy(pointer); -+ if (seat) wl_seat_destroy(seat); -+ xdg_toplevel_destroy(window_toplevel); -+ xdg_surface_destroy(window_surface); -+ wl_surface_destroy(wayland_window); -+ xdg_wm_base_destroy(wm_base); -+ if (xdg_decoration_mgr) { -+ zxdg_toplevel_decoration_v1_destroy(toplevel_decoration); -+ zxdg_decoration_manager_v1_destroy(xdg_decoration_mgr); -+ } -+ wl_compositor_destroy(compositor); -+ wl_registry_destroy(registry); -+ wl_display_disconnect(wayland_display); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ if (wsi_platform == WsiPlatform::directfb) { -+ event_buffer->Release(event_buffer); -+ directfb_window->Release(directfb_window); -+ dfb->Release(dfb); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) - screen_destroy_event(screen_event); - screen_destroy_window(screen_window); - screen_destroy_context(screen_context); -@@ -887,7 +1011,7 @@ void Demo::init(int argc, char **argv) { - continue; - } - if (strcmp(argv[i], "--xlib") == 0) { -- fprintf(stderr, "--xlib is deprecated and no longer does anything"); -+ fprintf(stderr, "--xlib is deprecated and no longer does anything\n"); - continue; - } - if (strcmp(argv[i], "--c") == 0 && frameCount == UINT32_MAX && i < argc - 1 && -@@ -935,6 +1059,61 @@ void Demo::init(int argc, char **argv) { - force_errors = true; - continue; - } -+ if ((strcmp(argv[i], "--wsi") == 0) && (i < argc - 1)) { -+ std::string selection_input = argv[i + 1]; -+ for (char &c : selection_input) { -+ c = std::tolower(c); -+ } -+ WsiPlatform selection = wsi_from_string(selection_input); -+ if (selection == WsiPlatform::invalid) { -+ printf( -+ "The --wsi parameter %s is not a supported WSI platform. The list of available platforms is available from " -+ "--help\n", -+ (const char *)&(argv[i + 1][0])); -+ fflush(stdout); -+ exit(1); -+ } -+ wsi_platform = selection; -+ i++; -+ continue; -+ } -+ -+ std::string wsi_platforms; -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ wsi_platforms.append("xcb"); -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ if (!wsi_platforms.empty()) wsi_platforms.append("|"); -+ wsi_platforms.append("xlib"); -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ if (!wsi_platforms.empty()) wsi_platforms.append("|"); -+ wsi_platforms.append("wayland"); -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ if (!wsi_platforms.empty()) wsi_platforms.append("|"); -+ wsi_platforms.append("directfb"); -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -+ if (!wsi_platforms.empty()) wsi_platforms.append("|"); -+ wsi_platforms.append("display"); -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) -+ if (!wsi_platforms.empty()) wsi_platforms.append("|"); -+ wsi_platforms.append("metal"); -+#endif -+#if defined(VK_USE_PLATFORM_WIN32_KHR) -+ if (!wsi_platforms.empty()) wsi_platforms.append("|"); -+ wsi_platforms.append("win32"); -+#endif -+#if defined(VK_USE_PLATFORM_ANDROID_KHR) -+ if (!wsi_platforms.empty()) wsi_platforms.append("|"); -+ wsi_platforms.append("android"); -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ if (!wsi_platforms.empty()) wsi_platforms.append("|"); -+ wsi_platforms.append("qnx"); -+#endif - std::stringstream usage; - usage << "Usage:\n " << APP_SHORT_NAME << "\t[--use_staging] [--validate]\n" - << "\t[--break] [--c ] [--suppress_popups]\n" -@@ -942,6 +1121,7 @@ void Demo::init(int argc, char **argv) { - << "\t[--present_mode ]\n" - << "\t[--width ] [--height ]\n" - << "\t[--force_errors]\n" -+ << "\t[--wsi <" << wsi_platforms << ">]\n" - << "\t\n" - << "\t\tVK_PRESENT_MODE_IMMEDIATE_KHR = " << VK_PRESENT_MODE_IMMEDIATE_KHR << "\n" - << "\t\tVK_PRESENT_MODE_MAILBOX_KHR = " << VK_PRESENT_MODE_MAILBOX_KHR << "\n" -@@ -957,8 +1137,6 @@ void Demo::init(int argc, char **argv) { - exit(1); - } - -- init_connection(); -- - init_vk(); - - spin_angle = 4.0f; -@@ -972,24 +1150,24 @@ void Demo::init(int argc, char **argv) { - projection_matrix[1][1] *= -1; // Flip projection matrix from GL to Vulkan orientation. - } - --void Demo::init_connection() { - #if defined(VK_USE_PLATFORM_XCB_KHR) -+const char *Demo::init_xcb_connection() { -+ xcb_library = initialize_xcb(); -+ if (NULL == xcb_library) { -+ return "Cannot load XLIB dynamic library."; -+ } - const xcb_setup_t *setup; - xcb_screen_iterator_t iter; - int scr; - - const char *display_envar = getenv("DISPLAY"); - if (display_envar == nullptr || display_envar[0] == '\0') { -- printf("Environment variable DISPLAY requires a valid value.\nExiting ...\n"); -- fflush(stdout); -- exit(1); -+ return "Environment variable DISPLAY requires a valid value."; - } - - connection = xcb_connect(nullptr, &scr); - if (xcb_connection_has_error(connection) > 0) { -- printf("Cannot connect to XCB.\nExiting ...\n"); -- fflush(stdout); -- exit(1); -+ return "Cannot connect to XCB."; - } - - setup = xcb_get_setup(connection); -@@ -997,18 +1175,155 @@ void Demo::init_connection() { - while (scr-- > 0) xcb_screen_next(&iter); - - screen = iter.data; --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -- display = wl_display_connect(nullptr); -+ return NULL; -+} -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+const char *Demo::init_xlib_connection() { -+ xlib_library = initialize_xlib(); -+ if (NULL == xlib_library) { -+ return "Cannot load XLIB dynamic library."; -+ } -+ return NULL; -+} -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+const char *Demo::init_wayland_connection() { -+ wayland_library = initialize_wayland(); -+ if (NULL == wayland_library) { -+ return "Cannot load wayland dynamic library."; -+ } -+ wayland_display = wl_display_connect(nullptr); - -- if (display == nullptr) { -- printf("Cannot connect to wayland.\nExiting ...\n"); -- fflush(stdout); -- exit(1); -+ if (wayland_display == nullptr) { -+ return "Cannot connect to wayland."; - } - -- registry = wl_display_get_registry(display); -+ registry = wl_display_get_registry(wayland_display); - wl_registry_add_listener(registry, ®istry_listener, this); -- wl_display_dispatch(display); -+ wl_display_dispatch(wayland_display); -+ return NULL; -+} -+#endif -+ -+void Demo::check_and_set_wsi_platform() { -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ if (wsi_platform == WsiPlatform::xcb || wsi_platform == WsiPlatform::auto_) { -+ auto found = std::find_if(enabled_instance_extensions.begin(), enabled_instance_extensions.end(), -+ [](const char *str) { return 0 == strcmp(str, VK_KHR_XCB_SURFACE_EXTENSION_NAME); }); -+ if (found != enabled_instance_extensions.end()) { -+ const char *error_msg = init_xcb_connection(); -+ if (error_msg != NULL) { -+ if (wsi_platform == WsiPlatform::xcb) { -+ fprintf(stderr, "%s\nExiting ...\n", error_msg); -+ fflush(stdout); -+ exit(1); -+ } -+ } else { -+ wsi_platform = WsiPlatform::xcb; -+ return; -+ } -+ } -+ } -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ if (wsi_platform == WsiPlatform::xlib || wsi_platform == WsiPlatform::auto_) { -+ auto found = std::find_if(enabled_instance_extensions.begin(), enabled_instance_extensions.end(), -+ [](const char *str) { return 0 == strcmp(str, VK_KHR_XLIB_SURFACE_EXTENSION_NAME); }); -+ if (found != enabled_instance_extensions.end()) { -+ const char *error_msg = init_xlib_connection(); -+ if (error_msg != NULL) { -+ if (wsi_platform == WsiPlatform::xlib) { -+ fprintf(stderr, "%s\nExiting ...\n", error_msg); -+ fflush(stdout); -+ exit(1); -+ } -+ } else { -+ wsi_platform = WsiPlatform::xlib; -+ return; -+ } -+ } -+ } -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ if (wsi_platform == WsiPlatform::wayland || wsi_platform == WsiPlatform::auto_) { -+ auto found = std::find_if(enabled_instance_extensions.begin(), enabled_instance_extensions.end(), -+ [](const char *str) { return 0 == strcmp(str, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); }); -+ if (found != enabled_instance_extensions.end()) { -+ const char *error_msg = init_wayland_connection(); -+ if (error_msg != NULL) { -+ if (wsi_platform == WsiPlatform::wayland) { -+ fprintf(stderr, "%s\nExiting ...\n", error_msg); -+ fflush(stdout); -+ exit(1); -+ } -+ } else { -+ wsi_platform = WsiPlatform::wayland; -+ return; -+ } -+ } -+ } -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ if (wsi_platform == WsiPlatform::directfb || wsi_platform == WsiPlatform::auto_) { -+ auto found = std::find_if(enabled_instance_extensions.begin(), enabled_instance_extensions.end(), -+ [](const char *str) { return 0 == strcmp(str, VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME); }); -+ if (found != enabled_instance_extensions.end()) { -+ // Because DirectFB is still linked in, we can assume that it works if we got here -+ wsi_platform = WsiPlatform::directfb; -+ return; -+ } -+ } -+#endif -+#if defined(VK_USE_PLATFORM_WIN32_KHR) -+ if (wsi_platform == WsiPlatform::win32 || wsi_platform == WsiPlatform::auto_) { -+ auto found = std::find_if(enabled_instance_extensions.begin(), enabled_instance_extensions.end(), -+ [](const char *str) { return 0 == strcmp(str, VK_KHR_WIN32_SURFACE_EXTENSION_NAME); }); -+ if (found != enabled_instance_extensions.end()) { -+ wsi_platform = WsiPlatform::win32; -+ return; -+ } -+ } -+#endif -+#if defined(VK_USE_PLATFORM_ANDROID_KHR) -+ if (wsi_platform == WsiPlatform::android || wsi_platform == WsiPlatform::auto_) { -+ auto found = std::find_if(enabled_instance_extensions.begin(), enabled_instance_extensions.end(), -+ [](const char *str) { return 0 == strcmp(str, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); }); -+ if (found != enabled_instance_extensions.end()) { -+ wsi_platform = WsiPlatform::android; -+ return; -+ } -+ } -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) -+ if (wsi_platform == WsiPlatform::metal || wsi_platform == WsiPlatform::auto_) { -+ auto found = std::find_if(enabled_instance_extensions.begin(), enabled_instance_extensions.end(), -+ [](const char *str) { return 0 == strcmp(str, VK_EXT_METAL_SURFACE_EXTENSION_NAME); }); -+ if (found != enabled_instance_extensions.end()) { -+ wsi_platform = WsiPlatform::metal; -+ return; -+ } -+ } -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ if (wsi_platform == WsiPlatform::qnx || wsi_platform == WsiPlatform::auto_) { -+ auto found = std::find_if(enabled_instance_extensions.begin(), enabled_instance_extensions.end(), -+ [](const char *str) { return 0 == strcmp(str, VK_QNX_SCREEN_SURFACE_EXTENSION_NAME); }); -+ if (found != enabled_instance_extensions.end()) { -+ wsi_platform = WsiPlatform::qnx; -+ return; -+ } -+ } -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -+ if (wsi_platform == WsiPlatform::display || wsi_platform == WsiPlatform::auto_) { -+ auto found = std::find_if(enabled_instance_extensions.begin(), enabled_instance_extensions.end(), -+ [](const char *str) { return 0 == strcmp(str, VK_KHR_DISPLAY_EXTENSION_NAME); }); -+ if (found != enabled_instance_extensions.end()) { -+ wsi_platform = WsiPlatform::display; -+ return; -+ } -+ } - #endif - } - #if defined(VK_USE_PLATFORM_DISPLAY_KHR) -@@ -1018,13 +1333,13 @@ int find_display_gpu(int gpu_number, const std::vector &phys - if (gpu_number >= 0) { - auto display_props_return = physical_devices[gpu_number].getDisplayPropertiesKHR(); - VERIFY(display_props_return.result == vk::Result::eSuccess); -- display_count = display_props_return.value.size(); -+ display_count = static_cast(display_props_return.value.size()); - } else { - for (uint32_t i = 0; i < physical_devices.size(); i++) { - auto display_props_return = physical_devices[i].getDisplayPropertiesKHR(); - VERIFY(display_props_return.result == vk::Result::eSuccess); - if (display_props_return.value.size() > 0) { -- display_count = display_props_return.value.size(); -+ display_count = static_cast(display_props_return.value.size()); - gpu_return = i; - break; - } -@@ -1181,42 +1496,57 @@ void Demo::init_vk() { - enabled_instance_extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); - } - #if defined(VK_USE_PLATFORM_WIN32_KHR) -- else if (!strcmp(VK_KHR_WIN32_SURFACE_EXTENSION_NAME, extension.extensionName)) { -+ else if (!strcmp(VK_KHR_WIN32_SURFACE_EXTENSION_NAME, extension.extensionName) && -+ (wsi_platform == WsiPlatform::auto_ || wsi_platform == WsiPlatform::win32)) { - platformSurfaceExtFound = 1; - enabled_instance_extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); - } --#elif defined(VK_USE_PLATFORM_XLIB_KHR) -- else if (!strcmp(VK_KHR_XLIB_SURFACE_EXTENSION_NAME, extension.extensionName)) { -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ else if (!strcmp(VK_KHR_XLIB_SURFACE_EXTENSION_NAME, extension.extensionName) && -+ (wsi_platform == WsiPlatform::auto_ || wsi_platform == WsiPlatform::xlib)) { - platformSurfaceExtFound = 1; - enabled_instance_extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - } --#elif defined(VK_USE_PLATFORM_XCB_KHR) -- else if (!strcmp(VK_KHR_XCB_SURFACE_EXTENSION_NAME, extension.extensionName)) { -+#endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ else if (!strcmp(VK_KHR_XCB_SURFACE_EXTENSION_NAME, extension.extensionName) && -+ (wsi_platform == WsiPlatform::auto_ || wsi_platform == WsiPlatform::xcb)) { - platformSurfaceExtFound = 1; - enabled_instance_extensions.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); - } --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -- else if (!strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, extension.extensionName)) { -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ else if (!strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, extension.extensionName) && -+ (wsi_platform == WsiPlatform::auto_ || wsi_platform == WsiPlatform::wayland)) { - platformSurfaceExtFound = 1; - enabled_instance_extensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); - } --#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) -- else if (!strcmp(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME, extension.extensionName)) { -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ else if (!strcmp(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME, extension.extensionName) && -+ (wsi_platform == WsiPlatform::auto_ || wsi_platform == WsiPlatform::directfb)) { - platformSurfaceExtFound = 1; - enabled_instance_extensions.push_back(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME); - } --#elif defined(VK_USE_PLATFORM_DISPLAY_KHR) -- else if (!strcmp(VK_KHR_DISPLAY_EXTENSION_NAME, extension.extensionName)) { -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -+ else if (!strcmp(VK_KHR_DISPLAY_EXTENSION_NAME, extension.extensionName) && -+ (wsi_platform == WsiPlatform::auto_ || wsi_platform == WsiPlatform::display)) { - platformSurfaceExtFound = 1; - enabled_instance_extensions.push_back(VK_KHR_DISPLAY_EXTENSION_NAME); - } --#elif defined(VK_USE_PLATFORM_METAL_EXT) -- else if (!strcmp(VK_EXT_METAL_SURFACE_EXTENSION_NAME, extension.extensionName)) { -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) -+ else if (!strcmp(VK_EXT_METAL_SURFACE_EXTENSION_NAME, extension.extensionName) && -+ (wsi_platform == WsiPlatform::auto_ || wsi_platform == WsiPlatform::metal)) { - platformSurfaceExtFound = 1; - enabled_instance_extensions.push_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME); - } --#elif defined(VK_USE_PLATFORM_SCREEN_QNX) -- else if (!strcmp(VK_QNX_SCREEN_SURFACE_EXTENSION_NAME, extension.extensionName)) { -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ else if (!strcmp(VK_QNX_SCREEN_SURFACE_EXTENSION_NAME, extension.extensionName) && -+ (wsi_platform == WsiPlatform::auto_ || wsi_platform == WsiPlatform::qnx)) { - platformSurfaceExtFound = 1; - enabled_instance_extensions.push_back(VK_QNX_SCREEN_SURFACE_EXTENSION_NAME); - } -@@ -1233,56 +1563,93 @@ void Demo::init_vk() { - - if (!platformSurfaceExtFound) { - #if defined(VK_USE_PLATFORM_WIN32_KHR) -- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_WIN32_SURFACE_EXTENSION_NAME -- " extension.\n\n" -- "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -- "Please look at the Getting Started guide for additional information.\n", -- "vkCreateInstance Failure"); --#elif defined(VK_USE_PLATFORM_XCB_KHR) -- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_XCB_SURFACE_EXTENSION_NAME -- " extension.\n\n" -- "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -- "Please look at the Getting Started guide for additional information.\n", -- "vkCreateInstance Failure"); --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME -- " extension.\n\n" -- "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -- "Please look at the Getting Started guide for additional information.\n", -- "vkCreateInstance Failure"); --#elif defined(VK_USE_PLATFORM_XLIB_KHR) -- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_XLIB_SURFACE_EXTENSION_NAME -- " extension.\n\n" -- "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -- "Please look at the Getting Started guide for additional information.\n", -- "vkCreateInstance Failure"); --#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) -- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME -- " extension.\n\n" -- "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -- "Please look at the Getting Started guide for additional information.\n", -- "vkCreateInstance Failure"); --#elif defined(VK_USE_PLATFORM_DISPLAY_KHR) -- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_DISPLAY_EXTENSION_NAME -- " extension.\n\n" -- "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -- "Please look at the Getting Started guide for additional information.\n", -- "vkCreateInstance Failure"); --#elif defined(VK_USE_PLATFORM_METAL_EXT) -- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_EXT_METAL_SURFACE_EXTENSION_NAME -- " extension.\n\nDo you have a compatible " -- "Vulkan installable client driver (ICD) installed?\nPlease " -- "look at the Getting Started guide for additional " -- "information.\n", -- "vkCreateInstance Failure"); --#elif defined(VK_USE_PLATFORM_SCREEN_QNX) -- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_QNX_SCREEN_SURFACE_EXTENSION_NAME -- " extension.\n\nDo you have a compatible " -- "Vulkan installable client driver (ICD) installed?\nPlease " -- "look at the Getting Started guide for additional " -- "information.\n", -- "vkCreateInstance Failure"); -+ if (wsi_platform == WsiPlatform::win32) { -+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_WIN32_SURFACE_EXTENSION_NAME -+ " extension.\n\n" -+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -+ "Please look at the Getting Started guide for additional information.\n", -+ "vkCreateInstance Failure"); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ if (wsi_platform == WsiPlatform::xcb) { -+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_XCB_SURFACE_EXTENSION_NAME -+ " extension.\n\n" -+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -+ "Please look at the Getting Started guide for additional information.\n", -+ "vkCreateInstance Failure"); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ if (wsi_platform == WsiPlatform::wayland) { -+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME -+ " extension.\n\n" -+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -+ "Please look at the Getting Started guide for additional information.\n", -+ "vkCreateInstance Failure"); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ if (wsi_platform == WsiPlatform::xlib) { -+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_XLIB_SURFACE_EXTENSION_NAME -+ " extension.\n\n" -+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -+ "Please look at the Getting Started guide for additional information.\n", -+ "vkCreateInstance Failure"); -+ } - #endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ if (wsi_platform == WsiPlatform::directfb) { -+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME -+ " extension.\n\n" -+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -+ "Please look at the Getting Started guide for additional information.\n", -+ "vkCreateInstance Failure"); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -+ if (wsi_platform == WsiPlatform::display) { -+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_DISPLAY_EXTENSION_NAME -+ " extension.\n\n" -+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -+ "Please look at the Getting Started guide for additional information.\n", -+ "vkCreateInstance Failure"); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) -+ if (wsi_platform == WsiPlatform::metal) { -+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_EXT_METAL_SURFACE_EXTENSION_NAME -+ " extension.\n\nDo you have a compatible " -+ "Vulkan installable client driver (ICD) installed?\nPlease " -+ "look at the Getting Started guide for additional " -+ "information.\n", -+ "vkCreateInstance Failure"); -+ } -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ if (wsi_platform == WsiPlatform::qnx) { -+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_QNX_SCREEN_SURFACE_EXTENSION_NAME -+ " extension.\n\nDo you have a compatible " -+ "Vulkan installable client driver (ICD) installed?\nPlease " -+ "look at the Getting Started guide for additional " -+ "information.\n", -+ "vkCreateInstance Failure"); -+ } -+#endif -+ ERR_EXIT( -+ "vkEnumerateInstanceExtensionProperties failed to find any supported WSI surface extension.\n\n" -+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n" -+ "Please look at the Getting Started guide for additional information.\n", -+ "vkCreateInstance Failure"); -+ } -+ -+ bool auto_wsi_platform = wsi_platform == WsiPlatform::auto_; -+ -+ check_and_set_wsi_platform(); -+ -+ // Print a message to indicate the automatically set WSI platform -+ if (auto_wsi_platform && wsi_platform != WsiPlatform::auto_) { -+ fprintf(stderr, "Selected WSI platform: %s\n", wsi_to_string(wsi_platform)); - } - - vk::DebugUtilsMessageSeverityFlagsEXT severityFlags(vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | -@@ -1350,46 +1717,53 @@ void Demo::init_vk() { - fprintf(stderr, "GPU %d specified is not present, GPU count = %zu\n", gpu_number, physical_devices.size()); - ERR_EXIT("Specified GPU number is not present", "User Error"); - } -+ -+ if (wsi_platform == WsiPlatform::display) { - #if defined(VK_USE_PLATFORM_DISPLAY_KHR) -- gpu_number = find_display_gpu(gpu_number, physical_devices); -- if (gpu_number < 0) { -- printf("Cannot find any display!\n"); -+ gpu_number = find_display_gpu(gpu_number, physical_devices); -+ if (gpu_number < 0) { -+ printf("Cannot find any display!\n"); -+ fflush(stdout); -+ exit(1); -+ } -+#else -+ printf("WSI selection was set to DISPLAY but vkcubepp was not compiled with support for the DISPLAY platform, exiting \n"); - fflush(stdout); - exit(1); -- } --#else -- /* Try to auto select most suitable device */ -- if (gpu_number == -1) { -- constexpr uint32_t device_type_count = static_cast(vk::PhysicalDeviceType::eCpu) + 1; -- std::array count_device_type{}; -- -- for (uint32_t i = 0; i < physical_devices.size(); i++) { -- const auto physicalDeviceProperties = physical_devices[i].getProperties(); -- assert(physicalDeviceProperties.deviceType <= vk::PhysicalDeviceType::eCpu); -- count_device_type[static_cast(physicalDeviceProperties.deviceType)]++; -- } -+#endif -+ } else { -+ /* Try to auto select most suitable device */ -+ if (gpu_number == -1) { -+ constexpr uint32_t device_type_count = static_cast(vk::PhysicalDeviceType::eCpu) + 1; -+ std::array count_device_type{}; -+ -+ for (uint32_t i = 0; i < physical_devices.size(); i++) { -+ const auto physicalDeviceProperties = physical_devices[i].getProperties(); -+ assert(physicalDeviceProperties.deviceType <= vk::PhysicalDeviceType::eCpu); -+ count_device_type[static_cast(physicalDeviceProperties.deviceType)]++; -+ } - -- std::array const device_type_preference = { -- vk::PhysicalDeviceType::eDiscreteGpu, vk::PhysicalDeviceType::eIntegratedGpu, vk::PhysicalDeviceType::eVirtualGpu, -- vk::PhysicalDeviceType::eCpu, vk::PhysicalDeviceType::eOther}; -+ std::array const device_type_preference = { -+ vk::PhysicalDeviceType::eDiscreteGpu, vk::PhysicalDeviceType::eIntegratedGpu, vk::PhysicalDeviceType::eVirtualGpu, -+ vk::PhysicalDeviceType::eCpu, vk::PhysicalDeviceType::eOther}; - -- vk::PhysicalDeviceType search_for_device_type = vk::PhysicalDeviceType::eDiscreteGpu; -- for (uint32_t i = 0; i < sizeof(device_type_preference) / sizeof(vk::PhysicalDeviceType); i++) { -- if (count_device_type[static_cast(device_type_preference[i])]) { -- search_for_device_type = device_type_preference[i]; -- break; -+ vk::PhysicalDeviceType search_for_device_type = vk::PhysicalDeviceType::eDiscreteGpu; -+ for (uint32_t i = 0; i < sizeof(device_type_preference) / sizeof(vk::PhysicalDeviceType); i++) { -+ if (count_device_type[static_cast(device_type_preference[i])]) { -+ search_for_device_type = device_type_preference[i]; -+ break; -+ } - } -- } - -- for (uint32_t i = 0; i < physical_devices.size(); i++) { -- const auto physicalDeviceProperties = physical_devices[i].getProperties(); -- if (physicalDeviceProperties.deviceType == search_for_device_type) { -- gpu_number = i; -- break; -+ for (uint32_t i = 0; i < physical_devices.size(); i++) { -+ const auto physicalDeviceProperties = physical_devices[i].getProperties(); -+ if (physicalDeviceProperties.deviceType == search_for_device_type) { -+ gpu_number = i; -+ break; -+ } - } - } - } --#endif - assert(gpu_number >= 0); - gpu = physical_devices[gpu_number]; - { -@@ -1437,54 +1811,63 @@ void Demo::init_vk() { - void Demo::create_surface() { - // Create a WSI surface for the window: - #if defined(VK_USE_PLATFORM_WIN32_KHR) -- { -+ if (wsi_platform == WsiPlatform::win32) { - auto const createInfo = vk::Win32SurfaceCreateInfoKHR().setHinstance(connection).setHwnd(window); - - auto result = inst.createWin32SurfaceKHR(&createInfo, nullptr, &surface); - VERIFY(result == vk::Result::eSuccess); - } --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -- { -- auto const createInfo = vk::WaylandSurfaceCreateInfoKHR().setDisplay(display).setSurface(window); -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ -+ if (wsi_platform == WsiPlatform::wayland) { -+ auto const createInfo = vk::WaylandSurfaceCreateInfoKHR().setDisplay(wayland_display).setSurface(wayland_window); - - auto result = inst.createWaylandSurfaceKHR(&createInfo, nullptr, &surface); - VERIFY(result == vk::Result::eSuccess); -+ return; - } --#elif defined(VK_USE_PLATFORM_XLIB_KHR) -- { -- auto const createInfo = vk::XlibSurfaceCreateInfoKHR().setDpy(display).setWindow(xlib_window); -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ if (wsi_platform == WsiPlatform::xlib) { -+ auto const createInfo = vk::XlibSurfaceCreateInfoKHR().setDpy(xlib_display).setWindow(xlib_window); - - auto result = inst.createXlibSurfaceKHR(&createInfo, nullptr, &surface); - VERIFY(result == vk::Result::eSuccess); - } --#elif defined(VK_USE_PLATFORM_XCB_KHR) -- { -+#endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) -+ if (wsi_platform == WsiPlatform::xcb) { - auto const createInfo = vk::XcbSurfaceCreateInfoKHR().setConnection(connection).setWindow(xcb_window); - - auto result = inst.createXcbSurfaceKHR(&createInfo, nullptr, &surface); - VERIFY(result == vk::Result::eSuccess); - } --#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) -- { -- auto const createInfo = vk::DirectFBSurfaceCreateInfoEXT().setDfb(dfb).setSurface(window); -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ if (wsi_platform == WsiPlatform::directfb) { -+ auto const createInfo = vk::DirectFBSurfaceCreateInfoEXT().setDfb(dfb).setSurface(directfb_window); - - auto result = inst.createDirectFBSurfaceEXT(&createInfo, nullptr, &surface); - VERIFY(result == vk::Result::eSuccess); - } --#elif defined(VK_USE_PLATFORM_METAL_EXT) -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) - { - auto const createInfo = vk::MetalSurfaceCreateInfoEXT().setPLayer(static_cast(caMetalLayer)); - - auto result = inst.createMetalSurfaceEXT(&createInfo, nullptr, &surface); - VERIFY(result == vk::Result::eSuccess); - } --#elif defined(VK_USE_PLATFORM_DISPLAY_KHR) -- { -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -+ if (wsi_platform == WsiPlatform::display) { - auto result = create_display_surface(); - VERIFY(result == vk::Result::eSuccess); - } --#elif defined(VK_USE_PLATFORM_SCREEN_QNX) -- { -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ if (wsi_platform == WsiPlatform::qnx) { - auto const createInfo = vk::ScreenSurfaceCreateInfoQNX().setContext(screen_context).setWindow(screen_window); - - auto result = inst.createScreenSurfaceQNX(&createInfo, nullptr, &surface); -@@ -2607,7 +2990,8 @@ void Demo::create_window() { - minsize.x = GetSystemMetrics(SM_CXMINTRACK); - minsize.y = GetSystemMetrics(SM_CYMINTRACK) + 1; - } --#elif defined(VK_USE_PLATFORM_XLIB_KHR) -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) - - void Demo::create_xlib_window() { - const char *display_envar = getenv("DISPLAY"); -@@ -2618,14 +3002,15 @@ void Demo::create_xlib_window() { - } - - XInitThreads(); -- display = XOpenDisplay(nullptr); -+ xlib_display = XOpenDisplay(nullptr); - long visualMask = VisualScreenMask; - int numberOfVisuals; - XVisualInfo vInfoTemplate = {}; -- vInfoTemplate.screen = DefaultScreen(display); -- XVisualInfo *visualInfo = XGetVisualInfo(display, visualMask, &vInfoTemplate, &numberOfVisuals); -+ vInfoTemplate.screen = DefaultScreen(xlib_display); -+ XVisualInfo *visualInfo = XGetVisualInfo(xlib_display, visualMask, &vInfoTemplate, &numberOfVisuals); - -- Colormap colormap = XCreateColormap(display, RootWindow(display, vInfoTemplate.screen), visualInfo->visual, AllocNone); -+ Colormap colormap = -+ XCreateColormap(xlib_display, RootWindow(xlib_display, vInfoTemplate.screen), visualInfo->visual, AllocNone); - - XSetWindowAttributes windowAttributes = {}; - windowAttributes.colormap = colormap; -@@ -2634,13 +3019,13 @@ void Demo::create_xlib_window() { - windowAttributes.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask | ExposureMask; - - xlib_window = -- XCreateWindow(display, RootWindow(display, vInfoTemplate.screen), 0, 0, width, height, 0, visualInfo->depth, InputOutput, -- visualInfo->visual, CWBackPixel | CWBorderPixel | CWEventMask | CWColormap, &windowAttributes); -+ XCreateWindow(xlib_display, RootWindow(xlib_display, vInfoTemplate.screen), 0, 0, width, height, 0, visualInfo->depth, -+ InputOutput, visualInfo->visual, CWBackPixel | CWBorderPixel | CWEventMask | CWColormap, &windowAttributes); - -- XSelectInput(display, xlib_window, ExposureMask | KeyPressMask); -- XMapWindow(display, xlib_window); -- XFlush(display); -- xlib_wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False); -+ XSelectInput(xlib_display, xlib_window, ExposureMask | KeyPressMask); -+ XMapWindow(xlib_display, xlib_window); -+ XFlush(xlib_display); -+ xlib_wm_delete_window = XInternAtom(xlib_display, "WM_DELETE_WINDOW", False); - } - - void Demo::handle_xlib_event(const XEvent *event) { -@@ -2683,11 +3068,11 @@ void Demo::run_xlib() { - XEvent event; - - if (pause) { -- XNextEvent(display, &event); -+ XNextEvent(xlib_display, &event); - handle_xlib_event(&event); - } -- while (XPending(display) > 0) { -- XNextEvent(display, &event); -+ while (XPending(xlib_display) > 0) { -+ XNextEvent(xlib_display, &event); - handle_xlib_event(&event); - } - -@@ -2699,7 +3084,8 @@ void Demo::run_xlib() { - } - } - } --#elif defined(VK_USE_PLATFORM_XCB_KHR) -+#endif -+#if defined(VK_USE_PLATFORM_XCB_KHR) - - void Demo::handle_xcb_event(const xcb_generic_event_t *event) { - uint8_t event_code = event->response_type & 0x7f; -@@ -2799,14 +3185,15 @@ void Demo::create_xcb_window() { - std::array const coords = {100, 100}; - xcb_configure_window(connection, xcb_window, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, coords.data()); - } --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) - --void Demo::run() { -+void Demo::run_wayland() { - while (!quit) { - if (pause) { -- wl_display_dispatch(display); -+ wl_display_dispatch(wayland_display); - } else { -- wl_display_dispatch_pending(display); -+ wl_display_dispatch_pending(wayland_display); - draw(); - curFrame++; - if (frameCount != UINT32_MAX && curFrame == frameCount) { -@@ -2848,21 +3235,21 @@ static void handle_toplevel_close(void *data, xdg_toplevel *xdg_toplevel) { - - static const xdg_toplevel_listener toplevel_listener = {handle_toplevel_configure, handle_toplevel_close}; - --void Demo::create_window() { -+void Demo::create_wayland_window() { - if (!wm_base) { - printf("Compositor did not provide the standard protocol xdg-wm-base\n"); - fflush(stdout); - exit(1); - } - -- window = wl_compositor_create_surface(compositor); -- if (!window) { -+ wayland_window = wl_compositor_create_surface(compositor); -+ if (!wayland_window) { - printf("Can not create wayland_surface from compositor!\n"); - fflush(stdout); - exit(1); - } - -- window_surface = xdg_wm_base_get_xdg_surface(wm_base, window); -+ window_surface = xdg_wm_base_get_xdg_surface(wm_base, wayland_window); - if (!window_surface) { - printf("Can not get xdg_surface from wayland_surface!\n"); - fflush(stdout); -@@ -2883,9 +3270,10 @@ void Demo::create_window() { - zxdg_toplevel_decoration_v1_set_mode(toplevel_decoration, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); - } - -- wl_surface_commit(window); -+ wl_surface_commit(wayland_window); - } --#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) - - void Demo::handle_directfb_event(const DFBInputEvent *event) { - if (event->type != DIET_KEYPRESS) return; -@@ -2948,7 +3336,7 @@ void Demo::create_directfb_window() { - desc.caps = DSCAPS_PRIMARY; - desc.width = width; - desc.height = height; -- ret = dfb->CreateSurface(dfb, &desc, &window); -+ ret = dfb->CreateSurface(dfb, &desc, &directfb_window); - if (ret) { - printf("CreateSurface failed to create DirectFB surface interface!\n"); - fflush(stdout); -@@ -2962,7 +3350,8 @@ void Demo::create_directfb_window() { - exit(1); - } - } --#elif defined(VK_USE_PLATFORM_METAL_EXT) -+#endif -+#if defined(VK_USE_PLATFORM_METAL_EXT) - void Demo::run() { - draw(); - curFrame++; -@@ -2970,7 +3359,8 @@ void Demo::run() { - quit = true; - } - } --#elif defined(VK_USE_PLATFORM_DISPLAY_KHR) -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) - - vk::Result Demo::create_display_surface() { - auto display_properties_return = gpu.getDisplayPropertiesKHR(); -@@ -3078,7 +3468,8 @@ void Demo::run_display() { - } - } - --#elif defined(VK_USE_PLATFORM_SCREEN_QNX) -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) - #include - - void Demo::run() { -@@ -3394,35 +3785,89 @@ int main(int argc, char **argv) { - - demo.init(argc, argv); - -+ switch (demo.wsi_platform) { -+ default: -+ case (WsiPlatform::auto_): -+ fprintf(stderr, -+ "WSI platform should have already been set, indicating a bug. Please set a WSI platform manually with " -+ "--wsi\n"); -+ exit(1); -+ break; - #if defined(VK_USE_PLATFORM_XCB_KHR) -- demo.create_xcb_window(); --#elif defined(VK_USE_PLATFORM_XLIB_KHR) -- demo.create_xlib_window(); --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -- demo.create_window(); --#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) -- demo.create_directfb_window(); --#elif defined(VK_USE_PLATFORM_SCREEN_QNX) -- demo.create_window(); -+ case (WsiPlatform::xcb): -+ demo.create_xcb_window(); -+ break; -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ case (WsiPlatform::xlib): -+ demo.create_xlib_window(); -+ break; -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ case (WsiPlatform::wayland): -+ demo.create_wayland_window(); -+ break; -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ case (WsiPlatform::directfb): -+ demo.create_directfb_window(); -+ break; -+#endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ case (WsiPlatform::qnx): -+ demo.create_window(); -+ break; -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -+ case (WsiPlatform::display): -+ // nothing to do here -+ break; - #endif -+ } - - demo.init_vk_swapchain(); - - demo.prepare(); - -+ switch (demo.wsi_platform) { -+ default: -+ case (WsiPlatform::auto_): -+ fprintf(stderr, -+ "WSI platform should have already been set, indicating a bug. Please set a WSI platform manually with " -+ "--wsi\n"); -+ exit(1); -+ break; - #if defined(VK_USE_PLATFORM_XCB_KHR) -- demo.run_xcb(); --#elif defined(VK_USE_PLATFORM_XLIB_KHR) -- demo.run_xlib(); --#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) -- demo.run(); --#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT) -- demo.run_directfb(); --#elif defined(VK_USE_PLATFORM_DISPLAY_KHR) -- demo.run_display(); --#elif defined(VK_USE_PLATFORM_SCREEN_QNX) -- demo.run(); -+ case (WsiPlatform::xcb): -+ demo.run_xcb(); -+ break; -+#endif -+#if defined(VK_USE_PLATFORM_XLIB_KHR) -+ case (WsiPlatform::xlib): -+ demo.run_xlib(); -+ break; -+#endif -+#if defined(VK_USE_PLATFORM_WAYLAND_KHR) -+ case (WsiPlatform::wayland): -+ demo.run_wayland(); -+ break; -+#endif -+#if defined(VK_USE_PLATFORM_DIRECTFB_EXT) -+ case (WsiPlatform::directfb): -+ demo.run_directfb(); -+ break; -+#endif -+#if defined(VK_USE_PLATFORM_DISPLAY_KHR) -+ case (WsiPlatform::display): -+ demo.run_display(); -+ break; - #endif -+#if defined(VK_USE_PLATFORM_SCREEN_QNX) -+ case (WsiPlatform::qnx): -+ demo.run(); -+ break; -+#endif -+ } - - demo.cleanup(); - -diff --git a/cube/macOS/cube/CMakeLists.txt b/cube/macOS/cube/CMakeLists.txt -index 1fcc6c45..4d8a955e 100644 ---- a/cube/macOS/cube/CMakeLists.txt -+++ b/cube/macOS/cube/CMakeLists.txt -@@ -59,7 +59,7 @@ add_dependencies(vkcube MoltenVK_icd-staging-json) - target_include_directories(vkcube PRIVATE . ${MOLTENVK_DIR}/MoltenVK/include) - - # We do this so vkcube is linked to an individual library and NOT a framework. --target_link_libraries(vkcube Vulkan::Loader volk::volk_headers "-framework Cocoa -framework QuartzCore") -+target_link_libraries(vkcube "-framework Cocoa -framework QuartzCore") - - # Disable warnings about sprintf - target_compile_options(vkcube PRIVATE -Wno-deprecated-declarations) -diff --git a/cube/macOS/cubepp/CMakeLists.txt b/cube/macOS/cubepp/CMakeLists.txt -index 645d4da9..491031f1 100644 ---- a/cube/macOS/cubepp/CMakeLists.txt -+++ b/cube/macOS/cubepp/CMakeLists.txt -@@ -59,7 +59,7 @@ add_dependencies(vkcubepp MoltenVK_icd-staging-json) - target_include_directories(vkcubepp PRIVATE ${CMAKE_CURRENT_LIST_DIR} ${MOLTENVK_DIR}/MoltenVK/include) - - # We do this so vkcubepp is linked to an individual library and NOT a framework. --target_link_libraries(vkcubepp Vulkan::Loader volk::volk_headers "-framework Cocoa -framework QuartzCore") -+target_link_libraries(vkcubepp "-framework Cocoa -framework QuartzCore") - - set_target_properties(vkcubepp PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_LIST_DIR}/Info.plist) - -diff --git a/cube/wayland_loader.h b/cube/wayland_loader.h -new file mode 100644 -index 00000000..2afab6e9 ---- /dev/null -+++ b/cube/wayland_loader.h -@@ -0,0 +1,124 @@ -+/* -+ * Copyright (c) 2024 The Khronos Group Inc. -+ * Copyright (c) 2024 Valve Corporation -+ * Copyright (c) 2024 LunarG, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ * -+ * Author: Charles Giessen -+ */ -+ -+#pragma once -+ -+#include -+#include -+#include -+ -+#include -+ -+typedef struct wl_display *(*PFN_wl_display_connect)(const char *name); -+typedef int (*PFN_wl_display_flush)(struct wl_display *display); -+typedef int (*PFN_wl_display_dispatch)(struct wl_display *display); -+typedef int (*PFN_wl_display_prepare_read)(struct wl_display *display); -+typedef int (*PFN_wl_display_dispatch_pending)(struct wl_display *display); -+typedef int (*PFN_wl_display_read_events)(struct wl_display *display); -+typedef void (*PFN_wl_proxy_marshal)(struct wl_proxy *p, uint32_t opcode, ...); -+typedef struct wl_proxy *(*PFN_wl_proxy_marshal_constructor)(struct wl_proxy *proxy, uint32_t opcode, -+ const struct wl_interface *interface, ...); -+typedef struct wl_proxy *(*PFN_wl_proxy_marshal_constructor_versioned)(struct wl_proxy *proxy, uint32_t opcode, -+ const struct wl_interface *interface, uint32_t version, ...); -+typedef struct wl_proxy *(*PFN_wl_proxy_marshal_flags)(struct wl_proxy *proxy, uint32_t opcode, -+ const struct wl_interface *interface, uint32_t version, uint32_t flags, ...); -+typedef uint32_t (*PFN_wl_proxy_get_version)(struct wl_proxy *proxy); -+typedef int (*PFN_wl_proxy_add_listener)(struct wl_proxy *proxy, void (**implementation)(void), void *data); -+typedef void (*PFN_wl_proxy_destroy)(struct wl_proxy *proxy); -+typedef int (*PFN_wl_display_roundtrip)(struct wl_display *display); -+typedef void (*PFN_wl_display_disconnect)(struct wl_display *display); -+ -+static PFN_wl_display_connect cube_wl_display_connect = NULL; -+static PFN_wl_display_flush cube_wl_display_flush = NULL; -+static PFN_wl_display_dispatch cube_wl_display_dispatch = NULL; -+static PFN_wl_display_prepare_read cube_wl_display_prepare_read = NULL; -+static PFN_wl_display_dispatch_pending cube_wl_display_dispatch_pending = NULL; -+static PFN_wl_display_read_events cube_wl_display_read_events = NULL; -+static PFN_wl_proxy_marshal cube_wl_proxy_marshal = NULL; -+static PFN_wl_proxy_marshal_constructor cube_wl_proxy_marshal_constructor = NULL; -+static PFN_wl_proxy_marshal_constructor_versioned cube_wl_proxy_marshal_constructor_versioned = NULL; -+static PFN_wl_proxy_marshal_flags cube_wl_proxy_marshal_flags = NULL; -+static PFN_wl_proxy_get_version cube_wl_proxy_get_version = NULL; -+static PFN_wl_proxy_add_listener cube_wl_proxy_add_listener = NULL; -+static PFN_wl_proxy_destroy cube_wl_proxy_destroy = NULL; -+static PFN_wl_display_roundtrip cube_wl_display_roundtrip = NULL; -+static PFN_wl_display_disconnect cube_wl_display_disconnect = NULL; -+ -+// Use macro's to redefine the PFN's as the functions in client code -+#define wl_display_connect cube_wl_display_connect -+#define wl_display_flush cube_wl_display_flush -+#define wl_display_dispatch cube_wl_display_dispatch -+#define wl_display_prepare_read cube_wl_display_prepare_read -+#define wl_display_dispatch_pending cube_wl_display_dispatch_pending -+#define wl_display_read_events cube_wl_display_read_events -+#define wl_proxy_marshal cube_wl_proxy_marshal -+#define wl_proxy_marshal_constructor cube_wl_proxy_marshal_constructor -+#define wl_proxy_marshal_constructor_versioned cube_wl_proxy_marshal_constructor_versioned -+#define wl_proxy_marshal_flags cube_wl_proxy_marshal_flags -+#define wl_proxy_get_version cube_wl_proxy_get_version -+#define wl_proxy_add_listener cube_wl_proxy_add_listener -+#define wl_proxy_destroy cube_wl_proxy_destroy -+#define wl_display_roundtrip cube_wl_display_roundtrip -+#define wl_display_disconnect cube_wl_display_disconnect -+ -+static inline void *initialize_wayland() { -+ void *wayland_library = NULL; -+#if defined(WAYLAND_LIBRARY) -+ wayland_library = dlopen(WAYLAND_LIBRARY, RTLD_NOW | RTLD_LOCAL); -+#endif -+ if (NULL == wayland_library) { -+ wayland_library = dlopen("libwayland-client.so.0", RTLD_NOW | RTLD_LOCAL); -+ } -+ if (NULL == wayland_library) { -+ wayland_library = dlopen("libwayland-client.so", RTLD_NOW | RTLD_LOCAL); -+ } -+ if (NULL == wayland_library) { -+ return NULL; -+ } -+ -+#ifdef __cplusplus -+#define TYPE_CONVERSION(type) reinterpret_cast -+#else -+#define TYPE_CONVERSION(type) -+#endif -+ cube_wl_display_connect = TYPE_CONVERSION(PFN_wl_display_connect)(dlsym(wayland_library, "wl_display_connect")); -+ cube_wl_display_flush = TYPE_CONVERSION(PFN_wl_display_flush)(dlsym(wayland_library, "wl_display_flush")); -+ cube_wl_display_dispatch = TYPE_CONVERSION(PFN_wl_display_dispatch)(dlsym(wayland_library, "wl_display_dispatch")); -+ cube_wl_display_prepare_read = TYPE_CONVERSION(PFN_wl_display_prepare_read)(dlsym(wayland_library, "wl_display_prepare_read")); -+ cube_wl_display_dispatch_pending = -+ TYPE_CONVERSION(PFN_wl_display_dispatch_pending)(dlsym(wayland_library, "wl_display_dispatch_pending")); -+ cube_wl_display_read_events = TYPE_CONVERSION(PFN_wl_display_read_events)(dlsym(wayland_library, "wl_display_read_events")); -+ cube_wl_proxy_marshal = TYPE_CONVERSION(PFN_wl_proxy_marshal)(dlsym(wayland_library, "wl_proxy_marshal")); -+ cube_wl_proxy_marshal_constructor = -+ TYPE_CONVERSION(PFN_wl_proxy_marshal_constructor)(dlsym(wayland_library, "wl_proxy_marshal_constructor")); -+ cube_wl_proxy_marshal_constructor_versioned = TYPE_CONVERSION(PFN_wl_proxy_marshal_constructor_versioned)( -+ dlsym(wayland_library, "wl_proxy_marshal_constructor_versioned")); -+ cube_wl_proxy_marshal_flags = TYPE_CONVERSION(PFN_wl_proxy_marshal_flags)(dlsym(wayland_library, "wl_proxy_marshal_flags")); -+ cube_wl_proxy_get_version = TYPE_CONVERSION(PFN_wl_proxy_get_version)(dlsym(wayland_library, "wl_proxy_get_version")); -+ cube_wl_proxy_add_listener = TYPE_CONVERSION(PFN_wl_proxy_add_listener)(dlsym(wayland_library, "wl_proxy_add_listener")); -+ cube_wl_proxy_destroy = TYPE_CONVERSION(PFN_wl_proxy_destroy)(dlsym(wayland_library, "wl_proxy_destroy")); -+ cube_wl_display_roundtrip = TYPE_CONVERSION(PFN_wl_display_roundtrip)(dlsym(wayland_library, "wl_display_roundtrip")); -+ cube_wl_display_disconnect = TYPE_CONVERSION(PFN_wl_display_disconnect)(dlsym(wayland_library, "wl_display_disconnect")); -+ -+ return wayland_library; -+} -+ -+#include "xdg-shell-client-header.h" -+#include "xdg-decoration-client-header.h" -diff --git a/cube/xcb_loader.h b/cube/xcb_loader.h -new file mode 100644 -index 00000000..a94d5ab5 ---- /dev/null -+++ b/cube/xcb_loader.h -@@ -0,0 +1,129 @@ -+/* -+ * Copyright (c) 2024 The Khronos Group Inc. -+ * Copyright (c) 2024 Valve Corporation -+ * Copyright (c) 2024 LunarG, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ * -+ * Author: Charles Giessen -+ */ -+ -+#pragma once -+ -+#include -+#include -+ -+#include -+ -+typedef xcb_void_cookie_t (*PFN_xcb_destroy_window)(xcb_connection_t *c, xcb_window_t window); -+typedef void (*PFN_xcb_disconnect)(xcb_connection_t *c); -+typedef int (*PFN_xcb_flush)(xcb_connection_t *c); -+typedef xcb_generic_event_t *(*PFN_xcb_wait_for_event)(xcb_connection_t *c); -+typedef xcb_generic_event_t *(*PFN_xcb_poll_for_event)(xcb_connection_t *c); -+typedef uint32_t (*PFN_xcb_generate_id)(xcb_connection_t *c); -+typedef xcb_void_cookie_t (*PFN_xcb_create_window)(xcb_connection_t *c, uint8_t depth, xcb_window_t wid, xcb_window_t parent, -+ int16_t x, int16_t y, uint16_t width, uint16_t height, uint16_t border_width, -+ uint16_t _class, xcb_visualid_t visual, uint32_t value_mask, -+ const void *value_list); -+typedef xcb_intern_atom_cookie_t (*PFN_xcb_intern_atom)(xcb_connection_t *c, uint8_t only_if_exists, uint16_t name_len, -+ const char *name); -+typedef xcb_intern_atom_reply_t *(*PFN_xcb_intern_atom_reply)(xcb_connection_t *c, xcb_intern_atom_cookie_t cookie /**< */, -+ xcb_generic_error_t **e); -+typedef xcb_void_cookie_t (*PFN_xcb_change_property)(xcb_connection_t *c, uint8_t mode, xcb_window_t window, xcb_atom_t property, -+ xcb_atom_t type, uint8_t format, uint32_t data_len, const void *data); -+typedef xcb_void_cookie_t (*PFN_xcb_map_window)(xcb_connection_t *c, xcb_window_t window); -+typedef xcb_void_cookie_t (*PFN_xcb_configure_window)(xcb_connection_t *c, xcb_window_t window, uint16_t value_mask, -+ const void *value_list); -+typedef xcb_connection_t *(*PFN_xcb_connect)(const char *displayname, int *screenp); -+typedef int (*PFN_xcb_connection_has_error)(xcb_connection_t *c); -+typedef const struct xcb_setup_t *(*PFN_xcb_get_setup)(xcb_connection_t *c); -+typedef xcb_screen_iterator_t (*PFN_xcb_setup_roots_iterator)(const xcb_setup_t *R); -+typedef void (*PFN_xcb_screen_next)(xcb_screen_iterator_t *i); -+ -+static PFN_xcb_destroy_window cube_xcb_destroy_window = NULL; -+static PFN_xcb_disconnect cube_xcb_disconnect = NULL; -+static PFN_xcb_flush cube_xcb_flush = NULL; -+static PFN_xcb_wait_for_event cube_xcb_wait_for_event = NULL; -+static PFN_xcb_poll_for_event cube_xcb_poll_for_event = NULL; -+static PFN_xcb_generate_id cube_xcb_generate_id = NULL; -+static PFN_xcb_create_window cube_xcb_create_window = NULL; -+static PFN_xcb_intern_atom cube_xcb_intern_atom = NULL; -+static PFN_xcb_intern_atom_reply cube_xcb_intern_atom_reply = NULL; -+static PFN_xcb_change_property cube_xcb_change_property = NULL; -+static PFN_xcb_map_window cube_xcb_map_window = NULL; -+static PFN_xcb_configure_window cube_xcb_configure_window = NULL; -+static PFN_xcb_connect cube_xcb_connect = NULL; -+static PFN_xcb_connection_has_error cube_xcb_connection_has_error = NULL; -+static PFN_xcb_get_setup cube_xcb_get_setup = NULL; -+static PFN_xcb_setup_roots_iterator cube_xcb_setup_roots_iterator = NULL; -+static PFN_xcb_screen_next cube_xcb_screen_next = NULL; -+ -+#define xcb_destroy_window cube_xcb_destroy_window -+#define xcb_disconnect cube_xcb_disconnect -+#define xcb_flush cube_xcb_flush -+#define xcb_wait_for_event cube_xcb_wait_for_event -+#define xcb_poll_for_event cube_xcb_poll_for_event -+#define xcb_generate_id cube_xcb_generate_id -+#define xcb_create_window cube_xcb_create_window -+#define xcb_intern_atom cube_xcb_intern_atom -+#define xcb_intern_atom_reply cube_xcb_intern_atom_reply -+#define xcb_change_property cube_xcb_change_property -+#define xcb_map_window cube_xcb_map_window -+#define xcb_configure_window cube_xcb_configure_window -+#define xcb_connect cube_xcb_connect -+#define xcb_connection_has_error cube_xcb_connection_has_error -+#define xcb_get_setup cube_xcb_get_setup -+#define xcb_setup_roots_iterator cube_xcb_setup_roots_iterator -+#define xcb_screen_next cube_xcb_screen_next -+ -+void *initialize_xcb() { -+ void *xcb_library = NULL; -+#if defined(XCB_LIBRARY) -+ xcb_library = dlopen(XCB_LIBRARY, RTLD_NOW | RTLD_LOCAL); -+#endif -+ if (NULL == xcb_library) { -+ xcb_library = dlopen("libxcb.so.1", RTLD_NOW | RTLD_LOCAL); -+ } -+ if (NULL == xcb_library) { -+ xcb_library = dlopen("libxcb.so", RTLD_NOW | RTLD_LOCAL); -+ } -+ if (NULL == xcb_library) { -+ return NULL; -+ } -+ -+#ifdef __cplusplus -+#define TYPE_CONVERSION(type) reinterpret_cast -+#else -+#define TYPE_CONVERSION(type) -+#endif -+ -+ cube_xcb_destroy_window = TYPE_CONVERSION(PFN_xcb_destroy_window)(dlsym(xcb_library, "xcb_destroy_window")); -+ cube_xcb_disconnect = TYPE_CONVERSION(PFN_xcb_disconnect)(dlsym(xcb_library, "xcb_disconnect")); -+ cube_xcb_flush = TYPE_CONVERSION(PFN_xcb_flush)(dlsym(xcb_library, "xcb_flush")); -+ cube_xcb_wait_for_event = TYPE_CONVERSION(PFN_xcb_wait_for_event)(dlsym(xcb_library, "xcb_wait_for_event")); -+ cube_xcb_poll_for_event = TYPE_CONVERSION(PFN_xcb_poll_for_event)(dlsym(xcb_library, "xcb_poll_for_event")); -+ cube_xcb_generate_id = TYPE_CONVERSION(PFN_xcb_generate_id)(dlsym(xcb_library, "xcb_generate_id")); -+ cube_xcb_create_window = TYPE_CONVERSION(PFN_xcb_create_window)(dlsym(xcb_library, "xcb_create_window")); -+ cube_xcb_intern_atom = TYPE_CONVERSION(PFN_xcb_intern_atom)(dlsym(xcb_library, "xcb_intern_atom")); -+ cube_xcb_intern_atom_reply = TYPE_CONVERSION(PFN_xcb_intern_atom_reply)(dlsym(xcb_library, "xcb_intern_atom_reply")); -+ cube_xcb_change_property = TYPE_CONVERSION(PFN_xcb_change_property)(dlsym(xcb_library, "xcb_change_property")); -+ cube_xcb_map_window = TYPE_CONVERSION(PFN_xcb_map_window)(dlsym(xcb_library, "xcb_map_window")); -+ cube_xcb_configure_window = TYPE_CONVERSION(PFN_xcb_configure_window)(dlsym(xcb_library, "xcb_configure_window")); -+ cube_xcb_connect = TYPE_CONVERSION(PFN_xcb_connect)(dlsym(xcb_library, "xcb_connect")); -+ cube_xcb_connection_has_error = TYPE_CONVERSION(PFN_xcb_connection_has_error)(dlsym(xcb_library, "xcb_connection_has_error")); -+ cube_xcb_get_setup = TYPE_CONVERSION(PFN_xcb_get_setup)(dlsym(xcb_library, "xcb_get_setup")); -+ cube_xcb_setup_roots_iterator = TYPE_CONVERSION(PFN_xcb_setup_roots_iterator)(dlsym(xcb_library, "xcb_setup_roots_iterator")); -+ cube_xcb_screen_next = TYPE_CONVERSION(PFN_xcb_screen_next)(dlsym(xcb_library, "xcb_screen_next")); -+ -+ return xcb_library; -+} -diff --git a/cube/xlib_loader.h b/cube/xlib_loader.h -new file mode 100644 -index 00000000..c7874d0e ---- /dev/null -+++ b/cube/xlib_loader.h -@@ -0,0 +1,109 @@ -+/* -+ * Copyright (c) 2024 The Khronos Group Inc. -+ * Copyright (c) 2024 Valve Corporation -+ * Copyright (c) 2024 LunarG, Inc. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ * -+ * Author: Charles Giessen -+ */ -+ -+#pragma once -+ -+#include -+#include -+ -+#include -+ -+typedef int (*PFN_XDestroyWindow)(Display*, Window); -+typedef Display* (*PFN_XOpenDisplay)(_Xconst char*); -+typedef Colormap (*PFN_XCreateColormap)(Display*, Window, Visual*, int); -+typedef Window (*PFN_XCreateWindow)(Display*, Window, int, int, unsigned int, unsigned int, unsigned int, int, unsigned int, -+ Visual*, unsigned long, XSetWindowAttributes*); -+typedef int (*PFN_XSelectInput)(Display*, Window, long); -+typedef int (*PFN_XMapWindow)(Display*, Window); -+typedef Atom (*PFN_XInternAtom)(Display*, _Xconst char*, Bool); -+typedef int (*PFN_XNextEvent)(Display*, XEvent*); -+typedef int (*PFN_XPending)(Display*); -+typedef XVisualInfo* (*PFN_XGetVisualInfo)(Display*, long, XVisualInfo*, int*); -+typedef int (*PFN_XCloseDisplay)(Display* /* display */ -+); -+typedef Status (*PFN_XInitThreads)(void); -+typedef int (*PFN_XFlush)(Display* /* display */ -+); -+ -+static PFN_XDestroyWindow cube_XDestroyWindow = NULL; -+static PFN_XOpenDisplay cube_XOpenDisplay = NULL; -+static PFN_XCreateColormap cube_XCreateColormap = NULL; -+static PFN_XCreateWindow cube_XCreateWindow = NULL; -+static PFN_XSelectInput cube_XSelectInput = NULL; -+static PFN_XMapWindow cube_XMapWindow = NULL; -+static PFN_XInternAtom cube_XInternAtom = NULL; -+static PFN_XNextEvent cube_XNextEvent = NULL; -+static PFN_XPending cube_XPending = NULL; -+static PFN_XGetVisualInfo cube_XGetVisualInfo = NULL; -+static PFN_XCloseDisplay cube_XCloseDisplay = NULL; -+static PFN_XInitThreads cube_XInitThreads = NULL; -+static PFN_XFlush cube_XFlush = NULL; -+ -+#define XDestroyWindow cube_XDestroyWindow -+#define XOpenDisplay cube_XOpenDisplay -+#define XCreateColormap cube_XCreateColormap -+#define XCreateWindow cube_XCreateWindow -+#define XSelectInput cube_XSelectInput -+#define XMapWindow cube_XMapWindow -+#define XInternAtom cube_XInternAtom -+#define XNextEvent cube_XNextEvent -+#define XPending cube_XPending -+#define XGetVisualInfo cube_XGetVisualInfo -+#define XCloseDisplay cube_XCloseDisplay -+#define XInitThreads cube_XInitThreads -+#define XFlush cube_XFlush -+ -+void* initialize_xlib() { -+ void* xlib_library = NULL; -+#if defined(XLIB_LIBRARY) -+ xlib_library = dlopen(XLIB_LIBRARY, RTLD_NOW | RTLD_LOCAL); -+#endif -+ if (NULL == xlib_library) { -+ xlib_library = dlopen("libX11.so.6", RTLD_NOW | RTLD_LOCAL); -+ } -+ if (NULL == xlib_library) { -+ xlib_library = dlopen("libX11.so", RTLD_NOW | RTLD_LOCAL); -+ } -+ if (NULL == xlib_library) { -+ return NULL; -+ } -+ -+#ifdef __cplusplus -+#define TYPE_CONVERSION(type) reinterpret_cast -+#else -+#define TYPE_CONVERSION(type) -+#endif -+ -+ cube_XDestroyWindow = TYPE_CONVERSION(PFN_XDestroyWindow)(dlsym(xlib_library, "XDestroyWindow")); -+ cube_XOpenDisplay = TYPE_CONVERSION(PFN_XOpenDisplay)(dlsym(xlib_library, "XOpenDisplay")); -+ cube_XCreateColormap = TYPE_CONVERSION(PFN_XCreateColormap)(dlsym(xlib_library, "XCreateColormap")); -+ cube_XCreateWindow = TYPE_CONVERSION(PFN_XCreateWindow)(dlsym(xlib_library, "XCreateWindow")); -+ cube_XSelectInput = TYPE_CONVERSION(PFN_XSelectInput)(dlsym(xlib_library, "XSelectInput")); -+ cube_XMapWindow = TYPE_CONVERSION(PFN_XMapWindow)(dlsym(xlib_library, "XMapWindow")); -+ cube_XInternAtom = TYPE_CONVERSION(PFN_XInternAtom)(dlsym(xlib_library, "XInternAtom")); -+ cube_XNextEvent = TYPE_CONVERSION(PFN_XNextEvent)(dlsym(xlib_library, "XNextEvent")); -+ cube_XPending = TYPE_CONVERSION(PFN_XPending)(dlsym(xlib_library, "XPending")); -+ cube_XGetVisualInfo = TYPE_CONVERSION(PFN_XGetVisualInfo)(dlsym(xlib_library, "XGetVisualInfo")); -+ cube_XCloseDisplay = TYPE_CONVERSION(PFN_XCloseDisplay)(dlsym(xlib_library, "XCloseDisplay")); -+ cube_XInitThreads = TYPE_CONVERSION(PFN_XInitThreads)(dlsym(xlib_library, "XInitThreads")); -+ cube_XFlush = TYPE_CONVERSION(PFN_XFlush)(dlsym(xlib_library, "XFlush")); -+ -+ return xlib_library; -+} --- -2.47.0 - diff --git a/0001-vkcube-Remove-unused-command-line-option.patch b/0001-vkcube-Remove-unused-command-line-option.patch deleted file mode 100644 index ab13038..0000000 --- a/0001-vkcube-Remove-unused-command-line-option.patch +++ /dev/null @@ -1,46 +0,0 @@ -From eb9b6043be165f06c7ec78fadbb1ff773c5fc19c Mon Sep 17 00:00:00 2001 -From: Charles Giessen -Date: Fri, 11 Oct 2024 12:26:50 -0500 -Subject: [PATCH] vkcube: Remove unused command line option - -The --validate-checks-disabled flag was unused, so will be removed. ---- - cube/cube.c | 8 +------- - 1 file changed, 1 insertion(+), 7 deletions(-) - -diff --git a/cube/cube.c b/cube/cube.c -index 78d0bb55..4879317c 100644 ---- a/cube/cube.c -+++ b/cube/cube.c -@@ -437,7 +437,6 @@ struct demo { - int32_t curFrame; - int32_t frameCount; - bool validate; -- bool validate_checks_disabled; - bool use_break; - bool suppress_popups; - bool force_errors; -@@ -4223,11 +4222,6 @@ static void demo_init(struct demo *demo, int argc, char **argv) { - demo->validate = true; - continue; - } -- if (strcmp(argv[i], "--validate-checks-disabled") == 0) { -- demo->validate = true; -- demo->validate_checks_disabled = true; -- continue; -- } - if (strcmp(argv[i], "--xlib") == 0) { - fprintf(stderr, "--xlib is deprecated and no longer does anything"); - continue; -@@ -4286,7 +4280,7 @@ static void demo_init(struct demo *demo, int argc, char **argv) { - ERR_EXIT("Usage: vkcube [--validate]\n", "Usage"); - #else - char *message = -- "Usage:\n %s\t[--use_staging] [--validate] [--validate-checks-disabled]\n" -+ "Usage:\n %s\t[--use_staging] [--validate]\n" - "\t[--break] [--c ] [--suppress_popups]\n" - "\t[--incremental_present] [--display_timing]\n" - "\t[--gpu_number ]\n" --- -2.47.0 - diff --git a/sources b/sources index ac28191..ae54945 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (Vulkan-Tools-sdk-1.3.296.0.tar.gz) = 66bc89272f150198cd52f2971ad67a2fd6c922ac4bafb420c0d54788ca6bab2246e8a153a09eccce15a87e1fe16fdeef16af1c6b6b13386bff79dd73858f3cae +SHA512 (Vulkan-Tools-sdk-1.4.350.0.tar.gz) = 2d2afbcb06bb1ee08ffb3cbe133b531fe6341e90fa0dca4d5459dbdedf201521e798226768a7e307f8b6c08b388114a34a9a581a294f6226ca7a2fcd6f63f813 diff --git a/vulkan-tools.spec b/vulkan-tools.spec index 4c7ee38..2577e01 100644 --- a/vulkan-tools.spec +++ b/vulkan-tools.spec @@ -1,5 +1,5 @@ Name: vulkan-tools -Version: 1.3.296.0 +Version: 1.4.350.0 Release: %autorelease Summary: Vulkan tools @@ -7,13 +7,9 @@ License: Apache-2.0 URL: https://github.com/KhronosGroup/Vulkan-Tools Source0: %url/archive/vulkan-sdk-%{version}.tar.gz#/Vulkan-Tools-sdk-%{version}.tar.gz -# vkcube runtime selection support -Patch00: 0001-vkcube-Remove-unused-command-line-option.patch -Patch01: 0001-cube-Support-runtime-selection-of-WSI-platform.patch - BuildRequires: gcc BuildRequires: gcc-c++ -BuildRequires: cmake3 +BuildRequires: cmake BuildRequires: glslang BuildRequires: ninja-build BuildRequires: python%{python3_pkgversion}-devel @@ -40,12 +36,12 @@ Vulkan tools %build -%cmake3 -GNinja -DCMAKE_BUILD_TYPE=Release -DGLSLANG_INSTALL_DIR=%{_prefix} -%cmake3_build +%cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DGLSLANG_INSTALL_DIR=%{_prefix} +%cmake_build %install -%cmake3_install +%cmake_install %files %license LICENSE.txt