Skip to content

Commit

Permalink
Merge pull request hrydgard#10449 from myfreeweb/master
Browse files Browse the repository at this point in the history
Vulkan + Wayland + FreeBSD
  • Loading branch information
hrydgard authored Dec 26, 2017
2 parents 43166c4 + bbf2dcd commit 4657397
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 79 deletions.
49 changes: 15 additions & 34 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,32 +69,13 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Android")
set(ANDROID ON)
endif()

# Of the CMake platforms, we only support Vulkan on Android and Windows.
if(ANDROID OR WIN32 OR LINUX)
# We only support Vulkan on Unix, Android and Windows.
if(ANDROID OR WIN32 OR (UNIX AND NOT APPLE))
set(VULKAN ON)
else()
add_definitions(-DNO_VULKAN)
endif()

if(NOT ANDROID)
# Use FindVulkan module added with CMAKE 3.7
if (NOT CMAKE_VERSION VERSION_LESS 3.7.0)
message(STATUS "Using module to find Vulkan")
find_package(Vulkan)
endif()
endif()

if(VULKAN AND NOT WIN32 AND NOT ANDROID)
IF (NOT Vulkan_FOUND)
find_library(Vulkan_LIBRARY NAMES vulkan HINTS "$ENV{VULKAN_SDK}/lib" "${CMAKE_SOURCE_DIR}/ext/vulkan" REQUIRED)
IF (Vulkan_LIBRARY)
set(Vulkan_FOUND ON)
MESSAGE("Using bundled Vulkan library version")
add_definitions(-DVULKAN_STATIC)
ENDIF()
ENDIF()
endif()

if(NOT DEFINED HEADLESS)
set(HEADLESS OFF)
endif()
Expand All @@ -106,12 +87,6 @@ else()
message("Normal Build")
endif()

if(LINUX AND VULKAN)
message("Using XCB extension...")
add_definitions(-DVK_USE_PLATFORM_XLIB_KHR)
# add_definitions(-DVK_USE_PLATFORM_XCB_KHR)
endif()

# Doesn't link on some platforms
#if(NOT DEFINED UNITTEST)
# set(UNITTEST OFF)
Expand All @@ -138,10 +113,20 @@ option(SIMULATOR "Set to ON when targeting an x86 simulator of an ARM platform"
# :: Options
option(USE_FFMPEG "Build with FFMPEG support" ${USE_FFMPEG})
option(USE_SYSTEM_FFMPEG "Dynamically link against system FFMPEG" ${USE_SYSTEM_FFMPEG})
option(USE_WAYLAND_WSI "Set to ON to require Wayland support for Vulkan" ${USE_WAYLAND_WSI})

# Vulkan on Linux options. If none of these are set, X11 is assumed.
OPTION(USE_D2D_WSI "Build the project using Direct to Display swapchain" OFF)
OPTION(USE_WAYLAND_WSI "Build the project using Wayland swapchain" OFF)
if(UNIX AND NOT APPLE AND VULKAN)
add_definitions(-DVK_USE_PLATFORM_XLIB_KHR)
# add_definitions(-DVK_USE_PLATFORM_XCB_KHR)
find_package(Wayland)
if (USE_WAYLAND_WSI AND NOT WAYLAND_FOUND)
message(FATAL_ERROR "Could not find libwayland, but USE_WAYLAND_WSI was enabled. Failing.")
endif()
if (WAYLAND_FOUND)
include_directories(${WAYLAND_INCLUDE_DIR})
add_definitions(-DVK_USE_PLATFORM_WAYLAND_KHR)
endif()
endif()

if(ANDROID)
set(CoreLibName ppsspp_jni)
Expand Down Expand Up @@ -1676,10 +1661,6 @@ set(GlslangLibs glslang OGLCompiler OSDependent SPIRV SPVRemapper spirv-cross-gl
target_link_libraries(${CoreLibName} Common native kirk cityhash sfmt19937 xbrz xxhash ${GlslangLibs}
${CoreExtraLibs} ${OPENGL_LIBRARIES} ${X11_LIBRARIES} ${CMAKE_DL_LIBS})

if(VULKAN AND NOT ANDROID AND NOT WIN32)
target_link_libraries(${CoreLibName} ${Vulkan_LIBRARY})
endif()

if(FFmpeg_FOUND)
target_compile_definitions(${CoreLibName} PRIVATE USE_FFMPEG=1)
target_link_libraries(${CoreLibName}
Expand Down
33 changes: 24 additions & 9 deletions Common/Vulkan/VulkanContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,19 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) {
instance_extensions_enabled_.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
#elif defined(__ANDROID__)
instance_extensions_enabled_.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
#elif defined(VK_USE_PLATFORM_XLIB_KHR)
instance_extensions_enabled_.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
#elif defined(VK_USE_PLATFORM_XCB_KHR)
instance_extensions_enabled_.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
#elif defined(VK_USE_PLATFORM_MIR_KHR)
instance_extensions_enabled_.push_back(VK_KHR_MIR_SURFACE_EXTENSION_NAME);
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
instance_extensions.enabled_.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
#else
//...
#if defined(VK_USE_PLATFORM_XLIB_KHR)
instance_extensions_enabled_.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
#endif
//#if defined(VK_USE_PLATFORM_XCB_KHR)
// instance_extensions_enabled_.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
//#endif
//#if defined(VK_USE_PLATFORM_MIR_KHR)
// instance_extensions_enabled_.push_back(VK_KHR_MIR_SURFACE_EXTENSION_NAME);
//#endif
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
instance_extensions_enabled_.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
#endif
#endif

if (flags_ & VULKAN_FLAG_VALIDATE) {
Expand Down Expand Up @@ -667,6 +670,18 @@ void VulkanContext::ReinitSurface(int width, int height) {
break;
}
#endif
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
case WINDOWSYSTEM_WAYLAND:
{
VkWaylandSurfaceCreateInfoKHR wayland = { VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR };
wayland.flags = 0;
wayland.display = (wl_display *)winsysData1_;
wayland.surface = (wl_surface *)winsysData2_;
VkResult res = vkCreateWaylandSurfaceKHR(instance_, &wayland, nullptr, &surface_);
assert(res == VK_SUCCESS);
break;
}
#endif

default:
_assert_msg_(G3D, false, "Vulkan support for chosen window system not implemented");
Expand Down
3 changes: 3 additions & 0 deletions Common/Vulkan/VulkanContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ enum WindowSystem {
#ifdef VK_USE_PLATFORM_XCB_KHR
WINDOWSYSTEM_XCB,
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
WINDOWSYSTEM_WAYLAND,
#endif
};

struct VulkanPhysicalDeviceInfo {
Expand Down
27 changes: 10 additions & 17 deletions Common/Vulkan/VulkanLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
#include <dlfcn.h>
#endif

#ifndef VULKAN_STATIC

PFN_vkCreateInstance vkCreateInstance;
PFN_vkDestroyInstance vkDestroyInstance;
PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
Expand Down Expand Up @@ -167,9 +165,13 @@ PFN_vkCmdExecuteCommands vkCmdExecuteCommands;
PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR;
#elif defined(_WIN32)
PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
#elif defined(VK_USE_PLATFORM_XLIB_KHR)
#endif
#if defined(VK_USE_PLATFORM_XLIB_KHR)
PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR;
#endif
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;
#endif

PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;

Expand All @@ -183,7 +185,6 @@ PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
PFN_vkQueuePresentKHR vkQueuePresentKHR;
#endif

// And the DEBUG_REPORT extension. We dynamically load this.
PFN_vkCreateDebugReportCallbackEXT dyn_vkCreateDebugReportCallbackEXT;
Expand All @@ -207,9 +208,6 @@ static const char *so_names[] = {
};

bool VulkanMayBeAvailable() {
#ifdef VULKAN_STATIC
return true;
#else
if (vulkanLibrary)
return true;
bool available = false;
Expand All @@ -231,11 +229,9 @@ bool VulkanMayBeAvailable() {
}
#endif
return available;
#endif
}

bool VulkanLoad() {
#ifndef VULKAN_STATIC
if (!vulkanLibrary) {
#ifndef _WIN32
for (int i = 0; i < ARRAY_SIZE(so_names); i++) {
Expand All @@ -260,12 +256,10 @@ bool VulkanLoad() {
LOAD_GLOBAL_FUNC(vkEnumerateInstanceLayerProperties);

WLOG("Vulkan base functions loaded.");
#endif
return true;
}

void VulkanLoadInstanceFunctions(VkInstance instance) {
#ifndef VULKAN_STATIC
// OK, let's use the above functions to get the rest.
LOAD_INSTANCE_FUNC(instance, vkDestroyInstance);
LOAD_INSTANCE_FUNC(instance, vkEnumeratePhysicalDevices);
Expand Down Expand Up @@ -415,12 +409,15 @@ void VulkanLoadInstanceFunctions(VkInstance instance) {
LOAD_INSTANCE_FUNC(instance, vkCreateWin32SurfaceKHR);
#elif defined(__ANDROID__)
LOAD_INSTANCE_FUNC(instance, vkCreateAndroidSurfaceKHR);
#elif defined(VK_USE_PLATFORM_XLIB_KHR)
#endif
#if defined(VK_USE_PLATFORM_XLIB_KHR)
LOAD_INSTANCE_FUNC(instance, vkCreateXlibSurfaceKHR);
#endif
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
LOAD_INSTANCE_FUNC(instance, vkCreateWaylandSurfaceKHR);
#endif

LOAD_INSTANCE_FUNC(instance, vkDestroySurfaceKHR);
#endif

dyn_vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");
dyn_vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");
Expand All @@ -433,18 +430,15 @@ void VulkanLoadInstanceFunctions(VkInstance instance) {
// good for multi-device.
void VulkanLoadDeviceFunctions(VkDevice device) {
WLOG("Vulkan device functions loaded.");
#ifndef VULKAN_STATIC
// TODO: Move more functions VulkanLoadInstanceFunctions to here.
LOAD_DEVICE_FUNC(device, vkCreateSwapchainKHR);
LOAD_DEVICE_FUNC(device, vkDestroySwapchainKHR);
LOAD_DEVICE_FUNC(device, vkGetSwapchainImagesKHR);
LOAD_DEVICE_FUNC(device, vkAcquireNextImageKHR);
LOAD_DEVICE_FUNC(device, vkQueuePresentKHR);
#endif
}

void VulkanFree() {
#ifndef VULKAN_STATIC
if (vulkanLibrary) {
#ifdef _WIN32
FreeLibrary(vulkanLibrary);
Expand All @@ -453,5 +447,4 @@ void VulkanFree() {
#endif
vulkanLibrary = nullptr;
}
#endif
}
11 changes: 5 additions & 6 deletions Common/Vulkan/VulkanLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,10 @@
#define NOMINMAX
#endif

#ifndef VULKAN_STATIC
#define VK_NO_PROTOTYPES
#endif

#include "ext/vulkan/vulkan.h"

#ifndef VULKAN_STATIC
extern PFN_vkCreateInstance vkCreateInstance;
extern PFN_vkDestroyInstance vkDestroyInstance;
extern PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
Expand Down Expand Up @@ -174,9 +171,13 @@ extern PFN_vkCmdExecuteCommands vkCmdExecuteCommands;
extern PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR;
#elif defined(_WIN32)
extern PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
#elif defined(VK_USE_PLATFORM_XLIB_KHR)
#endif
#if defined(VK_USE_PLATFORM_XLIB_KHR)
extern PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR;
#endif
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
extern PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;
#endif

extern PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;

Expand All @@ -192,8 +193,6 @@ extern PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
extern PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
extern PFN_vkQueuePresentKHR vkQueuePresentKHR;

#endif

// And the DEBUG_REPORT extension. Since we load this dynamically even in static
// linked mode, we have to rename it :(
extern PFN_vkCreateDebugReportCallbackEXT dyn_vkCreateDebugReportCallbackEXT;
Expand Down
26 changes: 13 additions & 13 deletions SDL/SDLMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,27 +438,27 @@ bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode,
fprintf(stderr, "Error getting SDL window wm info: %s\n", SDL_GetError());
exit(1);
}
Display *display = sys_info.info.x11.display;
Window x11_window = sys_info.info.x11.window;
switch (sys_info.subsystem) {
case SDL_SYSWM_X11:
#if defined(VK_USE_PLATFORM_XLIB_KHR)
vulkan_->InitSurface(WINDOWSYSTEM_XLIB, (void*)sys_info.info.x11.display,
(void *)(intptr_t)sys_info.info.x11.window, pixel_xres, pixel_yres);
#elif defined(VK_USE_PLATFORM_XCB_KHR)
vulkan_->InitSurface(WINDOWSYSTEM_XCB, (void*)XGetXCBConnection(sys_info.info.x11.display),
(void *)(intptr_t)sys_info.info.x11.window, pixel_xres, pixel_yres);
#endif
break;
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
case SDL_SYSWM_WAYLAND:
vulkan_->InitSurface(WINDOWSYSTEM_WAYLAND, (void*)sys_info.info.wl.display,
(void *)sys_info.info.wl.surface, pixel_xres, pixel_yres);
break;
#endif
default:
fprintf(stderr, "Vulkan subsystem %d not supported\n", sys_info.subsystem);
exit(1);
break;
}
#else
// Fake to make it build on Apple. This code won't run there though.
void *display = nullptr;
int x11_window = 0;
#endif
ILOG("Display: %p", display);

#if defined(VK_USE_PLATFORM_XLIB_KHR)
vulkan_->InitSurface(WINDOWSYSTEM_XLIB, (void*)display, (void *)(intptr_t)x11_window, pixel_xres, pixel_yres);
#elif defined(VK_USE_PLATFORM_XCB_KHR)
vulkan_->InitSurface(WINDOWSYSTEM_XCB, (void*)XGetXCBConnection(display), (void *)(intptr_t)x11_window, pixel_xres, pixel_yres);
#endif

if (!vulkan_->InitObjects()) {
Expand Down
66 changes: 66 additions & 0 deletions cmake/Modules/FindWayland.cmake
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
#
# 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 ()

0 comments on commit 4657397

Please sign in to comment.