diff --git a/filament/backend/src/vulkan/PlatformVkLinux.cpp b/filament/backend/src/vulkan/PlatformVkLinux.cpp index c1d8010b68..94e89b3e5a 100644 --- a/filament/backend/src/vulkan/PlatformVkLinux.cpp +++ b/filament/backend/src/vulkan/PlatformVkLinux.cpp @@ -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(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; } diff --git a/filament/backend/src/vulkan/PlatformVkLinux.h b/filament/backend/src/vulkan/PlatformVkLinux.h index fbbc07d757..c112ecd628 100644 --- a/filament/backend/src/vulkan/PlatformVkLinux.h +++ b/filament/backend/src/vulkan/PlatformVkLinux.h @@ -22,7 +22,11 @@ #include #include "VulkanPlatform.h" +#ifdef FILAMENT_SUPPORTS_XCB +#include +#else #include +#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 diff --git a/libs/bluevk/include/vulkan/vk_platform.h b/libs/bluevk/include/vulkan/vk_platform.h index 830b8e780e..4bfd1f0c1a 100644 --- a/libs/bluevk/include/vulkan/vk_platform.h +++ b/libs/bluevk/include/vulkan/vk_platform.h @@ -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)