From 2b3075626bd9e81ad9799e1c811dbec12a3deb35 Mon Sep 17 00:00:00 2001 From: Karen Webb Date: Tue, 26 Nov 2024 18:29:06 +0000 Subject: [PATCH] surface: Better support for linux surface backends (#225) * surface: Better support for linux surface backends Manually create X surface instead of being tied to the Qt platform in use Don't rely on Qt's wayland/X libraries Don't violate vulkan spec with null wayland surface * Fix Build --- vulkanCapsViewer.pro | 4 +-- vulkanDeviceInfo.h | 4 --- vulkancapsviewer.cpp | 63 +++++++++++++++++++++++++++++++++++--------- 3 files changed, 52 insertions(+), 19 deletions(-) diff --git a/vulkanCapsViewer.pro b/vulkanCapsViewer.pro index 6b15e11..22bd705 100644 --- a/vulkanCapsViewer.pro +++ b/vulkanCapsViewer.pro @@ -27,12 +27,12 @@ linux:!android { LIBS += -lvulkan contains(DEFINES, X11) { message("Building for X11") - QT += x11extras + LIBS += -lxcb DEFINES += VK_USE_PLATFORM_XCB_KHR } contains(DEFINES, WAYLAND) { message("Building for Wayland") - QT += waylandclient + LIBS += -lwayland-client DEFINES += VK_USE_PLATFORM_WAYLAND_KHR } target.path = /usr/bin diff --git a/vulkanDeviceInfo.h b/vulkanDeviceInfo.h index 2b63a7f..a104712 100644 --- a/vulkanDeviceInfo.h +++ b/vulkanDeviceInfo.h @@ -51,10 +51,6 @@ #include #endif -#ifdef VK_USE_PLATFORM_XCB_KHR -#include -#endif - #include "vulkanandroid.h" #if !defined(DISABLE_PROFILES) #include "vulkan_profiles.hpp" diff --git a/vulkancapsviewer.cpp b/vulkancapsviewer.cpp index 5a84545..9c87175 100644 --- a/vulkancapsviewer.cpp +++ b/vulkancapsviewer.cpp @@ -56,10 +56,6 @@ #include #endif -#ifdef VK_USE_PLATFORM_XCB_KHR -#include -#endif - #ifdef VK_USE_PLATFORM_WAYLAND_KHR #include #endif @@ -785,21 +781,62 @@ bool VulkanCapsViewer::initVulkan() #if defined(VK_USE_PLATFORM_WAYLAND_KHR) if (surface_extension == VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) { - VkWaylandSurfaceCreateInfoKHR surfaceCreateInfo = {}; - surfaceCreateInfo.pNext = nullptr; - surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; - surfaceCreateInfo.display = wl_display_connect(NULL); - surfaceCreateInfo.surface = nullptr; - surfaceResult = vkCreateWaylandSurfaceKHR(vulkanContext.instance, &surfaceCreateInfo, nullptr, &vulkanContext.surface); + static const wl_registry_listener WAYLAND_LISTENER { + .global = [](void *data, wl_registry*, uint32_t name, const char* interface, uint32_t){ + if (!strcmp(interface, wl_compositor_interface.name)) { + *static_cast(data) = name; + } + }, + .global_remove = [](void*, wl_registry*, uint32_t){ + + } + }; + + const auto wayland_display = wl_display_connect(nullptr); + const auto wayland_registry = wl_display_get_registry(wayland_display); + uint32_t wayland_compositor_name = 0; + wl_registry_add_listener(wayland_registry, &WAYLAND_LISTENER, &wayland_compositor_name); + wl_display_roundtrip(wayland_display); + + if (wayland_compositor_name > 0) { + const auto wayland_compositor = static_cast( + wl_registry_bind(wayland_registry, wayland_compositor_name, &wl_compositor_interface, 1) + ); + const auto wayland_surface = wl_compositor_create_surface(wayland_compositor); + VkWaylandSurfaceCreateInfoKHR surfaceCreateInfo = {}; + surfaceCreateInfo.pNext = nullptr; + surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; + surfaceCreateInfo.display = wayland_display; + surfaceCreateInfo.surface = wayland_surface; + surfaceResult = vkCreateWaylandSurfaceKHR(vulkanContext.instance, &surfaceCreateInfo, nullptr, &vulkanContext.surface); + } } #endif - #if defined(VK_USE_PLATFORM_XCB_KHR) if (surface_extension == VK_KHR_XCB_SURFACE_EXTENSION_NAME) { + int xcb_screen_idx; + const auto xcb_connection = xcb_connect(nullptr, &xcb_screen_idx); + const auto xcb_setup = xcb_get_setup(xcb_connection); + auto xcb_screen = xcb_setup_roots_iterator(xcb_setup); + for (int i = 0; i < xcb_screen_idx; ++i) { + xcb_screen_next(&xcb_screen); + } + const auto xcb_window = xcb_generate_id(xcb_connection); + xcb_create_window( + xcb_connection, + xcb_screen.data->root_depth, + xcb_window, + xcb_screen.data->root, + 0, 0, + 800, 600, 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, + xcb_screen.data->root_visual, + 0, nullptr); + VkXcbSurfaceCreateInfoKHR surfaceCreateInfo = {}; surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; - surfaceCreateInfo.connection = QX11Info::connection(); - surfaceCreateInfo.window = static_cast(this->winId()); + surfaceCreateInfo.connection = xcb_connection; + surfaceCreateInfo.window = xcb_window; surfaceResult = vkCreateXcbSurfaceKHR(vulkanContext.instance, &surfaceCreateInfo, nullptr, &vulkanContext.surface); } #endif