Skip to content

Commit

Permalink
surface: Better support for linux surface backends (#225)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
HildarTheDorf authored Nov 26, 2024
1 parent 9b7bfaa commit 2b30756
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 19 deletions.
4 changes: 2 additions & 2 deletions vulkanCapsViewer.pro
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 0 additions & 4 deletions vulkanDeviceInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,6 @@
#include <sys/system_properties.h>
#endif

#ifdef VK_USE_PLATFORM_XCB_KHR
#include <QX11Info>
#endif

#include "vulkanandroid.h"
#if !defined(DISABLE_PROFILES)
#include "vulkan_profiles.hpp"
Expand Down
63 changes: 50 additions & 13 deletions vulkancapsviewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,6 @@
#include <sys/utsname.h>
#endif

#ifdef VK_USE_PLATFORM_XCB_KHR
#include <QX11Info>
#endif

#ifdef VK_USE_PLATFORM_WAYLAND_KHR
#include <wayland-client.h>
#endif
Expand Down Expand Up @@ -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<uint32_t *>(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_compositor *>(
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<xcb_window_t>(this->winId());
surfaceCreateInfo.connection = xcb_connection;
surfaceCreateInfo.window = xcb_window;
surfaceResult = vkCreateXcbSurfaceKHR(vulkanContext.instance, &surfaceCreateInfo, nullptr, &vulkanContext.surface);
}
#endif
Expand Down

0 comments on commit 2b30756

Please sign in to comment.