acdream/src/AcDream.App/Rendering/Shaders/spv/shaders.manifest.json
Erik d1e3e64f61 feat(render): S4 chunk 1 — retail far-punch bits, the ±12 local-input reject, the depth truth table and cross-frame latch pins
S4-c1 per docs/research/2026-09-01-overhaul/s4-depth-alpha-packet.md §6.
S3 chunk 2 already landed the persistent portalsDrawnCount latch, the
gated clear, the exit-seal counting, and the look-in isolation — this
chunk covers only what §1/§2 of the packet name as still owed: C0-C3.

C0 — far-punch depth constant (R1: DrawPortalPolyInternal @0x0059bc90's
tail). portal_depth.vert's punch branch carried the decimal 0.99999988,
which reinterprets as bits 0x3F7FFFFE — fifteen ULPs FARTHER from the
camera than retail's real constant, bits 0x3F7FFFEF. Now writes
`uintBitsToFloat(0x3F7FFFEFu)` so the exact bits survive the GLSL/SPIR-V
compiler instead of trusting a decimal literal to round-trip unchanged.
Recompiled via tools/compile-shaders.ps1 (glslc 1.4.350.0 backend
recorded, managed shaderc path used); portal_depth.vert.spv's SHA-256
re-pinned in VulkanShaderManifestTests
(51c60d0924d62c61548efcf5f9e7672a121b1b68ca0a06755e32f1a4d73a8acf,
was 4ac1c452e7ac0d08a32f67fb03f21229af2d1605baa81f407240a3626251dfd7).

T1 (new Fact PortalDepthVert_FarPunchConstant_MatchesRetailExactBits in
VulkanShaderManifestTests.cs): a SOURCE pin — reads portal_depth.vert's
punch line and reinterprets whatever literal it carries (uintBitsToFloat
hex or a plain decimal) as raw bits, asserts == 0x3F7FFFEF. Verified
against the PRE-CHANGE source by hand-reverting the line to
`clipPos.z = clipPos.w * 0.99999988;` and re-running just this test:

    Assert.Equal() Failure: Values differ
    Expected: 1065353199
    Actual:   1065353214

(1065353199 = 0x3F7FFFEF, 1065353214 = 0x3F7FFFFE). Line restored and
the test re-confirmed green afterward. MUTATION: any other literal fails
the same way.

C1 — the ±12 local-input reject (R2: 0x59BCD6-0x59BD28 then
0x59BD40-0x59BD66). The Ghidra arbitration table in
oh1-depth-lifecycle.md governs over the pseudo-C's own nested-if reading
of the four x87 FCOM results (BinaryNinja's `test ah, 0x44` condition
synthesis is FPU-flag-ambiguous and reads backward at face value — see
feedback_bn_decomp_field_names.md on decompiler flag mush as an artifact
class, not semantics): the table's row says "whole poly on any
local-input x/y == +/-12 boundary is rejected before count/clip" — taken
as written, not re-derived from the pseudo-C's literal branch nesting.

Ported as one shared predicate,
WalkVisibilityMath.IsRejectedByPortalPolygonBoundaryGuard(ReadOnlySpan
<Vector3>): true iff any vertex's X or Y is exactly +12f/-12f (retail
tests LOCAL x/y before xformStart, the world transform). Wired at BOTH
producers that own the LOCAL polygon before it leaves cell/building
space:
  - WalkFrameDriver.OnPunchGeometry (the walk's punch-event producer,
    IWalkEventSink.OnPunchGeometry) — checked on the building-local
    WalkPolygon.Vertices before TransformToWorld; a hit returns before
    MarkIfGrown/any event append (retail's reject -> transform -> clip
    -> count order).
  - RetailPViewPassExecutor.DrawPortalDepthWrite (the exit-seal
    enumeration behind DrawExitPortalMask, the sole caller) — checked on
    cell.PortalPolygons[index]'s local vertices before the
    Vector3.Transform loop; a hit `continue`s with no `submitted++`.

T2 (three layers):
  1. WalkVisibilityMathTests.cs — direct unit tests of the predicate:
     Boundary_guard_rejects_a_polygon_with_one_vertex_exactly_on_plus_minus_12
     (Theory, x/y == +-12 each), Boundary_guard_admits_a_polygon_whose_
     nearest_vertex_is_just_inside_12 (Theory, x/y == +-11.999),
     Boundary_guard_rejects_the_whole_polygon_even_when_only_one_of_
     several_vertices_hits_it, Boundary_guard_ignores_the_vertical_z_
     component, Boundary_guard_admits_the_empty_polygon.
  2. WalkFrameDriverTests.OnPunchGeometry_RejectsWholePolygonOnExact
     PlusMinus12LocalVertex_ButPunchesJustInside — functional: feeds
     OnPunchGeometry a polygon with a vertex at x=12 (no PunchFan/no
     "PUNCH:" log line) then one at x=11.999 (punches normally,
     leaf.Punches has exactly one entry, log has exactly one "PUNCH:3@v0").
  3. RetailPViewPassExecutorTests.DrawPortalDepthWrite_RejectsDegenerate
     LocalPolygons_BeforeTransformOrSubmission — a real functional test of
     DrawPortalDepthWrite needs a live PortalDepthMaskRenderer the suite
     has no fake for, so this is a compiled-call-graph pin (this file's
     established pattern for exactly this situation): the guard call
     precedes both the Vector3.Transform loop and
     PortalDepthMaskRenderer.DrawDepthFan by IL offset, gated by a
     conditional branch immediately after it.

MUTATION texts, all verified live during this session then reverted:
  - OnPunchGeometry_RejectsWholePolygon... with the C1 guard deleted from
    OnPunchGeometry:
      Assert.Single() Failure: The collection contained 2 items
      Collection: [WalkPolygon { Plane = WalkPlane { Normal = <0, 0, 1>, D = -3 }, Vertices = [<0, 0, 3>, <12, 0, 3>, <5, 5, 3>] }, WalkPolygon { Plane = WalkPlane { Normal = <0, 0, 1>, D = -3 }, Vertices = [<0, 0, 3>, <11.999, 0, 3>, <5, 5, 3>] }]
  - DrawPortalDepthWrite_RejectsDegenerateLocalPolygons... with the C1
    guard deleted from DrawPortalDepthWrite:
      Expected call to WalkVisibilityMath.IsRejectedByPortalPolygonBoundaryGuard.
  - Boundary_guard_admits_a_polygon_whose_nearest_vertex_is_just_inside_12
    with the predicate widened to `MathF.Abs(x) >= 11.99f ||
    MathF.Abs(y) >= 11.99f` (all four rows):
      Assert.False() Failure
      Expected: False
      Actual:   True
  - Boundary_guard_rejects_a_polygon_with_one_vertex_exactly_on_plus_
    minus_12 with the predicate narrowed to strict `x > 12f || x < -12f
    || y > 12f || y < -12f` (all four rows):
      Assert.True() Failure
      Expected: True
      Actual:   False
  - Boundary_guard_rejects_the_whole_polygon_even_when_only_one_of_
    several_vertices_hits_it with the guard checking only
    localVertices[0] instead of looping every vertex:
      Assert.True() Failure
      Expected: True
      Actual:   False

C2 — no pipeline change for R3 (depth ALWAYS/write/no-cull, color writes
ENABLED with a zero-alpha SRCALPHA/INVSRCALPHA blend). acdream's
PortalDepthMaskRenderer.Rhi.cs:92,100 sets ColorWrite=false alongside
Blend=None; portal_depth.frag writes no color output at all. Provably
pixel-identical (retail's blend collapses to dst'=dst when srcAlpha is
fixed at 0, for any RGB) and the write mask is the SAFER mechanism going
forward (structurally blocks any future accidental color write,
independent of an authored zero-alpha invariant). Added register row
AD-119 to docs/architecture/retail-divergence-register.md (the next free
id after AD-118), citing DrawPortalPolyInternal @0x0059bc90 and
PortalDepthMaskRenderer.Rhi.cs; section 2's active-row count and running
header note updated (90 -> 91).

C3 — the truth table + cross-frame latch tests. The (root kind,
draw_landscape, outside-view count, previous count) table's cells are
mostly already covered by S3 chunk 2's own tests — this chunk adds only
the genuinely missing rows/cases, and leaves every existing test
untouched:

  Pre-existing coverage (named, not reproduced):
    - interior, ov==0, prior==0 ->
      RunFrame_InteriorFloodWithNoExitView_SkipsLandscapeAndNeverFlushesClearsOrSeals
    - interior, ov>0, prior==0 ->
      RunFrame_InteriorFloodWithExitView_FreshDriverSkipsTheGatedClearThenDrawsSealsAndFloodCells
      and OnInteriorFloodDrawTurn_FirstOvFrameSkipsClear_SecondFrameArmedByFirstsSealsClears
      (its own frame 1)
    - interior, ov>0, prior>0 (T4's "frame 1 seals N>0 -> frame 2
      clears" half) ->
      OnInteriorFloodDrawTurn_FirstOvFrameSkipsClear_SecondFrameArmedByFirstsSealsClears
      (its own frame 2)
    - T4's "frame 1 seals 0 -> frame 2 does not clear" half (repeated
      across three consecutive ov>0 frames, subsuming the two-frame
      case) -> OnInteriorFloodDrawTurn_FloodWithNoExitPortal_NeverClearsAcrossFrames
    - one look-in isolated from the root latch ->
      LookInDrawCells_NeitherArmsNorConsumesThePortalsDrawnCounter
  No further T4 test was added — the two existing facts above already
  prove both halves of the two-consecutive-frames latch case exactly.

  New rows added this chunk:
    - WalkFrame_OutdoorRoot_NeverFiresTheInteriorClearSealMachinery: root
      kind == OUTDOOR. RetailFrameWalk.WalkFrame's outdoor branch
      ((cameraCellId & 0xFFFF) < 0x100) calls DrawLandscape directly and
      never calls DrawInside/OnInteriorFloodDrawTurn at all, so the whole
      LFLUSH/stamp/CLEAR/SEALS mechanism structurally cannot fire —
      driven end-to-end through RunFrame with an outdoor cameraCellId,
      asserting SKY present, LFLUSH/CLEAR/SEALS absent, counter stays 0.
      MUTATION (verified, then reverted): added a stray
      `sink.OnInteriorFloodDrawTurn([], 1);` call to WalkFrame's outdoor
      branch:
        Assert.DoesNotContain() Failure: Item found in collection
                         ↓ (pos 1)
        Collection: ["SKY", "LFLUSH", "SEALS"]
        Found:      "LFLUSH"
    - OnInteriorFloodDrawTurn_OvZeroAfterAPriorArmedCounter_LeavesTheLatch
      CompletelyUntouched: interior, ov==0 immediately after an EARLIER
      ov>0 frame armed the counter — proves the counter is left EXACTLY
      as an earlier frame left it (not merely "not cleared this frame"),
      since S3 §8.1 R3 gates the ENTIRE outside_view.view_count>0 block,
      including the read-then-zero decision itself, on ov>0.
      MUTATION (verified, then reverted): moved
      `int armed = PortalsDrawnCount; PortalsDrawnCount = 0;` out of the
      `if (outsideViewCount > 0)` gate in
      WalkFrameDriver.OnInteriorFloodDrawTurn (unconditional
      read-then-zero every call):
        Assert.Equal() Failure: Values differ
        Expected: 1
        Actual:   0
      (every OTHER WalkFrameDriverTests fact stayed green under this same
      mutation — this new test is the only one that catches it).
    - MultipleLookIns_WithinOneFrameAndAcrossFrames_NeverTouchTheRootLatch
      (T5): extends the single-look-in fact to TWO look-ins in one frame
      then a THIRD in a later frame. MUTATION (verified, then reverted):
      a `_mutationLookInCalls` counter in HandleDrawCellsTurn's
      LookInStatic branch that resets PortalsDrawnCount on the SECOND
      look-in call:
        Assert.Equal() Failure: Values differ
        Expected: 1
        Actual:   0
      — while LookInDrawCells_NeitherArmsNorConsumesThePortalsDrawnCounter
      (one look-in only) stayed green under the identical mutation,
      confirming this test's incremental value over the existing single-
      look-in fact.

Gates: dotnet build (App.Tests and App) 0 warnings/0 errors; hermetic
lane 6832/6832 passed; InstalledDat lane against
C:/Users/erikn/Documents/Asheron's Call — exactly the four known
failures (TowerAscentReplayTests.TowerAscent_StaircaseStaysConeVisible_
EveryStep, LayoutImporterMediaBearingChildSweepTests.
MainGameUiAndChatInput_MediaBearingChildrenNowBuildAsRealWidgets and
LayoutImporterInvisibleSweepTests.EveryAuthoredInvisibleWidget_
StartsHiddenAcrossAllLayouts — both #383 — and
WalkTraceConformanceTests.Oh_doorway_still_first_frame_diff #458),
243 passed / 1 skipped / 4 failed / 248 total, no new failures; shader
tests (VulkanShaderDescriptorContractTests/VulkanShaderManifestTests/
RenderPackSpirvValidatorTests/SkyVertexLayoutTests) 35/35; register
tests (Divergence|Register filter) 52/52.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 23:38:52 +02:00

389 lines
10 KiB
JSON

{
"note": "Campaign V slice V6c. Regenerate with tools/compile-shaders.ps1.",
"shaders": [
{
"name": "atmospheric_bloom_blur",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "81222e42a52d0b560f5916b0f312bcc5370e42e596c821477d71c61883c3d025",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "ece56dc1c369316d7623f04795d93938fcc54756734bc49db01311fa96ec2dbf",
"compiled": true
}
]
},
{
"name": "atmospheric_bloom_downsample",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "81222e42a52d0b560f5916b0f312bcc5370e42e596c821477d71c61883c3d025",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "b13cd8712c6532fbe9c4661794ad9f424a27437b5f2fa14c0b76d38cf7e93523",
"compiled": true
}
]
},
{
"name": "atmospheric_filmic",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "81222e42a52d0b560f5916b0f312bcc5370e42e596c821477d71c61883c3d025",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "d28b82fc7ee8ca18d6911683ce904d59ecee749e9fd4bcc5af58ac048911a0b4",
"compiled": true
}
]
},
{
"name": "atmospheric_sun_occlusion",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "c21f381f2de05afc4415b2e348884a3cf6440da279b57d9a05a5d6ae5e9ac453",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "695e692cd5442be15d63a0b4f155abeaecf54674adae5f7cf25ef0bb892d18ee",
"compiled": true
}
]
},
{
"name": "atmospheric_sun_rays",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "81222e42a52d0b560f5916b0f312bcc5370e42e596c821477d71c61883c3d025",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "6ae2a078177b516c8ee138467559e9d4bf8838ea53941709176ce4f6fa3803a0",
"compiled": true
}
]
},
{
"name": "atmospheric_volumetric",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "81222e42a52d0b560f5916b0f312bcc5370e42e596c821477d71c61883c3d025",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "739b397a270142a77c08e7edefde7b2f9992588452a9827b737a0512bbeab513",
"compiled": true
}
]
},
{
"name": "debug_line",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "069ef7c89eea80c68e28f44b9e065c5cd3cc9220e8ba63261d345377025c2ea1",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "5db0714b88329f2465f4b8b949116e4295e37bf17360d81c108eacccb102a336",
"compiled": true
}
]
},
{
"name": "directional_shadow_terrain",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "e863894aa1d66508daad86806af2b2a3509088109754c491a3607477f78ed644",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "2b9ebbabc96c3ba53ce58cea175c52932c81d1d93820550f29a0734131dba5a3",
"compiled": true
}
]
},
{
"name": "directional_shadow_terrain_multiview",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "2f7d7bba3aa19a4891c30000e29c0bb84a2afdc26a44248d4c48bd0ffed8a04a",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "2b9ebbabc96c3ba53ce58cea175c52932c81d1d93820550f29a0734131dba5a3",
"compiled": true
}
]
},
{
"name": "directional_shadow_world_cutout",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "a30acec1fd60fcbc8a0cfa377726a65077a82836cbcf730cbcc756ce1b9299c5",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "cd9c404a9379715061358cb18a99b9310acbdd5062f0ad982ee9a37cd9f99922",
"compiled": true
}
]
},
{
"name": "directional_shadow_world_cutout_multiview",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "7651a9622227c0322f75c8e3af2685bceb9bc28b692b53df305ec73161e589ff",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "cd9c404a9379715061358cb18a99b9310acbdd5062f0ad982ee9a37cd9f99922",
"compiled": true
}
]
},
{
"name": "directional_shadow_world_opaque",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "9513c5baa4f269a9ddc265e9fa49c71a2834a004aca36939b99f9b5067d25ed1",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "2b9ebbabc96c3ba53ce58cea175c52932c81d1d93820550f29a0734131dba5a3",
"compiled": true
}
]
},
{
"name": "directional_shadow_world_opaque_multiview",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "edf89ab8a8c02bf8fc3099b091ca3508a5b9c18e2ebbfe5bb5a7d6c50a82c745",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "2b9ebbabc96c3ba53ce58cea175c52932c81d1d93820550f29a0734131dba5a3",
"compiled": true
}
]
},
{
"name": "mesh_atmospheric",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "e552edb7ef42e9e32812824c075310f2d99eb5826e527db5c22b54890ef02088",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "62b001a72080ea74bdaef0fb2a4ed92533feaeab76187ce4215813c6327432e7",
"compiled": true
}
]
},
{
"name": "mesh_detail",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "0c1eddb0fc892cb76ef4da47f727cec2516052d63247fa2682918bfd60b84fa8",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "e037fd28cf71453792c17522c97c4c7797193823ed78ca629a4331b632f177b1",
"compiled": true
}
]
},
{
"name": "mesh_modern",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "dba51ce23f2b621683fc78db73f608a0c000479b8e827cd3ecc8731d46c6ee64",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "12f2ceec9a8420bd273650e95251ca56c3bf3c3691fce1a539e4c5aea7abaabf",
"compiled": true
}
]
},
{
"name": "particle",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "f85089aaf92ee63d95f2e9feecd65d81e1aa942dceca5b62fa0747f9aae06f4c",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "6f2a5769670087bf58b0c1a7a007c1853952354dfd9106973656311bcbb855cd",
"compiled": true
}
]
},
{
"name": "particle_mesh",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "14ef8815265fee45bccaf08dcf4f0adc3c1135305fe123cb9085a3a2880fe08a",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "73c8db72aeb44e88054dd79fd722c7f683b27a8bc03368b5201f05adffd92728",
"compiled": true
}
]
},
{
"name": "portal_depth",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "afc70a0716ac9dbb3a514bfca6feeae8d0934f51e677b202b9049634645ba6ce",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "711ba97649f27f890f0cad5f355552fd8f707cbe801af4ac14afbee1b8f800c9",
"compiled": true
}
]
},
{
"name": "sky",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "51b42232202cd005439e95c50fd325a3849359b3357ab7550af9a4bb404279e4",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "5785633bc936fad68c97247f6ef8a22e5bcde0fe6d74a2f4676b844a2d7600c5",
"compiled": true
}
]
},
{
"name": "terrain_atmospheric",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "42d1dbd0dbd950862e8672f79a3f429f771bae55fd2b5721c3e551a0ea9563b6",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "9927abe9cc4fb83429d3e2ec8ee8d13f0b1936cebf484a4e529dcfdab431c3b8",
"compiled": true
}
]
},
{
"name": "terrain_modern",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "faf6855222cb2b09da6697c93a93f35cbc57c27bbc124055a6d235c72ef1a23a",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "a9f0ad2e679b68ee2de6c4877202f6f5e5089d0f7368fcedd6048891c6848915",
"compiled": true
}
]
},
{
"name": "ui_text",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "4ddc52f18ea953b33e9263dc2703397f63f4b104bc45d67edc06531145bd9d53",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "43cb53aa8c933f7800142b72ea81bafc923fd7039fd460022d55543081d0aee5",
"compiled": true
}
]
},
{
"name": "vk_probe",
"vulkanReady": true,
"stages": [
{
"stage": "vert",
"sourceSha256": "1f3f73aa4e9448c36f3b577e63b2142815736a4195bbc4395e1d674a9be92f43",
"compiled": true
},
{
"stage": "frag",
"sourceSha256": "8093adcacb925258ea79371a3ac3415de4f270f95eb12a621c759912992a5614",
"compiled": true
}
]
}
]
}