diff --git a/src/common/vulkan_platform.h b/src/common/vulkan_platform.h index 236c68236c..3c78243009 100644 --- a/src/common/vulkan_platform.h +++ b/src/common/vulkan_platform.h @@ -162,6 +162,7 @@ namespace dawn_native { namespace vulkan { #if defined(DAWN_USE_X11) # define VK_USE_PLATFORM_XLIB_KHR +# define VK_USE_PLATFORM_XCB_KHR # include "common/xlib_with_undefs.h" #endif // defined(DAWN_USE_X11) diff --git a/src/common/xlib_with_undefs.h b/src/common/xlib_with_undefs.h index f82a19aa2d..660a87a5a2 100644 --- a/src/common/xlib_with_undefs.h +++ b/src/common/xlib_with_undefs.h @@ -24,6 +24,7 @@ // This header includes but removes all the extra defines that conflict with // identifiers in internal code. It should never be included in something that is part of the public // interface. +#include #include #undef Success diff --git a/src/dawn_native/BUILD.gn b/src/dawn_native/BUILD.gn index b98708c69d..398105f308 100644 --- a/src/dawn_native/BUILD.gn +++ b/src/dawn_native/BUILD.gn @@ -295,7 +295,10 @@ source_set("dawn_native_sources") { ] if (dawn_use_x11) { - libs += [ "X11" ] + libs += [ + "X11", + "X11-xcb", + ] } if (is_win) { diff --git a/src/dawn_native/CMakeLists.txt b/src/dawn_native/CMakeLists.txt index 8767a70b6c..37bf90867e 100644 --- a/src/dawn_native/CMakeLists.txt +++ b/src/dawn_native/CMakeLists.txt @@ -179,8 +179,17 @@ target_link_libraries(dawn_native ) if (DAWN_USE_X11) - find_package(X11 REQUIRED) + find_package(X11 REQUIRED OPTIONAL_COMPONENTS X11_xcb) target_link_libraries(dawn_native PRIVATE ${X11_LIBRARIES}) + target_include_directories(dawn_native PRIVATE ${X11_INCLUDE_DIR}) + + if (DAWN_ENABLE_VULKAN) + if (NOT X11_X11_xcb_FOUND) + message(FATAL_ERROR "X11::X11_xcb cannot be found, maybe because cmake < 3.18. Consider filing an issue for Dawn to bundle its own FindX11_XCB script") + endif() + target_link_libraries(dawn_native PRIVATE ${X11_X11_xcb_LIB}) + target_include_directories(dawn_native PRIVATE ${X11_X11_xcb_INCLUDE_PATH}) + endif() endif() if (WIN32) diff --git a/src/dawn_native/vulkan/SwapChainVk.cpp b/src/dawn_native/vulkan/SwapChainVk.cpp index 0398f1e758..65e7f77e2b 100644 --- a/src/dawn_native/vulkan/SwapChainVk.cpp +++ b/src/dawn_native/vulkan/SwapChainVk.cpp @@ -145,6 +145,26 @@ namespace dawn_native { namespace vulkan { "CreateXlibSurface")); return vkSurface; } + + // Fall back to using XCB surfaces if the Xlib extension isn't available. + // See https://xcb.freedesktop.org/MixingCalls/ for more information about + // interoperability between Xlib and XCB + if (info.HasExt(InstanceExt::XcbSurface)) { + VkXcbSurfaceCreateInfoKHR createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = nullptr; + createInfo.flags = 0; + // The XCB connection lives as long as the X11 display. + createInfo.connection = + XGetXCBConnection(static_cast(surface->GetXDisplay())); + createInfo.window = surface->GetXWindow(); + + VkSurfaceKHR vkSurface = VK_NULL_HANDLE; + DAWN_TRY(CheckVkSuccess( + fn.CreateXcbSurfaceKHR(instance, &createInfo, nullptr, &*vkSurface), + "CreateXcbSurfaceKHR")); + return vkSurface; + } break; #endif // defined(DAWN_USE_X11) diff --git a/src/dawn_native/vulkan/VulkanFunctions.cpp b/src/dawn_native/vulkan/VulkanFunctions.cpp index 9584475a4b..261aabe7a8 100644 --- a/src/dawn_native/vulkan/VulkanFunctions.cpp +++ b/src/dawn_native/vulkan/VulkanFunctions.cpp @@ -152,6 +152,10 @@ namespace dawn_native { namespace vulkan { GET_INSTANCE_PROC(CreateXlibSurfaceKHR); GET_INSTANCE_PROC(GetPhysicalDeviceXlibPresentationSupportKHR); } + if (globalInfo.HasExt(InstanceExt::XcbSurface)) { + GET_INSTANCE_PROC(CreateXcbSurfaceKHR); + GET_INSTANCE_PROC(GetPhysicalDeviceXcbPresentationSupportKHR); + } #endif // defined(DAWN_USE_X11) return {}; } diff --git a/src/dawn_native/vulkan/VulkanFunctions.h b/src/dawn_native/vulkan/VulkanFunctions.h index bb98b6d222..2e6218ee27 100644 --- a/src/dawn_native/vulkan/VulkanFunctions.h +++ b/src/dawn_native/vulkan/VulkanFunctions.h @@ -137,6 +137,11 @@ namespace dawn_native { namespace vulkan { PFN_vkCreateXlibSurfaceKHR CreateXlibSurfaceKHR = nullptr; PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR GetPhysicalDeviceXlibPresentationSupportKHR = nullptr; + + // KHR_xcb_surface + PFN_vkCreateXcbSurfaceKHR CreateXcbSurfaceKHR = nullptr; + PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR + GetPhysicalDeviceXcbPresentationSupportKHR = nullptr; #endif // defined(DAWN_USE_X11) // ---------- Device procs