Skip to content

docs(adr): ADR-044 — the colour contract, per backend and swapchain format - #1761

Merged
dfattal merged 1 commit into
mainfrom
docs/adr-044-colour-contract
Sep 29, 2026
Merged

dfattal merged 1 commit into
mainfrom
docs/adr-044-colour-contract

Conversation

@dfattal

@dfattal dfattal commented Sep 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

The rule. The swapchain's format says what its bytes mean, and the runtime believes it:

  • _SRGB holds encoded colour;
  • UNORM and float hold linear values, and the runtime sRGB-encodes them.

This is OpenXR's rule, and the CTS judges it (GradientFormatsLinearVsNonLinear, SourceAlphaBlending*, #1589/#1610). Every native compositor except Metal has followed it since v2.21.0–v2.21.7.

The app rule: write encoded colour into _SRGB or linear into UNORM; prefer _SRGB, and make the choice the same way on every platform leg.

This PR adds ADR-044, which puts that into one table and amends ADR-021.

What ADR-044 contains

Also in this PR

  • ADR-021 gets an "amended by" note. Its principles stand. "Model A" now means "the atlas is encoded", not "UNORM passes through".
  • Pointers to ADR-044 from INV-4.6 and from compositor-pipeline.md.
  • The ADR index is regenerated.

Why now

On 2026-09-28 the demos were washed out:

  • every demo's Android leg, on the tablet running runtime v2.21.11;
  • avatar on macOS.

Each of those legs picked UNORM and wrote display-referred bytes, which v2.21.7+ encodes a second time. Fixed app-side in:

The guide text and per-leg linter fix is #1760 (separate PR, independent of this one).

Checks run locally

  • gen_adr_index.py --check: OK.
  • check_doc_paths.py: 894 links, OK.

Docs-only, so CI short-circuits.

🤖 Generated with Claude Code

…ormat

One table for what #1589/#1610 shipped across D3D11, the D3D11 service,
D3D12, GL, vk_native (Windows / Linux / macOS-MoltenVK / Android) and Metal:

- what each backend enumerates, in order;
- what it does with an _SRGB vs a UNORM/float swapchain;
- where layers blend;
- what the DP receives;
- which CTS test pins each row.

It also records the rows that are NOT CTS-covered (vk_native on macOS and
Android, Metal) and what guards them instead. The app rule fits in one line:
write encoded colour into _SRGB, or linear into UNORM; prefer _SRGB, the same
way on every leg.

Amends ADR-021 (principles unchanged). Its "Model A" now reads as "the atlas
is encoded", not "UNORM passes through". Pointers added from ADR-021, INV-4.6
and compositor-pipeline.md. Open rows are recorded, not fixed:

- Metal is still pre-#1589 passthrough;
- the IPC comp_multi paths are unaudited;
- the displayxr-common Windows HUD swapchain is UNORM with display-referred
  bytes.

Motivated by the 2026-09-28 washed-out demos: every demo's Android leg, plus
avatar's macOS/Linux legs, picked UNORM and wrote display-referred bytes.
Fixed app-side in gauss#138, avatar#113, earthview#76, modelviewer#154 and
mediaplayer#89. The per-leg lint is in #1760.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dfattal
dfattal requested a review from a team as a code owner September 28, 2026 21:30
@dfattal
dfattal merged commit 483a2a7 into main Sep 29, 2026
34 checks passed
@dfattal
dfattal deleted the docs/adr-044-colour-contract branch September 29, 2026 00:00
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