Add Vulkan renderer
This PR adds a new Vulkan renderer to complement the existing EGL renderer. It is usable, but incomplete, considered experimental, and disabled by default. Notably, it is currently slower than the EGL renderer owing to unimplemented DMA-BUF and damage rect support.
The primary motivation for this change is to bring true HDR support to Looking Glass, which is not currently possible via EGL.[^1]
Building with Vulkan support
Pass -DENABLE_VULKAN=1 to cmake when building the Looking Glass client. You may need to install luajit if cimgui binding generation fails.
Using the Vulkan renderer
Pass app:renderer=Vulkan to looking-glass-client to use the Vulkan renderer.
I also recommend initially passing vulkan:validate=true to enable the Vulkan validation layer. If any validation errors are logged to the console, please let me know.
Using HDR
Requirements
- Wayland
- A compositor which implements the Wayland color management protocol. I have tested against KWin 6.3. Hyprland may also work, but I have not tried it
- Enable HDR in your system display settings on both client and host
- Install the Vulkan Wayland HDR WSI layer (available in AUR as vk-hdr-layer-kwin6-git)
- This is a temporary requirement until Mesa MR 32038 lands
- Run
looking-glass-clientwith the environment variableENABLE_HDR_WSI=1to enable the above Vulkan layer - If using AMD graphics on the client, you must use RADV (Mesa). If you have both RADV and AMDVLK installed, you can force RADV by running
looking-glass-clientwith the environment variableAMD_VULKAN_ICD=RADV.
Other HDR advice
The following advice is specific to KWin 6.3. Other compositors/versions may behave slightly differently.
Set the SDR content brightness to 31 in Windows. This is approximately equal to the reference luminance of 203 nits used by KWin, which should make SDR white content look identical to that of native Linux applications, and the difference between HDR on and off in Windows should be virtually indistinguishable when looking at SDR content.
Be aware that the 'Maximum SDR Brightness' setting within the KDE display configuration also affects HDR content.[^2] I recommend setting this to whatever brightness feels most comfortable, but it can be set to the reference level of 203 nits to most accurately reproduce the Windows output with minimal interference by KWin.
[^1]: Theoretically, maybe it could be supported via extensions such as EGL_EXT_gl_colorspace_bt2020_pq, but Mesa does not currently implement these.
[^2]: https://zamundaaa.github.io/wayland/2024/11/06/hdr-and-color-management-in-kwin-part-5.html
Getting this if validation layers enabled
VUID-VkSwapchainCreateInfoKHR-imageExtent-01689(ERROR / SPEC): msgNum: 320081257 - Validation Error: [ VUID-VkSwapchainCreateInfoKHR-imageExtent-01689 ] | MessageID = 0x13140d69 | vkCreateSwapchainKHR(): pCreateInfo->imageExtent (width = 0, height = 0) is invalid.
The Vulkan spec states: imageExtent members width and height must both be non-zero (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkSwapchainCreateInfoKHR-imageExtent-01689)
VUID-VkSwapchainCreateInfoKHR-pNext-07781(ERROR / SPEC): msgNum: 1284057537 - Validation Error: [ VUID-VkSwapchainCreateInfoKHR-pNext-07781 ] | MessageID = 0x4c8929c1 | vkCreateSwapchainKHR(): pCreateInfo->imageExtent (width = 0, height = 0), which is outside the bounds returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): currentExtent = (width = 4294967295, height = 4294967295), minImageExtent = (width = 1, height = 1), maxImageExtent = (width = 16384, height = 16384).
The Vulkan spec states: If a VkSwapchainPresentScalingCreateInfoEXT structure was not included in the pNext chain, or it is included and VkSwapchainPresentScalingCreateInfoEXT::scalingBehavior is zero then imageExtent must be between minImageExtent and maxImageExtent, inclusive, where minImageExtent and maxImageExtent are members of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkSwapchainCreateInfoKHR-pNext-07781)
VUID-VkFramebufferCreateInfo-width-00885(ERROR / SPEC): msgNum: -1231547098 - Validation Error: [ VUID-VkFramebufferCreateInfo-width-00885 ] | MessageID = 0xb6981526 | vkCreateFramebuffer(): pCreateInfo->width is zero.
The Vulkan spec states: width must be greater than 0 (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkFramebufferCreateInfo-width-00885)
VUID-VkFramebufferCreateInfo-height-00887(ERROR / SPEC): msgNum: -1513456701 - Validation Error: [ VUID-VkFramebufferCreateInfo-height-00887 ] | MessageID = 0xa5ca7bc3 | vkCreateFramebuffer(): pCreateInfo->height is zero.
The Vulkan spec states: height must be greater than 0 (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkFramebufferCreateInfo-height-00887)
00:00:00.544 [E] crash.c:215 | crit_err_hdlr | ==== FATAL CRASH (B7-rc1-72-g0382a46d49+) ====
00:00:00.544 [E] crash.c:216 | crit_err_hdlr | signal 11 (Segmentation fault), address is (nil)
00:00:00.544 [E] crash.c:207 | printBacktrace | [trace]: (0) /usr/lib/libc.so.6(+0x42560) [0x7b075abe7560]
00:00:00.544 [E] crash.c:207 | printBacktrace | [trace]: (1) /usr/lib/libVkLayer_khronos_validation.so(+0x8a71ea) [0x7b073a4e71ea]
00:00:00.544 [E] crash.c:207 | printBacktrace | [trace]: (2) /usr/lib/libVkLayer_khronos_validation.so(+0x924e3a) [0x7b073a564e3a]
00:00:00.544 [E] crash.c:207 | printBacktrace | [trace]: (3) /usr/lib/libVkLayer_khronos_validation.so(+0x8fa589) [0x7b073a53a589]
00:00:00.544 [E] crash.c:207 | printBacktrace | [trace]: (4) /usr/lib/libVkLayer_khronos_validation.so(+0x507442) [0x7b073a147442]
00:00:00.544 [E] crash.c:202 | printBacktrace | [trace]: (5) vulkan.c:0 (vulkan_createFramebuffers)
00:00:00.544 [E] crash.c:202 | printBacktrace | [trace]: (6) vulkan.c:0 (vulkan_initPipeline)
00:00:00.544 [E] crash.c:202 | printBacktrace | [trace]: (7) vulkan.c:0 (vulkan_onFrameFormat)
00:00:00.544 [E] crash.c:207 | printBacktrace | [trace]: (8) /data/build/LookingGlass/client/build/looking-glass-client(+0x4da1d) [0x5e6b4e62fa1d]
00:00:00.544 [E] crash.c:202 | printBacktrace | [trace]: (9) thread.c:0 (threadWrapper)
00:00:00.544 [E] crash.c:207 | printBacktrace | [trace]: (10) /usr/lib/libc.so.6(+0x9fc5c) [0x7b075ac44c5c]
00:00:00.544 [E] crash.c:207 | printBacktrace | [trace]: (11) /usr/lib/libc.so.6(+0x1218dc) [0x7b075acc68dc]
@Vityacv Can you identify any particular condition that triggers this failure? It seems from your comment in #1151 that the Vulkan renderer is generally working?
Hi, on Ubuntu 24.10 build failed with: /bin/sh: 1: glslangValidator: not found. Fixed by installing glslang-dev and glslang-tools.
For me, window size cannot be changed, when resizing, it get malformed.
./looking-glass-client -a -d -S -k -f /dev/shm/looking-glass app:renderer=Vulkan
Running without vulkan enabled still works as expected.
00:00:00.000 [I] main.c:1865 | main | Looking Glass (B7-rc1-72-g0382a46d49+)
00:00:00.000 [I] main.c:1866 | main | Locking Method: Atomic
00:00:00.000 [I] cpuinfo.c:38 | cpuInfo_log | CPU Model: 13th Gen Intel(R) Core(TM) i9-13980HX
00:00:00.000 [I] cpuinfo.c:39 | cpuInfo_log | CPU: 1 sockets, 24 cores, 32 threads
00:00:00.019 [I] main.c:1192 | lg_run | Using font: /usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf
00:00:00.020 [I] ivshmem.c:137 | ivshmemOpenDev | KVMFR Device : /dev/shm/looking-glass
00:00:00.021 [I] audio.c:159 | audio_init | Using AudioDev: PipeWire
00:00:00.021 [I] ps.c:245 | purespice_connect | Connecting to socket 127.0.0.1:5900
00:00:00.028 [I] rsa.c:178 | rsa_encryptPassword | Using Nettle
00:00:00.028 [I] ps.c:268 | purespice_connect | Connected
00:00:00.028 [I] agent.c:103 | agent_connect | Connected to the spice guest agent
00:00:00.028 [I] channel_main.c:167 | onMessage_mainName | Guest name: win11
00:00:00.028 [I] channel_main.c:183 | onMessage_mainUUID | Guest UUID: 8d7b69aa-7899-4b76-a824-a3d015d35605
00:00:00.034 [I] ps.c:644 | ps_connectChannel | RECORD channel connected
00:00:00.042 [I] ps.c:644 | ps_connectChannel | PLAYBACK channel connected
00:00:00.048 [I] ps.c:644 | ps_connectChannel | INPUTS channel connected
00:00:00.048 [I] main.c:1321 | lg_run | Trying forced renderer
00:00:00.048 [I] channel.c:323 | onMessage_notify | [notify] keyboard channel is insecure
00:00:00.048 [I] main.c:1146 | tryRenderer | Using Renderer: Vulkan
00:00:00.048 [I] wayland.c:120 | waylandInit | Compositor: gnome-shell
00:00:00.048 [I] wayland.c:130 | waylandInit | Selected : libdecor
00:00:00.319 [I] extensions.c:129 | vulkan_checkExtensions | Enabling optional extension 'VK_EXT_swapchain_colorspace'
00:00:00.539 [I] vulkan.c:1159 | vulkan_printDeviceDetails | Device : Intel(R) Graphics (RPL-S)
00:00:00.539 [I] vulkan.c:1160 | vulkan_printDeviceDetails | Driver name : Intel open-source Mesa driver
00:00:00.539 [I] vulkan.c:1161 | vulkan_printDeviceDetails | Driver info : Mesa 25.0~git2502210600.64552d~oibaf~o (git-64552db 2025-02-21 oracular-oibaf-ppa)
00:00:00.539 [I] vulkan.c:1162 | vulkan_printDeviceDetails | Queue family: 0
00:00:00.554 [I] vulkan.c:533 | vulkan_createSwapchain | Min image count: 4
00:00:00.554 [I] vulkan.c:534 | vulkan_createSwapchain | Image format : 44
00:00:00.554 [I] vulkan.c:535 | vulkan_createSwapchain | Color space : 0
00:00:00.554 [I] vulkan.c:536 | vulkan_createSwapchain | Extent : 1024x768
00:00:00.554 [I] vulkan.c:538 | vulkan_createSwapchain | Pre-transform : 1
00:00:00.554 [I] vulkan.c:539 | vulkan_createSwapchain | Composite alpha: 1
00:00:00.554 [I] vulkan.c:540 | vulkan_createSwapchain | Present mode : 1
00:00:00.554 [I] main.c:1596 | lg_run | Guest Information:
00:00:00.554 [I] main.c:1597 | lg_run | Version : B7-rc1-72-g0382a46d49+
00:00:00.554 [I] main.c:1618 | lg_run | UUID : 00000000-0000-0000-0000-000000000000
00:00:00.554 [I] main.c:1627 | lg_run | CPU Model: 13th Gen Intel(R) Core(TM) i9-13980HX
00:00:00.554 [I] main.c:1628 | lg_run | CPU : 1 sockets, 6 cores, 12 threads
00:00:00.554 [I] main.c:1630 | lg_run | Using : D12
00:00:00.554 [I] main.c:1716 | lg_run | OS : Windows
00:00:00.554 [I] main.c:1718 | lg_run | OS Name : Windows 10 Pro (Build: 26100)
00:00:00.554 [I] main.c:1740 | lg_run | Starting session
00:00:00.873 [I] main.c:717 | main_frameThread | Format: FRAME_TYPE_BGRA 3840x2160 (3840x2160) stride:3840 pitch:15360 rotation:0 hdr:0 pq:0
Also system is detected as Windows 10 but actually is Windows 11.
Forcing full screen with -F parameter open small window which is hidden/minimized and cannot be opened. Moving to another monitor does not help.
This and above is with -DLIBDECOR=ON.
Below is with -DLIBDECOR=NO.
Window is small/cannot resize due to missing decorator (expected). When I toggle full screen with keyboard shortcut, window size stay same and Ubuntu toolbars got hidden (toolbar shoud be on left and top side).
Using keyboard shortcut brings toolbars back.
When I force full screen by -F, window opens for half a second and crash with:
00:00:00.512 [I] main.c:1718 | lg_run | OS Name : Windows 10 Pro (Build: 26100)
00:00:00.512 [I] main.c:1740 | lg_run | Starting session
00:00:00.701 [E] vulkan.c:1713 | vulkan_acquireSwapchainImage | Failed to acquire swapchain image (VkResult: 1000001003)
00:00:00.747 [I] channel.c:269 | channel_internal_disconnect | RECORD channel disconnected
00:00:00.747 [I] channel.c:269 | channel_internal_disconnect | PLAYBACK channel disconnected
00:00:00.747 [I] channel.c:269 | channel_internal_disconnect | INPUTS channel disconnected
00:00:00.747 [I] channel.c:269 | channel_internal_disconnect | MAIN channel disconnected
@Vityacv Can you identify any particular condition that triggers this failure? It seems from your comment in #1151 that the Vulkan renderer is generally working?
It works only with vulkan:validate=no, also log when launching with amd gpu (using validate=yes)
00:00:00.022 [I] main.c:1146 | tryRenderer | Using Renderer: Vulkan
00:00:00.022 [I] wayland.c:120 | waylandInit | Compositor: sway
00:00:00.022 [I] wayland.c:130 | waylandInit | Selected : xdg
00:00:00.027 [I] vulkan.c:1097 | vulkan_createInstance | Enabling validation layer
00:00:00.027 [I] extensions.c:129 | vulkan_checkExtensions | Enabling optional extension 'VK_EXT_swapchain_colorspace'
00:00:00.028 [E] vulkan.c:1130 | vulkan_createInstance | Failed to create Vulkan instance (VkResult: -6)
00:00:00.028 [E] main.c:176 | renderThread | Renderer failed to start
00:00:00.121 [I] channel.c:269 | channel_internal_disconnect | INPUTS channel disconnected
00:00:00.121 [I] channel.c:269 | channel_internal_disconnect | MAIN channel disconnected
00:00:00.121 [I] ps.c:330 | purespice_disconnect | Disconnected
Having issues that @Tony763 having with a window, but in my case I can force size of it in the client settings, and it's usable with sway
The primary motivation for this change is to bring true HDR support to Looking Glass, which is not currently possible via EGL
Isn't that unnecessary while using Wayland's recent color management protocol? I spun off a barebones fork of LG making use of it, with the help also from your HDR16to10 bits on the host. Does seem to work, at least from the naked eye, the colors on youtube HDR videos through Microsoft Edge do look like they match what I'm seeing on the lastest FIrefox Beta (141), which does also implement HDR.