Skip to content

fix(vk): Linux/Wayland: take an sRGB surface format for the swapchain (#679 rebased) - #1086

Merged
hckrman101 merged 2 commits into
NotRexed:mainfrom
metroid98:fix/swapchain-srgb-rebase
Nov 9, 2026
Merged

hckrman101 merged 2 commits into
NotRexed:mainfrom
metroid98:fix/swapchain-srgb-rebase

Conversation

@metroid98

Copy link
Copy Markdown

What

This is @t0masz407's #679 rebased onto current main, so that #1042 gets its fix. #679 was closed only because it conflicted ("please rebase on current main and reopen"), and it hasn't been reopened since. Tom's commit is kept as his own, with one small commit on top.

create_swapchain (gpu/vk/vk_main.cpp) kept the last B8G8R8A8_UNORM / R8G8B8A8_UNORM surface format, whatever its colour space. It now only takes VK_COLOR_SPACE_SRGB_NONLINEAR_KHR entries.

Why

Mesa's Wayland WSI (src/vulkan/wsi/wsi_common_wayland.c, wsi_wl_display_determine_colorspaces and wsi_wl_surface_get_formats on Mesa main) returns every format once per colour space: SRGB_NONLINEAR_KHR first, then PASS_THROUGH_EXT (always), then, when the compositor has wp_color_manager_v1 (KWin, Hyprland, ...), every colour space it can map. The last UNORM entry is therefore never sRGB on RADV + Wayland, and the compositor shows the picture unmanaged: the grey, washed-out image in #1042. That issue now has three reports, all AMD + Wayland: RX 6600, RX 9070 XT on Arch, RX 9070 XT on CachyOS. X11 and NVIDIA list only sRGB entries. On an RTX 3060 under KDE Wayland it does not reproduce (my data point in #1042).

Change from #679

#679 took the first sRGB match (break). The second commit keeps the old last-match rule, restricted to sRGB entries. On drivers that list only sRGB entries (NVIDIA, X11/XWayland, Windows), the chosen format is then exactly the one it is today, even when a driver lists both B8G8R8A8 and R8G8B8A8. The test (tests/test_swapchain_colorspace.py, picked up by tests/run_all.py, so the workflow edit from #679 is no longer needed) now checks for the sRGB condition and that the loop does not stop at the first match.

Testing

Tom tested the original on an RX 7900 XTX (RADV, Mesa 26.2.6, Hyprland HDR), see #679. I have no AMD card to test the rebase on, and I didn't build or run it locally: the conflict was only the neighbouring present-mode code, which keeps main's version. A test from someone on AMD + Wayland in #1042 would confirm it.

Fixes #1042

AI-assisted (Claude Code) on behalf of metroid98: rebase, Mesa source check and write-up; not run locally.

🤖 Generated with Claude Code

https://claude.ai/code/session_015DmSMGJSY9hHswALy4eqtQ

t0masz407 and others added 2 commits November 9, 2026 23:37
RADV's Wayland WSI lists every surface format twice, first in SRGB_NONLINEAR_KHR and then in
COLOR_SPACE_PASS_THROUGH_EXT. The loop kept the last B8G8R8A8/R8G8B8A8_UNORM entry, so with
SDL_VIDEODRIVER=wayland the swapchain was R8G8B8A8_UNORM in PASS_THROUGH_EXT and the compositor showed
the picture without colour management: grey on an HDR desktop (Hyprland 0.56). X11/XWayland and
Windows list only sRGB entries, which is why it did not show there.

The first UNORM entry in SRGB_NONLINEAR_KHR is taken now. Tested on an RX 7900 XTX (RADV, Mesa 26.2.6),
Kokiri Forest: native Wayland shows the same colours as XWayland, and its present is cheaper
(5.8 ms against 8.0 ms a frame). tests/test_swapchain_colorspace.py checks the choice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013mj4MgED5gai2jdByd6ztp
…t only sRGB keep theirs

On top of the rebased NotRexed#679: the loop still takes the last matching UNORM entry, now only among
SRGB_NONLINEAR_KHR ones, instead of stopping at the first. NVIDIA, X11 and Windows list only sRGB
entries, so they keep exactly the format they had; RADV on Wayland gets an sRGB one instead of
PASS_THROUGH_EXT or a compositor colour space.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015DmSMGJSY9hHswALy4eqtQ
@t0masz407

Copy link
Copy Markdown
Contributor

Tested on AMD: RX 7900 XTX, RADV (Mesa 26.2.6), Hyprland 0.56 with an HDR desktop (wp_color_manager_v1), native Wayland (SDL_VIDEODRIVER=wayland). The build is v2.0.7 plus both commits of this PR. Colours are normal, the same as on XWayland. Without the fix the picture is grey, as in #1042. The last-match rule is a good change, thanks for picking this up. I'll close my duplicate #1103 in favour of this one.

@metroid98

Copy link
Copy Markdown
Author

Thanks @t0masz407, that's the AMD + Wayland confirmation this needed, and the fix is yours. (AI-assisted reply via Claude Code on my behalf.)

@metroid98

Copy link
Copy Markdown
Author

Thanks for the review. On the AMD + Wayland caveat: @t0masz407 tested this PR (both commits on v2.0.7) on an RX 7900 XTX / RADV Mesa 26.2.6 / Hyprland HDR with native Wayland, in the comment above: colours were normal, grey without the fix. (AI-assisted via Claude Code on my behalf.)

@BiasedMonkey

Copy link
Copy Markdown

Confirmed on AMD + Wayland: RX 7700S (RADV NAVI33), Mesa 26.2.6, CachyOS, KDE Plasma Wayland (EDID colour management). On v2.0.11 the swapchain came out as R8G8B8A8_UNORM in colour space 1000104011 (ADOBERGB_LINEAR_EXT, the last of 90 pairs Mesa offered), and the picture was washed out: a readback of the swapchain image matched the game's own picture byte for byte, but on screen every value was lifted (17 -> 58, 46 -> 100, 102 -> 163, a second encode by KWin). The same change applied to v2.0.11 (sRGB colour spaces only) gives B8G8R8A8_UNORM / SRGB_NONLINEAR and the picture is right, on the title movie and in gameplay.

AI-assisted (Claude Code) on behalf of the reporter; tested by them on the machine above.

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.

Wayland weird color and line on video cutscene

3 participants