From 20ffe83c91aa1d6090bc6eafd30b3f1c0c341f0b Mon Sep 17 00:00:00 2001 From: Rhys Parry <8833792+rp42@users.noreply.github.com> Date: Wed, 23 Oct 2024 15:45:14 +0100 Subject: [PATCH] vulkaninfo: On X11 use default visual If the visual passed to XCreateWindow is not the default one, it can cause a BadMatch error. Usually the first one returned does work, but in certain cases we need to search through all the visuals to find one that matches the default visual. This was seen on an xrdp session on Rocky 9. --- vulkaninfo/vulkaninfo.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/vulkaninfo/vulkaninfo.h b/vulkaninfo/vulkaninfo.h index 61540559f..116c0b0c0 100644 --- a/vulkaninfo/vulkaninfo.h +++ b/vulkaninfo/vulkaninfo.h @@ -71,6 +71,7 @@ #endif // _WIN32 #if defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR) +#include #include #endif @@ -772,7 +773,7 @@ static void AppDestroyXcbWindow(AppInstance &inst) { #ifdef VK_USE_PLATFORM_XLIB_KHR static void AppCreateXlibWindow(AppInstance &inst) { long visualMask = VisualScreenMask; - int numberOfVisuals; + int numberOfVisuals{}; inst.xlib_display = XOpenDisplay(nullptr); if (inst.xlib_display == nullptr) { @@ -781,12 +782,17 @@ static void AppCreateXlibWindow(AppInstance &inst) { XVisualInfo vInfoTemplate = {}; vInfoTemplate.screen = DefaultScreen(inst.xlib_display); - XVisualInfo *visualInfo = XGetVisualInfo(inst.xlib_display, visualMask, &vInfoTemplate, &numberOfVisuals); + XVisualInfo *visualInfoBegin = XGetVisualInfo(inst.xlib_display, visualMask, &vInfoTemplate, &numberOfVisuals); + XVisualInfo *visualInfoEnd = visualInfoBegin + numberOfVisuals; + const Visual *rootVisual = DefaultVisual(inst.xlib_display, vInfoTemplate.screen); + const XVisualInfo *foundVisualInfo = + std::find_if(visualInfoBegin, visualInfoEnd, [rootVisual](const XVisualInfo &vi) { return vi.visual == rootVisual; }); + const XVisualInfo *visualInfo = foundVisualInfo == visualInfoEnd ? visualInfoBegin : foundVisualInfo; inst.xlib_window = XCreateWindow(inst.xlib_display, RootWindow(inst.xlib_display, vInfoTemplate.screen), 0, 0, inst.width, inst.height, 0, visualInfo->depth, InputOutput, visualInfo->visual, 0, nullptr); XSync(inst.xlib_display, false); - XFree(visualInfo); + XFree(visualInfoBegin); } static VkSurfaceKHR AppCreateXlibSurface(AppInstance &inst) {