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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user