Repository navigation
fix(#347): _SRGB swapchains on format-honest runtimes — colour no longer washed out - #348
Conversation
…ur isn't washed out Since runtime v2.21.0 (D3D11), v2.21.1 (D3D12) and v2.21.7 (Vulkan) the runtime believes the swapchain format (ADR-044 / INV-4.6, pinned by the Khronos CTS): an _SRGB swapchain holds encoded colour, and a UNORM one holds LINEAR values that it sRGB-encodes on the way to the panel. The plugin put encoded bytes into UNORM swapchains (the primary layer of every Gamma project, plus every wsui/Local2D canvas and the Gamma extra zones), so they were encoded twice and looked washed out. On a format-honest runtime (version from xrGetInstanceProperties, per graphics API; off under the runtime's own DXR_COLOR_LEGACY_UNORM_ENCODED=1 hatch): - Primary: _SRGB in both colour spaces. What Unity renders into is split from the swapchain format: a Linear project keeps encoding on store; a Gamma project renders into the UNORM sibling and the existing raw copy (CopyResource / CopyTextureRegion / vkCmdCopyImage) moves the encoded bytes into the _SRGB image unchanged. - wsui / Local2D (D3D11, D3D12, Vulkan): the _SRGB sibling; bridges stay UNORM. - Extra 3D zones (D3D, Gamma projects): the _SRGB sibling. Metal is not format-honest yet (ADR-044 section 7) and older runtimes keep the previous formats, byte for byte. Also refreshes the Windows x64 DLL, which predated #337/#339/#341. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Linux/Vulkan results on the DS1 (Ubuntu 26.04, RTX 4090 Laptop, lenovo-avatar, installed runtime v2.21.11): As-is, #348 doesn't engage on Linux. The Linux runtime reports The runtime itself is format-honest ( With the version read correctly, the fix works. For the test I added a fallback that parses the
Suggestion: keep a fallback like this in #348. Every Linux runtime shipped so far reports 1.6.0, so even with #1790 fixed, apps on today's // Linux runtimes report runtimeVersion 1.6.0 (displayxr-runtime#1790): fall back to
// the 'vX.Y.Z' tag in runtimeName.
if (XR_VERSION_MAJOR(s_runtime_version) < 2) {
const char *q = strstr(ip.runtimeName, "'v");
unsigned a = 0, b = 0, c = 0;
if (q && sscanf(q + 2, "%u.%u.%u", &a, &b, &c) == 3)
s_runtime_version = XR_MAKE_VERSION(a, b, c);
}🤖 Generated with Claude Code |
…ion is 1.x (Linux) Every Linux runtime shipped so far reports runtimeVersion 1.6.0 (DisplayXR/displayxr-runtime#1790), so the format-honest gate never engaged on Linux and apps stayed washed out. Fall back to the 'vX.Y.Z' tag in runtimeName when the major is < 2. Verified by Byungju on the DS1 (Ubuntu, RTX 4090, runtime v2.21.11): _SRGB swapchains (43 primary, 50 wsui/Local2D), raw bridge copies, no errors, and correct colour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks @byungjul, great catch. Your |
…from the merged source Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
Fixes #347. On runtime ≥ v2.21 every Gamma-project Unity app, and every window-space UI / Local2D canvas, looked washed out on the panel. Seen on the Windows Leia panel with lenovo-avatar.
The runtime is right. Since v2.21.0 it follows OpenXR's format rule, which the CTS checks (ADR-044, INV-4.6): an
_SRGBswapchain holds encoded colour, and a UNORM one holds linear values that the runtime encodes. The plugin was putting encoded bytes into UNORM swapchains, so they were encoded twice.What changes
When it applies: only on a format-honest runtime. That is
runtimeVersion(fromxrGetInstanceProperties) ≥ 2.21.0 on D3D11, 2.21.1 on D3D12, or 2.21.7 on Vulkan, and the runtime's ownDXR_COLOR_LEGACY_UNORM_ENCODED=1hatch is not set._SRGB, Unity encodes on store_SRGBswapchain. Unity renders into the UNORM sibling (s_unity_format), and the existing raw copy (CopyResource/CopyTextureRegion/vkCmdCopyImage) moves the bytes in unchanged_SRGBsibling. Bridges stay UNORM; the copies are raw_SRGBsibling (Linear projects are unchanged; their zone targets aren't sRGB-flagged)dxr_prov_swapchain_is_srgb(), which driveskUnityXRRenderTextureFlagsSRGB, now means "Unity encodes on store". It no longer means "the swapchain is sRGB": a Gamma project has an_SRGBswapchain but must not encode.This PR also refreshes the Windows x64 DLL. The committed one predated #337/#339/#341.
Testing
Windows, Leia panel, installed runtime v2.22.0, lenovo-avatar (Gamma, URP) player with this DLL, D3D12:
No
xrEndFrameerrors and no WARN lines.Still to do before merge:
Not in scope (app side, from the ADR-044 audit): lenovo's separate native Vulkan app (
native-vk~) creates its own UNORM swapchains and needs the displayxr-common ≥ v2.15.0 bump plus_SRGBwindow-space swapchains.Known residual: a Gamma project blends its canvas in encoded space, while the runtime now blends layers in linear light, so semi-transparent HUD pixels come out slightly lighter. Opaque UI is exact.
🤖 Generated with Claude Code