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