Skip to content

#1795: window-space + macOS decorations blend in linear light, sampled as declared (ADR-044 §7) - #1799

Merged
dfattal merged 3 commits into
mainfrom
fix/1795-format-honest-blends
Oct 2, 2026
Merged

dfattal merged 3 commits into
mainfrom
fix/1795-format-honest-blends

Conversation

@dfattal

@dfattal dfattal commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes the window-space half of #1795 (ADR-044 §7). Draft until the macOS test in the tmp-adr044-mac-colour channel passes. The release containing this is v2.23.0 and must ship together with displayxr-shell-pvt#121.

Changes

  • vk_hud_blend: source views are cached per (image, format), and the new vk_hud_blend_draw_no_layout_fmt() samples a source as a given format. Existing callers keep the legacy R8G8B8A8_UNORM view.
  • vk_native (in-process): window-space layers now composite in linear light.
    • The pass raw-copies the atlas into the private compose target (UNORM + MUTABLE, _SRGB view), blends each layer through that view with the source read as its declared format, then raw-copies back.
    • Cost: two atlas copies, only on frames with window-space layers.
    • Falls back to the encoded path under the legacy hatch or if anything can't be created.
  • comp_multi (macOS service): workspace decorations (shell chrome, cursor, overlays) render into the shared atlas through an _SRGB view of the now-MUTABLE atlas, sampled as declared.
    • Also adds the atlas's missing COLOR_ATTACHMENT usage.
    • Linux registers no workspace surfaces, so it has no such site.
  • ADR-044 §7: rows updated.

Measured (win box, in-process vk_native, dev runtime)

probe _SRGB UNORM
windowspace_handle_vk_win (opaque byte 38) 38 108 (one encode), was 38
cube_handle_vk_win HUD 50% backdrop over (13,13,64) (7,7,45), byte-identical to D3D11 —

The hard-coded view's R/B swap for B8G8R8A8 sources goes away with this change.

Ordering / compatibility

Not yet verified

  • macOS compile, and macOS pixels for the comp_multi path (test recipe posted in the channel).
  • An unmeasured inference to check there: on the macOS content pass, _SRGB clients may render too dark (decoded into the UNORM atlas, never re-encoded). Not changed here.

🤖 Generated with Claude Code

dfattal and others added 3 commits October 2, 2026 15:48
…d as declared (#1795)

vk_hud_blend sampled every window-space source through a hard-coded
R8G8B8A8_UNORM view and blended into the encoded atlas, so the layer's
declared format was ignored (37 and 43 gave byte-identical atlases) and a
B8G8R8A8 source would have been read with R and B swapped.

- vk_hud_blend: views cached per (image, format); new
  vk_hud_blend_draw_no_layout_fmt() samples the source as a given format.
  Existing callers keep the legacy view.
- vk_native: the window-space pass raw-copies the atlas into the private
  compose target (UNORM + MUTABLE, _SRGB view), blends each layer through
  that view with the source read as its declared format, and raw-copies
  back. Two atlas copies, only on frames with window-space layers. Falls
  back to the encoded path under the legacy hatch or if anything cannot be
  created.

Measured on the win box (windowspace_handle_vk_win, opaque byte 38):
_SRGB 38, UNORM 108 (one encode) - now identical to D3D11/D3D12/GL. The
cube_handle_vk_win HUD's 50% backdrop lands at (7,7,45), byte-identical to
D3D11. The comp_multi (macOS/Linux service) blends are the next step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ampled as declared (#1795)

The workspace chrome/cursor/overlay decorations on the macOS shared surface
were sampled through vk_hud_blend's hard-coded R8G8B8A8_UNORM view (illegal
on a non-mutable _SRGB/BGRA image) and blended into the encoded atlas, so a
surface's declared format was ignored. The atlas is now created
MUTABLE_FORMAT with its _SRGB sibling; decorations render through that view
with each source read as its declared format. Legacy hatch / any creation
failure keeps the old path (sticky, one WARN). Also adds the atlas's missing
COLOR_ATTACHMENT usage.

ORDERING: the macOS shell submits UNORM display-referred bytes today and
must move to _SRGB (displayxr-shell-pvt#121) in the same release.
Linux registers no workspace surfaces, so it has no such site.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…1795)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dfattal
dfattal marked this pull request as ready for review October 2, 2026 23:58
@dfattal
dfattal requested a review from a team as a code owner October 2, 2026 23:58
@dfattal
dfattal merged commit 8212f5e into main Oct 2, 2026
40 checks passed
@dfattal
dfattal deleted the fix/1795-format-honest-blends branch October 2, 2026 23:58
dfattal added a commit that referenced this pull request Oct 3, 2026
…clared (#1795)

The over-flatten and the 2D-under backdrop flatten sampled every Local2D
layer through the non-decoding view into a UNORM scratch, so the declared
format was ignored (a true-linear UNORM layer rendered too dark).

Both scratches are now B8G8R8A8_UNORM + MUTABLE_FORMAT with a
{UNORM,_SRGB} format list (the #1799 compose-target shape): the UNORM
view is what every reader samples, so they still see ENCODED bytes, and
the flatten renders through an _SRGB view with a second flatten render
pass + pipeline pair (vk_local2d_composite_init_srgb_flatten, opt-in, so
the Linux/macOS/Android multi-compositor callers are unchanged). The
source view follows the target: format-honest (true view) into an _SRGB
attachment, non-decoding into a UNORM one. The legacy hatch never builds
the _SRGB pipelines and keeps the old path exactly; so does the
weave-on-scanout split, whose bridge planes are typed-UNORM D3D11
textures.

Measured (hardware A/B pending): cube_handle_vk_win, DXR_LOCAL2D_PANEL=1,
opaque checker authored 40/235 -- expect _SRGB panel 40/235; UNORM panel
110/246 (one encode); UNORM under DXR_COLOR_LEGACY_UNORM_ENCODED=1 40/235.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dfattal added a commit that referenced this pull request Oct 3, 2026
…clared (#1795)

The over-flatten and the 2D-under backdrop flatten sampled every Local2D
layer through the non-decoding view into a UNORM scratch, so the declared
format was ignored (a true-linear UNORM layer rendered too dark).

Both scratches are now B8G8R8A8_UNORM + MUTABLE_FORMAT with a
{UNORM,_SRGB} format list (the #1799 compose-target shape): the UNORM
view is what every reader samples, so they still see ENCODED bytes, and
the flatten renders through an _SRGB view with a second flatten render
pass + pipeline pair (vk_local2d_composite_init_srgb_flatten, opt-in, so
the Linux/macOS/Android multi-compositor callers are unchanged). The
source view follows the target: format-honest (true view) into an _SRGB
attachment, non-decoding into a UNORM one. The legacy hatch never builds
the _SRGB pipelines and keeps the old path exactly; so does the
weave-on-scanout split, whose bridge planes are typed-UNORM D3D11
textures.

Measured (hardware A/B pending): cube_handle_vk_win, DXR_LOCAL2D_PANEL=1,
opaque checker authored 40/235 -- expect _SRGB panel 40/235; UNORM panel
110/246 (one encode); UNORM under DXR_COLOR_LEGACY_UNORM_ENCODED=1 40/235.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant