fix(vk): Linux/Wayland: take an sRGB surface format for the swapchain (#679 rebased) #1086
No reviewers
Labels
No labels
accessibility
autorelease: pending
autorelease: tagged
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
question
testing wanted
wontfix
No milestone
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Hookshot!1086
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/swapchain-srgb-rebase"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
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 lastB8G8R8A8_UNORM/R8G8B8A8_UNORMsurface format, whatever its colour space. It now only takesVK_COLOR_SPACE_SRGB_NONLINEAR_KHRentries.Why
Mesa's Wayland WSI (
src/vulkan/wsi/wsi_common_wayland.c,wsi_wl_display_determine_colorspacesandwsi_wl_surface_get_formatson Mesa main) returns every format once per colour space:SRGB_NONLINEAR_KHRfirst, thenPASS_THROUGH_EXT(always), then, when the compositor haswp_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 bytests/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
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.
Thanks @t0masz407, that's the AMD + Wayland confirmation this needed, and the fix is yours. (AI-assisted reply via Claude Code on my behalf.)
Looks good. Only nits, nothing blocking.
The format stays B8G8R8A8/R8G8B8A8_UNORM and only the colour space is filtered, so nothing changes for the present path: the swapchain is still TRANSFER_DST (plus SRC when allowed) and written by copy/blit, so there is no gamma change, no re-encode on write and no STORAGE-usage question. Where a driver lists only SRGB_NONLINEAR entries (NVIDIA, X11, Windows) the chosen entry is the same as before, since it is still the last match. If no UNORM/sRGB entry exists it falls back to formats[0], as it did. The test is picked up by run_all's glob, and it correctly drops the
breakexpectation from #679. Context: this supersedes #1103 (same fix, first-match withbreak), which was closed in favour of this one.One caveat: I haven't run it on AMD + Wayland. It would be good to get a confirmation in #1042 before or soon after merge.
@ -417,2 +417,3 @@for (const auto& f : formats) // (an UNORM target: the game's window textures are presented as they are)if (f.format == VK_FORMAT_B8G8R8A8_UNORM || f.format == VK_FORMAT_R8G8B8A8_UNORM) fmt = f;// (in sRGB: RADV on Wayland lists every format again with PASS_THROUGH_EXT and the compositor's colour spaces,// and the last UNORM entry left the compositor an untagged surface, a grey picture. Still the last sRGB one, soNit: the new comment says "in sRGB:" and sits right below the old "an UNORM target" comment, so it reads a bit tangled. Also the format is still UNORM here, only the colour space is sRGB_NONLINEAR (same for the PR title). Maybe: "(UNORM format, SRGB_NONLINEAR colour space: ...)".
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.)
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_UNORMin colour space1000104011(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) givesB8G8R8A8_UNORM/SRGB_NONLINEARand 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.