From 570d9bc6ee3af50d284251bdc42162eb1eacfa7f Mon Sep 17 00:00:00 2001 From: Tomek Bury Date: Thu, 2 Feb 2017 08:54:56 +0000 Subject: [PATCH] Add Wayland WSI support --- CMakeLists.txt | 10 +- base/keycodes.hpp | 7 + base/vulkanexamplebase.cpp | 365 +++++++++++++++++++++++++++++++++++++ base/vulkanexamplebase.h | 78 +++++++- base/vulkanswapchain.hpp | 12 ++ cmake/FindWayland.cmake | 66 +++++++ triangle/triangle.cpp | 16 +- 7 files changed, 551 insertions(+), 3 deletions(-) create mode 100644 cmake/FindWayland.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 519e4a30..db31c71a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ include_directories(external/assimp) include_directories(base) OPTION(USE_D2D_WSI "Build the project using Direct to Display swapchain" OFF) +OPTION(USE_WAYLAND_WSI "Build the project using Wayland swapchain" OFF) # Use FindVulkan module added with CMAKE 3.7 if (NOT CMAKE_VERSION VERSION_LESS 3.7.0) @@ -43,6 +44,13 @@ ELSE(WIN32) IF(USE_D2D_WSI) MESSAGE("Using direct to display extension...") add_definitions(-D_DIRECT2DISPLAY) +ELSEIF(USE_WAYLAND_WSI) + find_package(Wayland REQUIRED) + if (NOT WAYLAND_FOUND) + message(FATAL_ERROR "Wayland development package not found") + endif () + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_USE_PLATFORM_WAYLAND_KHR") + include_directories(${WAYLAND_INCLUDE_DIR}) ELSE(USE_D2D_WSI) find_package(XCB REQUIRED) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_USE_PLATFORM_XCB_KHR") @@ -77,7 +85,7 @@ function(buildExample EXAMPLE_NAME) target_link_libraries(${EXAMPLE_NAME} ${Vulkan_LIBRARY} ${ASSIMP_LIBRARIES} ${WINLIBS}) else(WIN32) add_executable(${EXAMPLE_NAME} ${EXAMPLE_NAME}/${EXAMPLE_NAME}.cpp ${SOURCE}) - target_link_libraries(${EXAMPLE_NAME} ${Vulkan_LIBRARY} ${ASSIMP_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) + target_link_libraries(${EXAMPLE_NAME} ${Vulkan_LIBRARY} ${ASSIMP_LIBRARIES} ${WAYLAND_CLIENT_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) endif(WIN32) endfunction(buildExample) diff --git a/base/keycodes.hpp b/base/keycodes.hpp index 4650c55e..6b43775a 100644 --- a/base/keycodes.hpp +++ b/base/keycodes.hpp @@ -51,6 +51,13 @@ #define KEY_N 0xE #define KEY_O 0xF #define KEY_T 0x10 +#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) +#include + +// todo: hack for bloom example +#define KEY_KPADD KEY_KPPLUS +#define KEY_KPSUB KEY_KPMINUS + #elif defined(__linux__) #define KEY_ESCAPE 0x9 #define KEY_F1 0x43 diff --git a/base/vulkanexamplebase.cpp b/base/vulkanexamplebase.cpp index 4b44192b..fbddd714 100644 --- a/base/vulkanexamplebase.cpp +++ b/base/vulkanexamplebase.cpp @@ -29,6 +29,8 @@ VkResult VulkanExampleBase::createInstance(bool enableValidation) enabledExtensions.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); #elif defined(_DIRECT2DISPLAY) enabledExtensions.push_back(VK_KHR_DISPLAY_EXTENSION_NAME); +#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) + enabledExtensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); #elif defined(__linux__) enabledExtensions.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); #endif @@ -436,6 +438,49 @@ void VulkanExampleBase::renderLoop() frameCounter = 0; } } +#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) + while (!quit) + { + auto tStart = std::chrono::high_resolution_clock::now(); + if (viewUpdated) + { + viewUpdated = false; + viewChanged(); + } + wl_display_dispatch(display); + render(); + frameCounter++; + auto tEnd = std::chrono::high_resolution_clock::now(); + auto tDiff = std::chrono::duration(tEnd - tStart).count(); + frameTimer = tDiff / 1000.0f; + camera.update(frameTimer); + if (camera.moving()) + { + viewUpdated = true; + } + // Convert to clamped timer value + if (!paused) + { + timer += timerSpeed * frameTimer; + if (timer > 1.0) + { + timer -= 1.0f; + } + } + fpsTimer += (float)tDiff; + if (fpsTimer > 1000.0f) + { + if (!enableTextOverlay) + { + std::string windowTitle = getWindowTitle(); + wl_shell_surface_set_title(shell_surface, windowTitle.c_str()); + } + lastFPS = frameCounter; + updateTextOverlay(); + fpsTimer = 0.0f; + frameCounter = 0; + } + } #elif defined(__linux__) xcb_flush(connection); while (!quit) @@ -616,6 +661,8 @@ VulkanExampleBase::VulkanExampleBase(bool enableValidation) assert(libLoaded); #elif defined(_DIRECT2DISPLAY) +#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) + initWaylandConnection(); #elif defined(__linux__) initxcbConnection(); #endif @@ -682,6 +729,18 @@ VulkanExampleBase::~VulkanExampleBase() #if defined(_DIRECT2DISPLAY) +#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) + wl_shell_surface_destroy(shell_surface); + wl_surface_destroy(surface); + if (keyboard) + wl_keyboard_destroy(keyboard); + if (pointer) + wl_pointer_destroy(pointer); + wl_seat_destroy(seat); + wl_shell_destroy(shell); + wl_compositor_destroy(compositor); + wl_registry_destroy(registry); + wl_display_disconnect(display); #elif defined(__linux) #if defined(__ANDROID__) // todo : android cleanup (if required) @@ -1151,6 +1210,310 @@ void VulkanExampleBase::handleAppCommand(android_app * app, int32_t cmd) } } #elif defined(_DIRECT2DISPLAY) +#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) +/*static*/void VulkanExampleBase::registryGlobalCb(void *data, + wl_registry *registry, uint32_t name, const char *interface, + uint32_t version) +{ + VulkanExampleBase *self = reinterpret_cast(data); + self->registryGlobal(registry, name, interface, version); +} + +/*static*/void VulkanExampleBase::seatCapabilitiesCb(void *data, wl_seat *seat, + uint32_t caps) +{ + VulkanExampleBase *self = reinterpret_cast(data); + self->seatCapabilities(seat, caps); +} + +/*static*/void VulkanExampleBase::pointerEnterCb(void *data, + wl_pointer *pointer, uint32_t serial, wl_surface *surface, + wl_fixed_t sx, wl_fixed_t sy) +{ +} + +/*static*/void VulkanExampleBase::pointerLeaveCb(void *data, + wl_pointer *pointer, uint32_t serial, wl_surface *surface) +{ +} + +/*static*/void VulkanExampleBase::pointerMotionCb(void *data, + wl_pointer *pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy) +{ + VulkanExampleBase *self = reinterpret_cast(data); + self->pointerMotion(pointer, time, sx, sy); +} +void VulkanExampleBase::pointerMotion(wl_pointer *pointer, uint32_t time, + wl_fixed_t sx, wl_fixed_t sy) +{ + double x = wl_fixed_to_double(sx); + double y = wl_fixed_to_double(sy); + + double dx = mousePos.x - x; + double dy = mousePos.y - y; + + if (mouseButtons.left) + { + rotation.x += dy * 1.25f * rotationSpeed; + rotation.y -= dx * 1.25f * rotationSpeed; + camera.rotate(glm::vec3( + dy * camera.rotationSpeed, + -dx * camera.rotationSpeed, + 0.0f)); + viewUpdated = true; + } + if (mouseButtons.right) + { + zoom += dy * .005f * zoomSpeed; + camera.translate(glm::vec3(-0.0f, 0.0f, dy * .005f * zoomSpeed)); + viewUpdated = true; + } + if (mouseButtons.middle) + { + cameraPos.x -= dx * 0.01f; + cameraPos.y -= dy * 0.01f; + camera.translate(glm::vec3(-dx * 0.01f, -dy * 0.01f, 0.0f)); + viewUpdated = true; + } + mousePos = glm::vec2(x, y); +} + +/*static*/void VulkanExampleBase::pointerButtonCb(void *data, + wl_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, + uint32_t state) +{ + VulkanExampleBase *self = reinterpret_cast(data); + self->pointerButton(pointer, serial, time, button, state); +} + +void VulkanExampleBase::pointerButton(struct wl_pointer *pointer, + uint32_t serial, uint32_t time, uint32_t button, uint32_t state) +{ + switch (button) + { + case BTN_LEFT: + mouseButtons.left = !!state; + break; + case BTN_MIDDLE: + mouseButtons.middle = !!state; + break; + case BTN_RIGHT: + mouseButtons.right = !!state; + break; + default: + break; + } +} + +/*static*/void VulkanExampleBase::pointerAxisCb(void *data, + wl_pointer *pointer, uint32_t time, uint32_t axis, + wl_fixed_t value) +{ + VulkanExampleBase *self = reinterpret_cast(data); + self->pointerAxis(pointer, time, axis, value); +} + +void VulkanExampleBase::pointerAxis(wl_pointer *pointer, uint32_t time, + uint32_t axis, wl_fixed_t value) +{ + double d = wl_fixed_to_double(value); + switch (axis) + { + case REL_X: + zoom += d * 0.005f * zoomSpeed; + camera.translate(glm::vec3(0.0f, 0.0f, d * 0.005f * zoomSpeed)); + viewUpdated = true; + break; + default: + break; + } +} + +/*static*/void VulkanExampleBase::keyboardKeymapCb(void *data, + struct wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size) +{ +} + +/*static*/void VulkanExampleBase::keyboardEnterCb(void *data, + struct wl_keyboard *keyboard, uint32_t serial, + struct wl_surface *surface, struct wl_array *keys) +{ +} + +/*static*/void VulkanExampleBase::keyboardLeaveCb(void *data, + struct wl_keyboard *keyboard, uint32_t serial, + struct wl_surface *surface) +{ +} + +/*static*/void VulkanExampleBase::keyboardKeyCb(void *data, + struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, + uint32_t key, uint32_t state) +{ + VulkanExampleBase *self = reinterpret_cast(data); + self->keyboardKey(keyboard, serial, time, key, state); +} + +void VulkanExampleBase::keyboardKey(struct wl_keyboard *keyboard, + uint32_t serial, uint32_t time, uint32_t key, uint32_t state) +{ + switch (key) + { + case KEY_W: + camera.keys.up = !!state; + break; + case KEY_S: + camera.keys.down = !!state; + break; + case KEY_A: + camera.keys.left = !!state; + break; + case KEY_D: + camera.keys.right = !!state; + break; + case KEY_P: + if (state) + paused = !paused; + break; + case KEY_F1: + if (state && enableTextOverlay) + textOverlay->visible = !textOverlay->visible; + break; + case KEY_ESC: + quit = true; + break; + } + + if (state) + keyPressed(key); +} + +/*static*/void VulkanExampleBase::keyboardModifiersCb(void *data, + struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, + uint32_t mods_latched, uint32_t mods_locked, uint32_t group) +{ +} + +void VulkanExampleBase::seatCapabilities(wl_seat *seat, uint32_t caps) +{ + if ((caps & WL_SEAT_CAPABILITY_POINTER) && !pointer) + { + pointer = wl_seat_get_pointer(seat); + static const struct wl_pointer_listener pointer_listener = + { pointerEnterCb, pointerLeaveCb, pointerMotionCb, pointerButtonCb, + pointerAxisCb, }; + wl_pointer_add_listener(pointer, &pointer_listener, this); + } + else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && pointer) + { + wl_pointer_destroy(pointer); + pointer = nullptr; + } + + if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !keyboard) + { + keyboard = wl_seat_get_keyboard(seat); + static const struct wl_keyboard_listener keyboard_listener = + { keyboardKeymapCb, keyboardEnterCb, keyboardLeaveCb, keyboardKeyCb, + keyboardModifiersCb, }; + wl_keyboard_add_listener(keyboard, &keyboard_listener, this); + } + else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && keyboard) + { + wl_keyboard_destroy(keyboard); + keyboard = nullptr; + } +} + +void VulkanExampleBase::registryGlobal(wl_registry *registry, uint32_t name, + const char *interface, uint32_t version) +{ + if (strcmp(interface, "wl_compositor") == 0) + { + compositor = (wl_compositor *) wl_registry_bind(registry, name, + &wl_compositor_interface, 3); + } + else if (strcmp(interface, "wl_shell") == 0) + { + shell = (wl_shell *) wl_registry_bind(registry, name, + &wl_shell_interface, 1); + } + else if (strcmp(interface, "wl_seat") == 0) + { + seat = (wl_seat *) wl_registry_bind(registry, name, &wl_seat_interface, + 1); + + static const struct wl_seat_listener seat_listener = + { seatCapabilitiesCb, }; + wl_seat_add_listener(seat, &seat_listener, this); + } +} + +/*static*/void VulkanExampleBase::registryGlobalRemoveCb(void *data, + struct wl_registry *registry, uint32_t name) +{ +} + +void VulkanExampleBase::initWaylandConnection() +{ + display = wl_display_connect(NULL); + if (!display) + { + std::cout << "Could not connect to Wayland display!\n"; + fflush(stdout); + exit(1); + } + + registry = wl_display_get_registry(display); + if (!registry) + { + std::cout << "Could not get Wayland registry!\n"; + fflush(stdout); + exit(1); + } + + static const struct wl_registry_listener registry_listener = + { registryGlobalCb, registryGlobalRemoveCb }; + wl_registry_add_listener(registry, ®istry_listener, this); + wl_display_dispatch(display); + if (!compositor || !shell || !seat) + { + std::cout << "Could not bind Wayland protocols!\n"; + fflush(stdout); + exit(1); + } +} + +static void PingCb(void *data, struct wl_shell_surface *shell_surface, + uint32_t serial) +{ + wl_shell_surface_pong(shell_surface, serial); +} + +static void ConfigureCb(void *data, struct wl_shell_surface *shell_surface, + uint32_t edges, int32_t width, int32_t height) +{ +} + +static void PopupDoneCb(void *data, struct wl_shell_surface *shell_surface) +{ +} + +wl_shell_surface *VulkanExampleBase::setupWindow() +{ + surface = wl_compositor_create_surface(compositor); + shell_surface = wl_shell_get_shell_surface(shell, surface); + + static const struct wl_shell_surface_listener shell_surface_listener = + { PingCb, ConfigureCb, PopupDoneCb }; + + wl_shell_surface_add_listener(shell_surface, &shell_surface_listener, this); + wl_shell_surface_set_toplevel(shell_surface); + std::string windowTitle = getWindowTitle(); + wl_shell_surface_set_title(shell_surface, windowTitle.c_str()); + return shell_surface; +} + #elif defined(__linux__) static inline xcb_intern_atom_reply_t* intern_atom_helper(xcb_connection_t *conn, bool only_if_exists, const char *str) @@ -1613,6 +1976,8 @@ void VulkanExampleBase::initSwapchain() swapChain.initSurface(androidApp->window); #elif defined(_DIRECT2DISPLAY) swapChain.initSurface(width, height); +#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) + swapChain.initSurface(display, surface); #elif defined(__linux__) swapChain.initSurface(connection, window); #endif diff --git a/base/vulkanexamplebase.h b/base/vulkanexamplebase.h index d9e47a68..6d3c2e19 100644 --- a/base/vulkanexamplebase.h +++ b/base/vulkanexamplebase.h @@ -18,6 +18,8 @@ #include #include #include "vulkanandroid.h" +#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) +#include #elif defined(__linux__) #include #endif @@ -194,6 +196,23 @@ public: #elif defined(__ANDROID__) // true if application has focused, false if moved to background bool focused = false; + +#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) + wl_display *display = nullptr; + wl_registry *registry = nullptr; + wl_compositor *compositor = nullptr; + wl_shell *shell = nullptr; + wl_seat *seat = nullptr; + wl_pointer *pointer = nullptr; + wl_keyboard *keyboard = nullptr; + wl_surface *surface = nullptr; + wl_shell_surface *shell_surface = nullptr; + bool quit = false; + struct { + bool left = false; + bool right = false; + bool middle = false; + } mouseButtons; #elif defined(__linux__) struct { bool left = false; @@ -223,6 +242,48 @@ public: #elif defined(__ANDROID__) static int32_t handleAppInput(struct android_app* app, AInputEvent* event); static void handleAppCommand(android_app* app, int32_t cmd); +#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) + wl_shell_surface *setupWindow(); + void initWaylandConnection(); + static void registryGlobalCb(void *data, struct wl_registry *registry, + uint32_t name, const char *interface, uint32_t version); + void registryGlobal(struct wl_registry *registry, uint32_t name, + const char *interface, uint32_t version); + static void registryGlobalRemoveCb(void *data, struct wl_registry *registry, + uint32_t name); + static void seatCapabilitiesCb(void *data, wl_seat *seat, uint32_t caps); + void seatCapabilities(wl_seat *seat, uint32_t caps); + static void pointerEnterCb(void *data, struct wl_pointer *pointer, + uint32_t serial, struct wl_surface *surface, wl_fixed_t sx, + wl_fixed_t sy); + static void pointerLeaveCb(void *data, struct wl_pointer *pointer, + uint32_t serial, struct wl_surface *surface); + static void pointerMotionCb(void *data, struct wl_pointer *pointer, + uint32_t time, wl_fixed_t sx, wl_fixed_t sy); + void pointerMotion(struct wl_pointer *pointer, + uint32_t time, wl_fixed_t sx, wl_fixed_t sy); + static void pointerButtonCb(void *data, struct wl_pointer *wl_pointer, + uint32_t serial, uint32_t time, uint32_t button, uint32_t state); + void pointerButton(struct wl_pointer *wl_pointer, + uint32_t serial, uint32_t time, uint32_t button, uint32_t state); + static void pointerAxisCb(void *data, struct wl_pointer *wl_pointer, + uint32_t time, uint32_t axis, wl_fixed_t value); + void pointerAxis(struct wl_pointer *wl_pointer, + uint32_t time, uint32_t axis, wl_fixed_t value); + static void keyboardKeymapCb(void *data, struct wl_keyboard *keyboard, + uint32_t format, int fd, uint32_t size); + static void keyboardEnterCb(void *data, struct wl_keyboard *keyboard, + uint32_t serial, struct wl_surface *surface, struct wl_array *keys); + static void keyboardLeaveCb(void *data, struct wl_keyboard *keyboard, + uint32_t serial, struct wl_surface *surface); + static void keyboardKeyCb(void *data, struct wl_keyboard *keyboard, + uint32_t serial, uint32_t time, uint32_t key, uint32_t state); + void keyboardKey(struct wl_keyboard *keyboard, + uint32_t serial, uint32_t time, uint32_t key, uint32_t state); + static void keyboardModifiersCb(void *data, struct wl_keyboard *keyboard, + uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, + uint32_t mods_locked, uint32_t group); + #elif defined(__linux__) xcb_window_t setupWindow(); void initxcbConnection(); @@ -384,6 +445,21 @@ int main(const int argc, const char *argv[]) \ delete(vulkanExample); \ return 0; \ } +#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) +#define VULKAN_EXAMPLE_MAIN() \ +VulkanExample *vulkanExample; \ +int main(const int argc, const char *argv[]) \ +{ \ + for (size_t i = 0; i < argc; i++) { VulkanExample::args.push_back(argv[i]); }; \ + vulkanExample = new VulkanExample(); \ + vulkanExample->initVulkan(); \ + vulkanExample->setupWindow(); \ + vulkanExample->initSwapchain(); \ + vulkanExample->prepare(); \ + vulkanExample->renderLoop(); \ + delete(vulkanExample); \ + return 0; \ +} #elif defined(__linux__) // Linux entry point #define VULKAN_EXAMPLE_MAIN() \ @@ -407,4 +483,4 @@ int main(const int argc, const char *argv[]) \ delete(vulkanExample); \ return 0; \ } -#endif \ No newline at end of file +#endif diff --git a/base/vulkanswapchain.hpp b/base/vulkanswapchain.hpp index fe4f1ea7..1d5eb087 100644 --- a/base/vulkanswapchain.hpp +++ b/base/vulkanswapchain.hpp @@ -109,10 +109,14 @@ public: #else #ifdef _DIRECT2DISPLAY uint32_t width, uint32_t height +#else +#ifdef VK_USE_PLATFORM_WAYLAND_KHR + wl_display *display, wl_surface *window #else xcb_connection_t* connection, xcb_window_t window #endif #endif +#endif #endif ) { @@ -134,6 +138,13 @@ public: #else #if defined(_DIRECT2DISPLAY) createDirect2DisplaySurface(width, height); +#else +#ifdef VK_USE_PLATFORM_WAYLAND_KHR + VkWaylandSurfaceCreateInfoKHR surfaceCreateInfo = {}; + surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; + surfaceCreateInfo.display = display; + surfaceCreateInfo.surface = window; + err = vkCreateWaylandSurfaceKHR(instance, &surfaceCreateInfo, nullptr, &surface); #else VkXcbSurfaceCreateInfoKHR surfaceCreateInfo = {}; surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; @@ -142,6 +153,7 @@ public: err = vkCreateXcbSurfaceKHR(instance, &surfaceCreateInfo, nullptr, &surface); #endif #endif +#endif #endif // Get available queue family properties diff --git a/cmake/FindWayland.cmake b/cmake/FindWayland.cmake new file mode 100644 index 00000000..f93218b8 --- /dev/null +++ b/cmake/FindWayland.cmake @@ -0,0 +1,66 @@ +# Try to find Wayland on a Unix system +# +# This will define: +# +# WAYLAND_FOUND - True if Wayland is found +# WAYLAND_LIBRARIES - Link these to use Wayland +# WAYLAND_INCLUDE_DIR - Include directory for Wayland +# WAYLAND_DEFINITIONS - Compiler flags for using Wayland +# +# In addition the following more fine grained variables will be defined: +# +# WAYLAND_CLIENT_FOUND WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES +# WAYLAND_SERVER_FOUND WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES +# WAYLAND_EGL_FOUND WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES +# +# Copyright (c) 2013 Martin Gräßlin +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +IF (NOT WIN32) + IF (WAYLAND_INCLUDE_DIR AND WAYLAND_LIBRARIES) + # In the cache already + SET(WAYLAND_FIND_QUIETLY TRUE) + ENDIF () + + # Use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + FIND_PACKAGE(PkgConfig) + PKG_CHECK_MODULES(PKG_WAYLAND QUIET wayland-client wayland-server wayland-egl wayland-cursor) + + SET(WAYLAND_DEFINITIONS ${PKG_WAYLAND_CFLAGS}) + + FIND_PATH(WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) + FIND_PATH(WAYLAND_SERVER_INCLUDE_DIR NAMES wayland-server.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) + FIND_PATH(WAYLAND_EGL_INCLUDE_DIR NAMES wayland-egl.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) + FIND_PATH(WAYLAND_CURSOR_INCLUDE_DIR NAMES wayland-cursor.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS}) + + FIND_LIBRARY(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) + FIND_LIBRARY(WAYLAND_SERVER_LIBRARIES NAMES wayland-server HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) + FIND_LIBRARY(WAYLAND_EGL_LIBRARIES NAMES wayland-egl HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) + FIND_LIBRARY(WAYLAND_CURSOR_LIBRARIES NAMES wayland-cursor HINTS ${PKG_WAYLAND_LIBRARY_DIRS}) + + set(WAYLAND_INCLUDE_DIR ${WAYLAND_CLIENT_INCLUDE_DIR} ${WAYLAND_SERVER_INCLUDE_DIR} ${WAYLAND_EGL_INCLUDE_DIR} ${WAYLAND_CURSOR_INCLUDE_DIR}) + + set(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_EGL_LIBRARIES} ${WAYLAND_CURSOR_LIBRARIES}) + + list(REMOVE_DUPLICATES WAYLAND_INCLUDE_DIR) + + include(FindPackageHandleStandardArgs) + + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CLIENT DEFAULT_MSG WAYLAND_CLIENT_LIBRARIES WAYLAND_CLIENT_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_SERVER DEFAULT_MSG WAYLAND_SERVER_LIBRARIES WAYLAND_SERVER_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_EGL DEFAULT_MSG WAYLAND_EGL_LIBRARIES WAYLAND_EGL_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND_CURSOR DEFAULT_MSG WAYLAND_CURSOR_LIBRARIES WAYLAND_CURSOR_INCLUDE_DIR) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND DEFAULT_MSG WAYLAND_LIBRARIES WAYLAND_INCLUDE_DIR) + + MARK_AS_ADVANCED( + WAYLAND_INCLUDE_DIR WAYLAND_LIBRARIES + WAYLAND_CLIENT_INCLUDE_DIR WAYLAND_CLIENT_LIBRARIES + WAYLAND_SERVER_INCLUDE_DIR WAYLAND_SERVER_LIBRARIES + WAYLAND_EGL_INCLUDE_DIR WAYLAND_EGL_LIBRARIES + WAYLAND_CURSOR_INCLUDE_DIR WAYLAND_CURSOR_LIBRARIES + ) + +ENDIF () diff --git a/triangle/triangle.cpp b/triangle/triangle.cpp index 523485f3..4a403678 100644 --- a/triangle/triangle.cpp +++ b/triangle/triangle.cpp @@ -1151,6 +1151,20 @@ int main(const int argc, const char *argv[]) delete(vulkanExample); return 0; } +#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) +VulkanExample *vulkanExample; +int main(const int argc, const char *argv[]) +{ + for (size_t i = 0; i < argc; i++) { VulkanExample::args.push_back(argv[i]); }; + vulkanExample = new VulkanExample(); + vulkanExample->initVulkan(); + vulkanExample->setupWindow(); + vulkanExample->initSwapchain(); + vulkanExample->prepare(); + vulkanExample->renderLoop(); + delete(vulkanExample); + return 0; +} #elif defined(__linux__) // Linux entry point @@ -1174,4 +1188,4 @@ int main(const int argc, const char *argv[]) delete(vulkanExample); return 0; } -#endif \ No newline at end of file +#endif