Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Vulkan renderer #1163

Open
wants to merge 38 commits into
base: master
Choose a base branch
from
Open

Add Vulkan renderer #1163

wants to merge 38 commits into from

Conversation

spencercw
Copy link
Contributor

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)
  • Run looking-glass-client with the environment variable ENABLE_HDR_WSI=1 to 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-client with the environment variable AMD_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.

Footnotes

  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

Currently, the sRGB cursor image is rendered directly into the framebuffer,
resulting in the cursor not matching the host white level when using HDR.

The fixed-function blending capabilities are not really adequate for our
purposes when using HDR. For standard color cursors it could work if we
converted the entire framebuffer from non-linear RGBA10 to linear RGBA16,
but that still doesn't help us with the other cursor types which require
the ability to invert a pixel with reference to the current SDR white
level.

To work around this, add a subpass self-dependency and attach the swapchain
image to the renderpass as both a color attachment and an input attachment.
This allows us to first render the desktop into the color attachment, add a
pipeline barrier to make the changes visible, then render the cursor, where
we can read the rendered desktop image from the input attachment to
manually blend it with the cursor.
The current logic simply adjusts for the SDR white level, so any true HDR
content is lost. Use perceptual quantization so HDR content can be
correctly rendered on the client.
Currently, the sRGB cursor image is rendered directly into the framebuffer,
resulting in the cursor not matching the host white level when using HDR.

The fixed-function blending capabilities are not really adequate for our
purposes when using HDR. For standard color cursors it could work if we
converted the entire framebuffer from non-linear RGBA10 to linear RGBA16,
but that still doesn't help us with the other cursor types which require
the ability to invert a pixel with reference to the current SDR white
level.

To work around this, add a subpass self-dependency and attach the swapchain
image to the renderpass as both a color attachment and an input attachment.
This allows us to first render the desktop into the color attachment, add a
pipeline barrier to make the changes visible, then render the cursor, where
we can read the rendered desktop image from the input attachment to
manually blend it with the cursor.
ImGui is rendered assuming a standard SDR sRGB output, so it looks very bad
when rendered into an HDR surface. Instead, render into an SDR surface,
then manually blend the result into the output HDR surface while performing
the necessary color space conversions.
The Vulkan present operation can currently be interrupted by the Wayland
pointer handling code if it issues a commit at the same time, resulting in
a protocol error.
This may be useful for diagnosing driver-related issues. For instance, the
Wayland HDR Vulkan layer does not work with AMDVLK, but it does work with
RADV.
This fixes a crash with the Intel driver when switching swapchain surface
formats.
This avoids a potential race with the invocation of onFrameFormat on the
frame thread.
@Vityacv
Copy link

Vityacv commented Feb 22, 2025

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 Vityacv mentioned this pull request Feb 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants