Add Wayland WSI support
This commit is contained in:
parent
eb5778039c
commit
570d9bc6ee
7 changed files with 551 additions and 3 deletions
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,13 @@
|
|||
#define KEY_N 0xE
|
||||
#define KEY_O 0xF
|
||||
#define KEY_T 0x10
|
||||
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
#include <linux/input.h>
|
||||
|
||||
// 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
|
||||
|
|
|
|||
|
|
@ -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<double, std::milli>(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<VulkanExampleBase *>(data);
|
||||
self->registryGlobal(registry, name, interface, version);
|
||||
}
|
||||
|
||||
/*static*/void VulkanExampleBase::seatCapabilitiesCb(void *data, wl_seat *seat,
|
||||
uint32_t caps)
|
||||
{
|
||||
VulkanExampleBase *self = reinterpret_cast<VulkanExampleBase *>(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<VulkanExampleBase *>(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<VulkanExampleBase *>(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<VulkanExampleBase *>(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<VulkanExampleBase *>(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
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
#include <android/asset_manager.h>
|
||||
#include <android_native_app_glue.h>
|
||||
#include "vulkanandroid.h"
|
||||
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
#include <wayland-client.h>
|
||||
#elif defined(__linux__)
|
||||
#include <xcb/xcb.h>
|
||||
#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
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
66
cmake/FindWayland.cmake
Normal file
66
cmake/FindWayland.cmake
Normal file
|
|
@ -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 <mgraesslin@kde.org>
|
||||
#
|
||||
# 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 ()
|
||||
|
|
@ -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
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue