Add optional XCB support to PlatformVkLinux.

This allows clients to build the Vulkan backend with either XLIB or XCB
support. I did a quick smoke test of the XCB option, but for now we are
continuing to default to XLIB. Note that the native window type used to
create the swap chain differs between these two API's.
This commit is contained in:
Philip Rideout
2020-10-16 16:11:05 -07:00
parent d14ba856a7
commit 5ceb9fc5d5
3 changed files with 48 additions and 11 deletions

View File

@@ -34,15 +34,18 @@ constexpr VkAllocationCallbacks* VKALLOC = nullptr;
static constexpr const char* LIBRARY_X11 = "libX11.so.6";
#ifdef FILAMENT_SUPPORTS_XCB
typedef xcb_connection_t* (*XCB_CONNECT)(const char *displayname, int *screenp);
#else
typedef Display* (*X11_OPEN_DISPLAY)(const char*);
typedef Display* (*X11_CLOSE_DISPLAY)(Display*);
typedef Status (*X11_GET_GEOMETRY)(Display*, Drawable, Window*, int*, int*, unsigned int*,
unsigned int*, unsigned int*, unsigned int*);
#endif
struct X11Functions {
#ifdef FILAMENT_SUPPORTS_XCB
XCB_CONNECT xcbConnect;
#else
X11_OPEN_DISPLAY openDisplay;
X11_CLOSE_DISPLAY closeDisplay;
X11_GET_GEOMETRY getGeometry;
#endif
void* library = nullptr;
} g_x11;
@@ -50,7 +53,11 @@ Driver* PlatformVkLinux::createDriver(void* const sharedContext) noexcept {
ASSERT_PRECONDITION(sharedContext == nullptr, "Vulkan does not support shared contexts.");
const char* requiredInstanceExtensions[] = {
"VK_KHR_surface",
#ifdef FILAMENT_SUPPORTS_XCB
"VK_KHR_xcb_surface",
#else
"VK_KHR_xlib_surface",
#endif
"VK_KHR_get_physical_device_properties2",
#if VK_ENABLE_VALIDATION
"VK_EXT_debug_utils",
@@ -61,22 +68,40 @@ Driver* PlatformVkLinux::createDriver(void* const sharedContext) noexcept {
}
void* PlatformVkLinux::createVkSurfaceKHR(void* nativeWindow, void* instance) noexcept {
#ifdef FILAMENT_SUPPORTS_XCB
if (g_x11.library == nullptr) {
g_x11.library = dlopen(LIBRARY_X11, RTLD_LOCAL | RTLD_NOW);
ASSERT_PRECONDITION(g_x11.library, "Unable to open X11 library.");
g_x11.xcbConnect = (XCB_CONNECT) dlsym(g_x11.library, "xcb_connect");
int screen;
mConnection = g_x11.xcbConnect(nullptr, &screen);
}
ASSERT_POSTCONDITION(vkCreateXcbSurfaceKHR, "Unable to load vkCreateXcbSurfaceKHR function.");
VkSurfaceKHR surface = nullptr;
const uint64_t ptrval = reinterpret_cast<uint64_t>(nativeWindow);
VkXcbSurfaceCreateInfoKHR createInfo = {
.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR,
.connection = mConnection,
.window = (xcb_window_t) ptrval,
};
VkResult result = vkCreateXcbSurfaceKHR((VkInstance) instance, &createInfo, VKALLOC, &surface);
#else
if (g_x11.library == nullptr) {
g_x11.library = dlopen(LIBRARY_X11, RTLD_LOCAL | RTLD_NOW);
ASSERT_PRECONDITION(g_x11.library, "Unable to open X11 library.");
g_x11.openDisplay = (X11_OPEN_DISPLAY) dlsym(g_x11.library, "XOpenDisplay");
g_x11.closeDisplay = (X11_CLOSE_DISPLAY) dlsym(g_x11.library, "XCloseDisplay");
g_x11.getGeometry = (X11_GET_GEOMETRY) dlsym(g_x11.library, "XGetGeometry");
mDisplay = g_x11.openDisplay(NULL);
ASSERT_PRECONDITION(mDisplay, "Unable to open X11 display.");
}
ASSERT_POSTCONDITION(vkCreateXlibSurfaceKHR, "Unable to load vkCreateXlibSurfaceKHR function.");
VkSurfaceKHR surface = nullptr;
VkXlibSurfaceCreateInfoKHR createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
createInfo.dpy = mDisplay;
createInfo.window = (Window) nativeWindow;
VkXlibSurfaceCreateInfoKHR createInfo = {
.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
.dpy = mDisplay,
.window = (Window) nativeWindow,
};
VkResult result = vkCreateXlibSurfaceKHR((VkInstance) instance, &createInfo, VKALLOC, &surface);
#endif
ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateXlibSurfaceKHR error.");
return surface;
}

View File

@@ -22,7 +22,11 @@
#include <backend/DriverEnums.h>
#include "VulkanPlatform.h"
#ifdef FILAMENT_SUPPORTS_XCB
#include <xcb/xcb.h>
#else
#include <X11/Xlib.h>
#endif
namespace filament {
@@ -36,7 +40,11 @@ public:
int getOSVersion() const noexcept override { return 0; }
private:
#ifdef FILAMENT_SUPPORTS_XCB
xcb_connection_t* mConnection;
#else
Display* mDisplay;
#endif
};
} // namespace filament

View File

@@ -26,7 +26,11 @@
#elif defined(IOS)
#define VK_USE_PLATFORM_IOS_MVK 1
#elif defined(__linux__)
#if defined(FILAMENT_SUPPORTS_XCB)
#define VK_USE_PLATFORM_XCB_KHR 1
#else
#define VK_USE_PLATFORM_XLIB_KHR 1
#endif
#elif defined(__APPLE__)
#define VK_USE_PLATFORM_MACOS_MVK 1
#elif defined(WIN32)