docs(overhaul): contract exact S5 c4 detail material
This commit is contained in:
parent
678bffaa85
commit
9f410d8b75
3 changed files with 282 additions and 4 deletions
|
|
@ -1,8 +1,7 @@
|
|||
# Campaign OVERHAUL v2 — S5 consumers, material, and closeout packet
|
||||
|
||||
**Status:** S5-c1 and S5-c2 LANDED + lead graphical gates PROVISIONAL PASS;
|
||||
S5-c3 implemented in scratch; retail review pass 3 PASS, production review
|
||||
pass 4 FAIL, and bounded fix round 3 is contracted under §20.
|
||||
**Status:** S5-c1 through S5-c3 LANDED + REVIEW-CLOSED with lead graphical
|
||||
gates PROVISIONAL PASS; S5-c4 is contracted under §22.
|
||||
**Branch:** `claude/campaign-w-retail-frame-walk`.
|
||||
**Gate:** G4 remains unpassed. Nothing merges to `main` before G4.
|
||||
|
||||
|
|
@ -1561,3 +1560,255 @@ based alpha/selection/light sidecars and omit the active atmospheric receiver
|
|||
pipeline/bindings. It exists at least at S4-c2 `252886e84`, is filed as #470,
|
||||
and must be repaired before renderer-solid/G4. S5-c4 is next; #469/#470, c5,
|
||||
the closeout program, and G4 remain. Nothing merges to `main` before G4.
|
||||
|
||||
## 22. S5-c4 contract — exact one-pass detail material and ordered production closure
|
||||
|
||||
This chunk replaces the acdream-only base-plus-`mesh_detail` replay with the
|
||||
single fragment retail emits when the hardware single-pass detail path is
|
||||
available. It applies to detail-active building and EnvCell subsets in every
|
||||
current world submission path: classic grouped, walk-ordered, immediate alpha,
|
||||
deferred alpha, and EnvCell opaque/transparent replay. One source subset must
|
||||
produce one physical draw and one `(rgb, alpha)` result while retaining that
|
||||
subset's existing queue position, blend family, alpha-test/depth state, cull,
|
||||
geometry, transform, material overrides, fog policy, sampler, and mip chain.
|
||||
|
||||
The production audit found that the walk-ordered path currently uploads
|
||||
building detail categories and forces them into solo runs but issues only the
|
||||
base draw. That omission is filed as #471 and is part of this chunk: the new
|
||||
one-pass detail result must be armed on that existing base draw. Do not add a
|
||||
blended overlay after the run. An overlay would preserve AP-232, create a new
|
||||
terrain/`StreamMark` flush obligation, and remain unlike retail.
|
||||
|
||||
### 22.1 Lead-verified retail and paired-binary facts
|
||||
|
||||
The paired executable is `C:\Turbine\Asheron's Call\acclient.exe`, SHA-256
|
||||
`006FFEADC5D679C871497112A5BD1F87714D0E273E2166BAE5052DDE369297B1`.
|
||||
Its CodeView identity remains GUID `{9E847E2F-777C-4BD9-886C-22256BB87F32}`,
|
||||
age 1, matching the named PDB. The named pseudo-C and fresh paired-executable
|
||||
disassembly agree on these exact ranges:
|
||||
|
||||
| Fact | VA range / length | SHA-256 |
|
||||
|---|---|---|
|
||||
| `SetSurface` detail stages | `0x0059C4D0..0x0059C5B5` / 229 | `090E24BE542E9DA4F77B547D091F5C2E676109495919BEA70027AD2B89E11426` |
|
||||
| `SetSurface` blend/alpha/depth state | `0x0059C6C5..0x0059C866` / 417 | `1F077DA1BB09FBAC0EAF7522E125C716AAF499DFA8763DD3DDF29CCC6A76C382` |
|
||||
| `RenderMeshSubset` single-pass arm | `0x0059CA10..0x0059CAF0` / 224 | `64A988D4B1611CEEA6DE135FF52CDF30FE1AFDAAFF5E3B76751FFA7FC833CC53` |
|
||||
| `DrawMesh` detail/alpha routing | `0x0059D4A0..0x0059D5A5` / 261 | `20B1E5D1E90C9E19C62047AF521F817CF6700B5FEA68CE78C7404CD238862CB3` |
|
||||
|
||||
Named anchors are `D3DPolyRender::SetSurface @0x0059C4D0`
|
||||
(`acclient_2013_pseudo_c.txt` lines 425083–425303),
|
||||
`RenderMeshSubset @0x0059CA10` (lines 425382–425450),
|
||||
`DrawMesh @0x0059D4A0`, `RenderDeviceD3D::DrawEnvCell @0x0059F170`, and
|
||||
`DrawBuilding @0x0059F2A0`. The live capability result remains the VM2 CDB
|
||||
record in `2026-08-22-vm2-retail-detail-path-cdb.md`: retail takes the
|
||||
single-pass path, not its fallback.
|
||||
|
||||
Let `B` be the sampled base RGB, `D` the active diffuse/lighting RGB, `a` the
|
||||
active diffuse/material alpha, and `Q=(q,qA)` the sampled detail texel. At
|
||||
`0x0059C51C/52B/53A/549` retail programs:
|
||||
|
||||
- stage 0 colour `C0 = B * D`;
|
||||
- stage 0 alpha `PREMODULATE(DIFFUSE,DIFFUSE)`, whose visible stage-0 result is
|
||||
`a` but whose stage-1 `CURRENT` alpha is premultiplied by the next texture,
|
||||
`a*qA`;
|
||||
- stage 1 colour `BLENDCURRENTALPHA(TEXTURE,CURRENT)`; and
|
||||
- stage 1 alpha `MODULATE(TEXTURE,CURRENT)`.
|
||||
|
||||
Therefore the exact pre-fog fragment is:
|
||||
|
||||
```text
|
||||
w = a * qA
|
||||
C = q * w + (B * D) * (1 - w)
|
||||
X = a * qA * qA
|
||||
```
|
||||
|
||||
The square in `X` is mandatory. Base texture alpha does not participate in the
|
||||
detail-active final alpha. Fog is applied to `C` after the combine wherever
|
||||
the subset's fixed-function policy enables fog; it never changes `X`.
|
||||
|
||||
`SetBlendFunction @0x005A2B90` writes one colour/alpha factor set, so the
|
||||
framebuffer equations for destination `F` are:
|
||||
|
||||
| Raw family | Result RGB | Result alpha |
|
||||
|---|---|---|
|
||||
| Alpha | `C*X + F.rgb*(1-X)` | `X*X + F.a*(1-X)` |
|
||||
| Alpha + Additive | `C*X + F.rgb` | `X*X + F.a` |
|
||||
| Additive without Alpha | `C + F.rgb` | `X + F.a` |
|
||||
| InverseAlpha | `C*(1-X) + F.rgb*X` | `X*(1-X) + F.a*X` |
|
||||
| InverseAlpha + Additive | `C*(1-X) + F.rgb` | `X*(1-X) + F.a` |
|
||||
| pure CLIP survivor | `C + F.rgb*(1-X)` | `X + F.a*(1-X)` |
|
||||
|
||||
Pure CLIP rejects iff `X < r`, with `r=100/255` for paletted and `r=200/255`
|
||||
for DDS/non-paletted input; equality survives. CLIP combined with an
|
||||
Alpha/Additive/Inverse family keeps that family's factors and applies the same
|
||||
test. The later `TRANSLUCENT` branch at `0x0059C767..0x0059C7A6` then matters:
|
||||
ordinary `T` and `T|Alpha` are straight-alpha; `T|Additive` and
|
||||
`T|InverseAlpha` retain their respective family unless the skip arm applies;
|
||||
every `T|CLIP` combination is forced to straight-alpha and CLIP is disabled.
|
||||
Do not replace that table with a universal straight-alpha assumption.
|
||||
|
||||
`a` is the active material alpha, including authored
|
||||
`1-Surface.Translucency` on a `Translucent` surface and the current object/part
|
||||
fade multiplier. The lead's installed Surface census found 261/261
|
||||
`Translucent`-flagged surfaces carry nonzero authored translucency, including
|
||||
real 0.25, 0.5, 0.75, and 1.0 values. Treating `a` as always one is disproven.
|
||||
Current prepared Wb payloads discard that scalar while the decoded base image
|
||||
bakes it into base alpha; because retail detail excludes base alpha, it cannot
|
||||
be recovered from the sampled texel. The implementation must carry authored
|
||||
surface opacity explicitly from extraction through the prepared payload and
|
||||
GPU batch data, multiply it by the existing live instance opacity, and use the
|
||||
product as `a`. Guessing from texture alpha, querying DAT from the renderer, or
|
||||
using `base.a` is forbidden.
|
||||
|
||||
### 22.2 One draw, one material result
|
||||
|
||||
Implement the combine in the ordinary and atmospheric world-mesh fragment
|
||||
families, sharing one source include or otherwise proving their arithmetic
|
||||
textually and numerically identical. The base texture remains the batch-owned
|
||||
array sample. A detail-active exact command supplies the category texture slot
|
||||
and tiling in the existing push fields; zero tiling is the unarmed value. The
|
||||
per-draw GPU batch record supplies authored surface opacity. The vertex stage
|
||||
passes that scalar without interpolation; the fragment multiplies it by the
|
||||
existing instance-opacity varying to obtain `a`.
|
||||
|
||||
The prepared contract must gain the scalar without ambiguity:
|
||||
|
||||
- `MeshExtractor` computes it from the resolved source `Surface` for ordinary
|
||||
GfxObj and CellStruct batches using the existing
|
||||
`OpacityFromSurfaceTranslucency` rule;
|
||||
- `TextureBatchData`, its deterministic serializer, and
|
||||
`ObjectRenderBatch` preserve it exactly;
|
||||
- this is a prepared-payload schema change, so advance the bake-tool recipe
|
||||
identity and update every recipe/round-trip/compatibility pin in the same
|
||||
commit; an old recipe must be rejected clearly, never misread; and
|
||||
- the GPU batch ABI carries it explicitly with layout/stride tests for both
|
||||
built-in shader families. Do not introduce a renderer-side surface table,
|
||||
per-frame dictionary, or DAT lookup.
|
||||
|
||||
For a detail-active fragment, compute `(C,X)` before the current discard/fog
|
||||
tail. Alpha testing uses `X`, not sampled base alpha. For detail-off fragments,
|
||||
preserve the current byte-for-byte logical path: base-alpha discard/reference,
|
||||
RGB lighting/fog, and `base.a * instanceOpacity` output alpha. The debug-light
|
||||
mode remains a deliberate diagnostic bypass and must not sample detail.
|
||||
|
||||
At each production draw site:
|
||||
|
||||
1. arm detail only when the existing Building Detail Textures option is on,
|
||||
the correct category binding is resident, tiling is nonzero, and the exact
|
||||
command/subset belongs to the building or EnvCell detail category;
|
||||
2. set the detail slot/tiling and draw that source subset exactly once through
|
||||
its original base pipeline family;
|
||||
3. preserve its original queue position, blend, depth test/write/reference,
|
||||
alpha test, cull, geometry, draw-id offset, absolute transform base, local
|
||||
sidecars, selected building GfxObj, palette/original-texture override,
|
||||
lighting, fog enable, and atmospheric receiver choice; and
|
||||
4. restore neutral detail push fields before the next non-detail draw.
|
||||
|
||||
Delete every now-unreachable `RetailDetail`/`RetailDetailTransparent` pipeline,
|
||||
`GpuBlendMode.RetailDetail`, `DrawBuildingDetailRangeRhi`-style replay helper,
|
||||
`mesh_detail.vert/.frag`, compiled SPIR-V entries, manifest entries, and stale
|
||||
two-draw comments/tests. Keep CPU detail-category ownership only where it still
|
||||
selects exact eligible commands. Do not delete or weaken the building-detail
|
||||
setting, category textures, repeat/linear sampler, full mip chain, S4's two
|
||||
FIFO queues, AD-120 immediate placement, AP-238 token granularity, AP-239 raw
|
||||
mask residual, or AP-240 ordinary-GfxObj ClipMap placement.
|
||||
|
||||
The ordered-path repair for #471 is a one-pass arm on the existing solo base
|
||||
run. It adds no second draw and therefore leaves `WalkFrameDriver`'s
|
||||
opaque/no-blended-overlay `StreamMark` terrain-flush premise true. Tests must
|
||||
prove that premise rather than adding a compensating terrain flush.
|
||||
|
||||
### 22.3 Audited policy table and explicit nonchanges
|
||||
|
||||
Add one data-driven policy test/table spanning Building and EnvCell × Opaque,
|
||||
Alpha, Additive, InverseAlpha, paletted CLIP, and DDS CLIP × detail on/off. For
|
||||
each row pin physical draw count, source order/FIFO, pipeline blend/depth/alpha
|
||||
test/reference, detail arm, emitted `(C,X)`, and framebuffer result on a
|
||||
nontrivial destination. Add raw `Translucent` combinations sufficient to pin
|
||||
the later override described in §22.1. Existing AP-238/AP-239/AP-240 facts
|
||||
remain visible in the table instead of being silently relabelled exact.
|
||||
|
||||
This chunk does not change FIFO classification/token granularity, portal or
|
||||
terrain ordering, building-degrade selection, visibility/membership,
|
||||
directional-shadow caster selection, #469's lighting-direction transition, or
|
||||
#470's general ordered atmospheric sidecar/receiver defect. It must implement
|
||||
the same material arithmetic in the atmospheric shader so the later #470
|
||||
repair cannot expose a second result. No graphical client is launched by the
|
||||
implementer.
|
||||
|
||||
Allowed production scope is the prepared mesh batch/extractor/serializer and
|
||||
bake-recipe identity; world GPU batch ABI and built-in ordinary/atmospheric
|
||||
mesh shaders; Wb/EnvCell detail draw/pipeline ownership; shader compiler
|
||||
outputs/manifest; and the smallest render-pack ABI pins required by those
|
||||
shader changes. Tests may change for those surfaces, deterministic prepared
|
||||
round trips, state/pixel equations, command transcripts, allocation, shader
|
||||
ABI, and package compatibility. The only authorized documentation file in the
|
||||
implementation commit is
|
||||
`docs/architecture/retail-divergence-register.md`: strike AP-232 with the exact
|
||||
new mechanism/evidence and amend counts; add or correct a row in the same
|
||||
commit for every discovered surviving deviation. Do not edit this packet,
|
||||
the plan, issues, architecture prose, scripts, or generated evidence reports.
|
||||
|
||||
### 22.4 Required proof, mutations, and return
|
||||
|
||||
Focused proof must include at least:
|
||||
|
||||
1. independent CPU fixtures over nontrivial base/detail RGBA, diffuse colour,
|
||||
authored opacity, live fade, fog, destination RGBA, and every §22.1 state;
|
||||
they must distinguish `a*qA²` from `a*qA`, `base.a*a*qA²`, and today's two
|
||||
draws;
|
||||
2. pure/paletted/DDS CLIP values immediately below, equal to, and above the
|
||||
final-`X` reference plus `Translucent|CLIP`'s disabled-test override;
|
||||
3. extraction and prepared serialization round trips for opacity 1, 0.75,
|
||||
0.5, 0.25, and 0, a bumped recipe identity, deterministic bytes, and clear
|
||||
rejection of recipe 8 by the recipe-9 build;
|
||||
4. GPU ABI pins proving the batch scalar reaches both ordinary and atmospheric
|
||||
fragments, detail-off never samples the category texture, and debug-light
|
||||
mode stays independent;
|
||||
5. real Wb classic, walk-ordered, immediate-alpha, and delayed-alpha command
|
||||
recordings proving one detail-active subset draw, original pipeline state,
|
||||
exact slot/tiling/material alpha, no replay, and no stale detail arm on an
|
||||
adjacent ordinary draw;
|
||||
6. real EnvCell opaque, Alpha, Additive, and both CLIP-reference recordings
|
||||
with the same one-draw/state/order proof;
|
||||
7. production ordered sequence ordinary → opaque building detail → ClipMap
|
||||
building detail → ordinary with exact one-draw adjacency and no added
|
||||
terrain flush, closing #471;
|
||||
8. active/inactive atmospheric receiver shader/pipeline recordings proving
|
||||
identical material equations while leaving #470's separate general repair
|
||||
boundary explicit;
|
||||
9. setting-off and unavailable-category identity, selected-surface override,
|
||||
sampler/mip, fog-after-combine, draw-id/transform-prefix, cull, and
|
||||
lifecycle/reset/revisit preservation; and
|
||||
10. warmed extraction-free draw/classification paths at 0 managed bytes after
|
||||
warmup, with no per-frame material lookup/table/allocation.
|
||||
|
||||
Sabotage and restore at least these mutations, recording the first failing
|
||||
test/assertion for each in the implementation commit body: change `X` to
|
||||
`a*qA`; multiply `X` by base alpha; test CLIP against base alpha or 0.05;
|
||||
restore any second detail draw; bind straight alpha instead of the original
|
||||
subset family; omit the walk-ordered detail arm; omit the atmospheric combine;
|
||||
drop authored opacity during prepared serialization; and leave the detail push
|
||||
fields armed for the following ordinary draw. Include one allocation sabotage
|
||||
that builds a per-frame surface map and prove the 0-B pin catches it.
|
||||
|
||||
Implementer return: one clean commit; exact changed-file and line-count list;
|
||||
all mutation first failures; `git diff --check`; Release solution build 0W/0E;
|
||||
shader compilation plus manifest/SPIR-V validation; focused content/serializer,
|
||||
renderer/state/pixel/command/allocation suites; official hermetic lane; and an
|
||||
inclusive InstalledDat lane with every accepted nonpassing identity named. If
|
||||
the package recipe changes, also return the exact deterministic bake command,
|
||||
artifact identity/size, and compatibility result. No client run.
|
||||
|
||||
Sequential review 1 — retail/material/deviation fidelity: re-check the named
|
||||
and paired bytes, PREMODULATE semantics, squared alpha, every framebuffer and
|
||||
CLIP/Translucent row, authored opacity provenance, fog placement, AP-232
|
||||
retirement, AP-238/239/240 preservation, and all retail-facing mutations.
|
||||
Sequential review 2 — architecture/production/gate honesty: one physical draw,
|
||||
all five production paths including #471, prepared-schema compatibility, no
|
||||
renderer DAT lookup or per-frame map, shader/pack ABI, state/order/reset,
|
||||
allocation, build/lane/artifact provenance, and at least three independently
|
||||
reproduced sabotages. Reviews run sequentially. Every code finding receives a
|
||||
bounded fix contract and narrow re-review; documentation-only findings may be
|
||||
corrected directly by the lead. At most ten c4 review passes may run; stop
|
||||
before an eleventh. Nothing lands or launches graphically until both lenses
|
||||
pass.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue