Repository navigation
fix(test-apps): D3D12 cubes decode authored colour for an _SRGB RTV; GL macOS cubes prefer GL_SRGB8_ALPHA8 (ADR-044, #1882) - #1885
Merged
Conversation
…ADR-044, #1882) cube_handle_d3d12_win asks for an _SRGB swapchain (displayxr-common default since v2.15.0) and creates its RTVs + PSOs typed _SRGB, but its pixel shaders wrote the authored display-referred colours raw, so the render target encoded them a second time: washed out on the rig while the D3D11 cube (which has had the DXR_LINEARIZE PS variant since #1589) looked right. The D3D12 copy of the renderer only ever got the display-referred clear (#1679). - d3d12_renderer.cpp (handle; copied verbatim into cube_zones_d3d12_win and cube_zones_texture_d3d12_win; shared by cube_hosted_legacy_d3d12_win): both pixel shaders gain the same DXR_LINEARIZE decode as the D3D11 reference renderer; CompileShader takes a `linearize` flag; the variant is chosen in CreateSwapchainRTVs, the first point where the RTV format is known, keyed on THAT format (not the process-wide dxr::RenderSceneLinear(), for the #1647 reason: the legacy D3D12 app resolves TYPELESS to the UNORM sibling and writes raw bytes, which must keep the raw variant). DXR_TRUE_LINEAR still overrides. One WARN line `[color] rtvFormat=.. sceneLinear=..` at init, the same discriminator the VK cubes log. - cube_hosted_legacy_d3d12_win: the comment describing the UNORM RTV still described the pre-#1589 runtime; it now states the ADR-044 row it sits on. - cube_handle_gl_win: the stale "may need glEnable(GL_FRAMEBUFFER_SRGB)" TODO is replaced by the actual contract (it stays off: raw display-referred bytes into an honestly-declared GL_SRGB8_ALPHA8 swapchain); the DXR_TEST_QUAD swapchain declares its raw bytes GL_SRGB8_ALPHA8 like the Local2D panels. - cube_handle_gl_macos, cube_hosted_legacy_gl_macos: preferred GL_RGBA8 and wrote display-referred bytes, i.e. the exact washed-out shape ADR-044 §2 describes on the format-honest GL compositor (>= v2.21.2); they now prefer GL_SRGB8_ALPHA8 with GL_RGBA8 as the fallback. cube_zones_texture_gl_macos already preferred sRGB; its hex literals become the named GL codes so the per-leg INV-4.6 lint judges it on tokens. - cube_zones_texture_vk_win: the strip/zone fallback format is the _SRGB sibling, not UNORM. Audit of the rest of the fleet: every D3D11 cube (shared displayxr-common renderer), every VK cube (uLinearize specialisation constant) and the GL Windows cubes were already on the contract. The Metal cubes keep BGRA8Unorm + raw bytes on purpose: Metal is the one backend ADR-044 §7 lists as not format-honest (UNORM passthrough), so they are correct there today and their migration (sRGB pipeline format + shader decode) is a macOS-verified change of its own. scripts/check_displayxr_app.py: 0 INV-4.6 findings on every cube app. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Collaborator
Author
|
Rig verification (2026-10-09, win box, installed runtime main after #1879 + Leia plug-in #323 build):
(13,13,64) is the authored 0.05/0.05/0.25 clear in display-referred bytes, i.e. the atlas holds exactly the authored colour once (ADR-044 §5). Before the fix the D3D12 cube stored one encode too many (the #1647 measurement of the same clear was 63,63,137). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1882.
What
cube_handle_d3d12_winwas washed out on the rig whilecube_handle_d3d11_winlooked right on the same runtime, plug-in and panels. The app asks for an_SRGBswapchain and creates_SRGB-typed RTVs/PSOs, but its pixel shaders wrote the authored display-referred colours raw, so the render target encoded them a second time. The D3D11 cube has had theDXR_LINEARIZEpixel-shader variant since #1589; the D3D12 copy of the renderer only ever received the display-referred clear (#1679).Changes
d3d12_renderer.cpp(handle; verbatim copies incube_zones_d3d12_winandcube_zones_texture_d3d12_win; shared bycube_hosted_legacy_d3d12_win): both pixel shaders gain the sameDXR_LINEARIZEdecode as the D3D11 reference renderer. The variant is chosen inCreateSwapchainRTVs, the first point where the RTV format is known, and is keyed on that format rather than the process-widedxr::RenderSceneLinear()flag (the test_apps: D3D12 (and macOS/Linux) apps need a display-referred clear before they get honest _SRGB swapchains; stale per-app displayxr-common pins #1647 lesson: the legacy D3D12 app resolves TYPELESS to the UNORM sibling and writes raw bytes, so it must keep the raw variant while the handle app's_SRGBRTV gets the decoding one; both store the same bytes).DXR_TRUE_LINEARstill overrides. One[color] rtvFormat=.. sceneLinear=..WARN at init, the same discriminator the VK cubes log.cube_hosted_legacy_d3d12_win: the comment on the UNORM RTV described the pre-CTS composition: UNORM (linear) swapchains are passed through un-encoded on every backend — GradientFormatsLinearVsNonLinear FAIL; ADR-021 Model A vs OpenXR format semantics #1589 runtime; it now states the ADR-044 row it sits on.cube_handle_gl_win: the stale "may needglEnable(GL_FRAMEBUFFER_SRGB)" TODO is replaced by the actual contract (it stays off: raw display-referred bytes into an honestly-declaredGL_SRGB8_ALPHA8swapchain). TheDXR_TEST_QUADswapchain declares its raw bytesGL_SRGB8_ALPHA8like the Local2D panels already do.cube_handle_gl_macos,cube_hosted_legacy_gl_macos: preferredGL_RGBA8and wrote display-referred bytes, the exact washed-out shape ADR-044 §2 describes on the format-honest GL compositor (≥ v2.21.2). They now preferGL_SRGB8_ALPHA8,GL_RGBA8as the fallback.cube_zones_texture_gl_macosalready preferred sRGB; its hex literals become the named codes so the per-leg INV-4.6 lint judges it on tokens.cube_zones_texture_vk_win: the strip/zone fallback format is the_SRGBsibling, not UNORM.Fleet audit (ADR-044 / INV-4.6)
DXR_LINEARIZE+ display-referred clears)uLinearizespecialisation constant,_SRGBfirst)_SRGBswapchain,GL_FRAMEBUFFER_SRGBoff, raw bytes)BGRA8Unorm+ raw bytes is correct there today. Migrating them (sRGB pipeline format + shader decode + linearised clears) is a macOS-verified change of its own.scripts/check_displayxr_app.py: 0 INV-4.6 findings on every cube app (the remaining INV-5.9 errors on the VK enable1 apps are pre-existing and out of scope).Verification
scripts\build_windows.bat test-apps: green, every touched executable rebuilt.displayxr_atlas_trigger.projectioncapture of the D3D12 cube vs the D3D11 cube, same authored scene → same atlas bytes) and David's eyeball follow before merge.🤖 Generated with Claude Code