docs(render): S4 packet draft — what S3 already delivered, the alpha-list cutover, open questions
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
e33fd24724
commit
ac1b7afeb7
1 changed files with 137 additions and 0 deletions
137
docs/research/2026-09-01-overhaul/s4-depth-alpha-packet.md
Normal file
137
docs/research/2026-09-01-overhaul/s4-depth-alpha-packet.md
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
# S4 packet — depth and alpha: what S3 already delivered, what remains (lead draft, 2026-09-03 evening)
|
||||||
|
|
||||||
|
**Status:** DRAFT written while the S3 post-hoc lenses ran; NOT dispatchable
|
||||||
|
until the S3 review closes (plan §9 order: S3 review → G3 → S4). Every owner
|
||||||
|
named below is re-located at chunk time; names, not line numbers.
|
||||||
|
|
||||||
|
Specs: `oh1-depth-lifecycle.md`, `oh1-alpha-list-contract.md`; the plan's §9 S4
|
||||||
|
section; the §7 alpha/depth captures under `oh-capture/` (`*.alphadepth.log`,
|
||||||
|
line formats in `tools/walk-oracle/oh/oh-capture-alphadepth.cdb.template`).
|
||||||
|
|
||||||
|
## 1. What S3 already delivered of S4's chunk 1
|
||||||
|
|
||||||
|
S3 chunk 2 (§8 of the S3 packet, landed `be9b4c1f` + `434a7df2`) implemented
|
||||||
|
the S4 chunk-1 scope almost whole, because the walk could not be exact without
|
||||||
|
it:
|
||||||
|
|
||||||
|
| S4 chunk-1 item (plan §9) | State after S3 | Where |
|
||||||
|
|---|---|---|
|
||||||
|
| one frame-persistent latch owner for `portalsDrawnCount` | DONE — `WalkFrameDriver.PortalsDrawnCount`, retained across frames, never cleared by Begin/Abort/EndFrame | S3 §8.2 B2 |
|
||||||
|
| landscape → flush → stamp → clear → seal block gated exactly as retail (`outside_view.view_count > 0`) | DONE — `OnInteriorFloodDrawTurn(cells, outsideViewCount)`; `LandscapeFlush` leaf; stamp advance; clear ONLY IF count ≠ 0 (read-then-zero); seals | S3 §8.2 B1/B3 |
|
||||||
|
| `WalkFrameDriver`'s unconditional interior clear deleted | DONE | S3 §8.2 B1 |
|
||||||
|
| mid-frame stamp placed exactly (0x005a4886) | DONE (`AdvanceWalkPartPassStamp` at the flush leaf) | S3 §8.2 B1 |
|
||||||
|
| exit seals from the exact current views and cell order, counted by the seal leaf's return value | DONE — `DrawExitSeals` returns the submitted count; punch fans never count | S3 §8.2 B2 |
|
||||||
|
| look-ins cannot touch the root latch | DONE (look-in `DrawCells` never increments) | S3 §8.2 B2 |
|
||||||
|
| truth-table tests over root kind / draw_landscape / outside-view count / previous-current portal count | PARTIAL — the chunk-2 tests flipped the two wrong contracts (§8.3); the full truth table and the two-consecutive-frames latch test are NOT yet one theory | S4-c1 below |
|
||||||
|
|
||||||
|
The depth-lifecycle spec's "Current acdream correspondence" table (its rows
|
||||||
|
marked **missing** / **wrong** for the counter, the gate and the test
|
||||||
|
contracts) is therefore stale for those rows; the rows that still stand are
|
||||||
|
the three below.
|
||||||
|
|
||||||
|
## 2. What remains for S4 chunk 1 (S4-c1, small)
|
||||||
|
|
||||||
|
- **Far-punch depth constant.** Retail writes the far-Z punch at the exact
|
||||||
|
bits `0x3F7FFFEF`; `portal_depth.vert` uses the decimal `0.99999988`. The
|
||||||
|
chunk decides by TEST, not by eye: a pin that reinterprets `0.99999988f` and
|
||||||
|
asserts `BitConverter.SingleToInt32Bits == 0x3F7FFFEF`; if they differ, the
|
||||||
|
shader takes the hex literal (`uintBitsToFloat(0x3F7FFFEFu)`) and the
|
||||||
|
manifest hash is re-pinned. (1 − 2⁻²³ is the expected identity; prove it.)
|
||||||
|
- **The ±12 local-input reject.** Ghidra arbitration (S3 packet §2, the
|
||||||
|
"±12 test is an equality degenerate guard") says the check rejects a
|
||||||
|
whole polygon whose local x/y equals ±12 exactly — a degenerate-input
|
||||||
|
guard, not a clip rule. Port it at the punch-event producer as an
|
||||||
|
equality test on the LOCAL polygon before transform, with a test that
|
||||||
|
feeds one exact ±12 vertex polygon and one at ±11.999 (only the first is
|
||||||
|
rejected). If the arbitration table shows the branch can never fire for a
|
||||||
|
real DAT polygon, record that as the reason to skip and cite the table.
|
||||||
|
- **Seal/punch color state.** Retail's portal-depth draws keep color writes
|
||||||
|
ENABLED with `SRCALPHA/INVSRCALPHA` and source alpha 0 (a no-op blend);
|
||||||
|
acdream sets `ColorWrite=false`. Pixel-identical by construction; the
|
||||||
|
chunk adds the register row (AD-nnn: "portal-depth color path: write-mask
|
||||||
|
off instead of a zero-alpha blend — identical output, different state") OR
|
||||||
|
ports the exact state if the Vulkan pipeline already carries the blend
|
||||||
|
attachment; the reviewer decides which is cheaper to keep honest.
|
||||||
|
- **Truth table + two-frame latch test** (plan §9 S4 tests): one theory in
|
||||||
|
`WalkFrameDriverTests` over (root kind, draw_landscape, outside-view count,
|
||||||
|
previous count) → the exact event subsequence (`LFLUSH`, stamp, `CLEAR`?,
|
||||||
|
`SEALS`?), plus the consecutive-frames case proving the latch crosses
|
||||||
|
frames, plus "multiple look-ins isolated from the root".
|
||||||
|
|
||||||
|
## 3. S4 chunk 2 — the alpha lists (the slice's body)
|
||||||
|
|
||||||
|
**Current state (verified 2026-09-03 at `7df0b94c9`):** `RetailAlphaQueue` is
|
||||||
|
ONE scope-global list sorted by viewer distance at flush
|
||||||
|
(`SortRetailOrder` in `Flush` / `FlushFartherThan`); submitters:
|
||||||
|
`WbDrawDispatcher` (two `queue.Submit` sites: the packed path and the walk
|
||||||
|
classify path with `viewerDistance`) and `ParticleRenderer` (one site).
|
||||||
|
Barriers: `IWalkFrameLeafRenderer.AlphaBarrier` → `FlushLandscapeAlpha` →
|
||||||
|
`_alpha.Flush()` at the building turn (retail `DrawBuilding`'s
|
||||||
|
`FlushAlphaList(0f)`), the `LandscapeFlush` leaf (retail `PView::DrawCells`'s
|
||||||
|
`FlushAlphaList(0f)` @0x005a4872), and two `RetailPViewRenderer` end-of-pass
|
||||||
|
calls (the top-level `SmartBox::RenderNormalMode` flush). `FlushFartherThan`
|
||||||
|
(the pre-punch "drain the farther content" approximation) is the AP-34 row.
|
||||||
|
|
||||||
|
**Retail (spec §5–§7, verified against the decomp at chunk time):** two
|
||||||
|
independent FIFO lists (CLIP and ALPHA) of 3000 `AlphaListEntry` each;
|
||||||
|
`AddMeshToAlphaList` appends, never sorts; each `DrawMesh` invocation owns a
|
||||||
|
first-for-this-list flag that captures material + object matrix for the
|
||||||
|
list's replay; `FlushAlphaList(threshold)` is a no-op only when BOTH counts
|
||||||
|
are below `threshold × 3000`, otherwise drains CLIP then ALPHA in append
|
||||||
|
order, resets both, restores the object matrix, does NOT restore the
|
||||||
|
material; capacity overflow = append returns false and the delayed subset is
|
||||||
|
NOT drawn; `DrawBlock` calls `FlushAlphaList(0.75)` per land cell (the
|
||||||
|
pressure valve — inert below 2250 entries).
|
||||||
|
|
||||||
|
**Behavior change (chunk contract to be written after the S3 review):**
|
||||||
|
1. Replace the sorted single queue with two FIFO records mirroring the
|
||||||
|
retail entry (source token, first-for-list material/matrix capture,
|
||||||
|
`overrideClipmap`, list id) — no distance field, no sort.
|
||||||
|
2. Route every submitter to the exact list by the retail `DrawMesh` branch
|
||||||
|
table (spec §4): CLIP for the multipass clip-map delayed duplicate, ALPHA
|
||||||
|
for delayed subsets; sky/detail immediate gates; material `has_alpha`
|
||||||
|
fallback.
|
||||||
|
3. Flush sites exactly: `DrawBuilding` 0f (the existing `AlphaBarrier`),
|
||||||
|
`DrawBlock` 0.75 per land cell (NEW — a threshold flush at the `SC` turn;
|
||||||
|
inert at today's counts, pinned by a capacity test), `PView::DrawCells`
|
||||||
|
0f (the existing `LandscapeFlush`), top-level 0f (the existing pass-end
|
||||||
|
flush). Delete `FlushFartherThan` and retire AP-34.
|
||||||
|
4. Capacity 3000 per list with the exact overflow behavior (append false,
|
||||||
|
subset dropped) — pinned, not "expanded or recovered".
|
||||||
|
5. Transparent EnvCell subsets routed to their retail list (spec §6: the
|
||||||
|
environment detail surface makes eligible subsets immediate).
|
||||||
|
|
||||||
|
**Tests (plan §9 S4):** multiple translucent objects in one cell with
|
||||||
|
reversed distance vs insertion order (FIFO wins); equal-key stable tie; two
|
||||||
|
cells where a global sort disagrees with traversal; particle/object/
|
||||||
|
transparent-cell overlap; `DrawBuilding 0f` flush; pre-clear and final
|
||||||
|
flush; the 0.75 partial flush at exactly 2250; alternating blend modes across
|
||||||
|
Vulkan batches; capacity 3000 overflow drops the subset.
|
||||||
|
|
||||||
|
**Gate:** the alpha/depth transcripts exact against the §7 captures
|
||||||
|
(`*.alphadepth.log` — `AM` add-mesh, `FL` flush, `PM` portal mask lines), the
|
||||||
|
walk/depth/alpha suites, Release build; then the owner's G3 (S4's owner gate
|
||||||
|
per the plan) — the lead's S3-state G3 pre-run of 2026-09-03 (20/20 frames)
|
||||||
|
is the baseline to diff against.
|
||||||
|
|
||||||
|
## 4. S4 chunk 3 — deletions
|
||||||
|
|
||||||
|
Delete the obsolete stencil/bias/skip paths and the CYpt sort once chunk 2's
|
||||||
|
transcript is exact: `RetailAlphaOrdering.ComputeViewerDistance` and every
|
||||||
|
`viewerDistance` argument on the submit path; any remaining
|
||||||
|
`FlushFartherThan` consumer; the `#117`/`#129` bias remnants the S1 hygiene
|
||||||
|
already removed from `portal_depth.vert` (verify nothing else carries them).
|
||||||
|
Register: AP-34 retired; any row describing the distance sort retired; the
|
||||||
|
seal/punch color-state row from S4-c1 kept or retired per its decision.
|
||||||
|
|
||||||
|
## 5. Open questions to settle before dispatch
|
||||||
|
|
||||||
|
- Does the walk's `SC` turn (per land cell) have a leaf hook where the 0.75
|
||||||
|
valve belongs, or does `OnSortCellTurn` need a third leaf method? (Read
|
||||||
|
`WalkFrameDriver`'s land-cell turn after chunk 3's interleave.)
|
||||||
|
- Where does the particle submitter's list membership come from — the
|
||||||
|
particle draw is retail's own `AddMeshToAlphaList` consumer (billboards go
|
||||||
|
to ALPHA), or is it drawn through the emitter's cell turn immediately?
|
||||||
|
Check `ParticleRenderer.cs`'s submit site against the spec's §4 table.
|
||||||
|
- The `alphadepth` capture format: confirm the `AM`/`FL` lines carry the list
|
||||||
|
id so the transcript can be compared per list, not merged.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue