diff --git a/MobileGL/MG_IntegrationTest/CMakeLists.txt b/MobileGL/MG_IntegrationTest/CMakeLists.txt index d5a83229..1c741550 100644 --- a/MobileGL/MG_IntegrationTest/CMakeLists.txt +++ b/MobileGL/MG_IntegrationTest/CMakeLists.txt @@ -2738,6 +2738,50 @@ if (MOBILEGL_BUILD_DISAGGREGATED) ) endforeach() + # ---- D2: THE TEXTURE / PROGRAM SPLIT-SCENARIO CENSUS ------------------------------------ + # + # PLAN-PH-P34B-P7.md 1.2, "门:纹理 / program 场景 split 覆盖". Each candidate was run once + # under MOBILEGL_TRANSPORT=inproc on build-split and its FIRST BLOCKER recorded; the row per + # scenario x backend x blocker is in notes/p34b/split-scenario-census.md. What follows is the + # result of that census, not a guess: every scenario listed here passed, and every case that + # did not is excluded BY NAME below with its blocker. + # + # D1 owns PixelStoreSweep, DepthStencilReadbackMatrix, PackedWordReadback and + # LayeredTextureReadback - they are not here. + # + # DIRECTVULKAN ARMS DEFAULT TO NONE, and that is not an omission. The macro records every + # call and the informational tier-2 block at the end of this file replays all of them on + # DirectVulkan under integration-magma-all-{split,spawn,tcp} - so these scenarios DO get a + # Magma reading, just not a gating one. Gating them there would be asserting P7 wave 2's + # exit gate 1 from inside a P3b/P4b package, on a backend whose own @P7 named refusals are + # still being retired in waves A/B/C. + set(MGL_SPLIT_D2_SCENARIOS + TextureViewScenario # glTextureView end to end, 10 cases + TextureParamsWithoutASamplerViewScenario # G9's four cases; also settles the debt-table row + SampledSetStalenessScenario # 2 cases + ImageSizeAfterRespecScenario # 1 case + ImageTargetKindScenario # 29 cases + IntegerBorderColorScenario # 6 cases + SwizzleAccessRoutineScenario # 4 cases + PostLinkAttachScenario # 2 cases + RelinkStageSetScenario # 3 cases + UniformInitializerScenario # 3 cases + Glsl420DeclarationScenario # 6 cases + IoBlockNameCollisionScenario) # 2 cases + foreach(mglItestD2Scenario IN LISTS MGL_SPLIT_D2_SCENARIOS) + if(DEFINED MGL_SPLIT_D2_FILTER_${mglItestD2Scenario}) + mgl_itest_register_split_arms("${MGL_SPLIT_D2_FILTER_${mglItestD2Scenario}}" "") + else() + mgl_itest_register_split_arms("${mglItestD2Scenario}.*" "") + endif() + endforeach() + + # ProgramPipelineScenario BEYOND *StorageBlock*: the i1 block above already registers the two + # storage-block cases. The other nine are pure name/state cases that draw nothing, and + # ScenarioFixture's armed-lane rule (the client encoder's record ordinal must move) makes a + # case that produced no record RED for having nothing to say - which is the rule working, not + # a defect. They stay unregistered for that reason and are listed in the census note. + # The split half of the counting pair. MGITEST_PERSISTENT_MAP_ARM=emulated is R-6: under split # the adopt tier is pinned at T2, the resource owner declines every acquisition and the client # pushes the mapping's dirty blocks - so pmap must be non-zero and mpr must be the monolith diff --git a/docs/Disaggregated/notes/p34b/split-scenario-census.md b/docs/Disaggregated/notes/p34b/split-scenario-census.md new file mode 100644 index 00000000..4a4b6dd3 --- /dev/null +++ b/docs/Disaggregated/notes/p34b/split-scenario-census.md @@ -0,0 +1,115 @@ +# Texture / program split-scenario census (P3b/P4b wave 2-D, package D2) + +`PLAN-PH-P34B-P7.md` §1.2, row **门:纹理 / program 场景 split 覆盖**: "~20 个候选场景…先在 +inproc 跑一遍记首阻塞,按 P7/P8/P9 归属决定注册或具名排除". + +Head `7ed5da52`, build `~/w7/p7-espryt-d2/build-split` (Release, clang, lavapipe ICD, WSL +desktop). Every candidate was run under `MOBILEGL_TRANSPORT=inproc` first; the ones that passed +were then registered through `mgl_itest_register_split_arms` and re-run under all three +transports, which is the reading in the table. + +Package D1 owns `PixelStoreSweep`, `DepthStencilReadbackMatrix`, `PackedWordReadback` and +`LayeredTextureReadback`. They are not in this census. + +## Summary + +| | registered | excluded by name | blocked, not registered | +|---|---|---|---| +| texture family | 7 scenarios | 1 case | 0 | +| program family | 5 scenarios | 9 cases (one scenario's remainder) | 0 | + +**12 scenarios newly carry `integration-split` / `-spawn` / `-tcp` entries**, 71 cases per arm. +Plus `TextureViewAliasScenario` (this package's own, 3 of 4 cases). The split-arm registration +count recorded for the tier-2 Magma replay went from 33 to 46. + +## Texture family + +| scenario | cases | inproc | spawn | tcp | first blocker | +|---|---|---|---|---|---| +| `TextureViewScenario` | 10 | pass | pass | pass | — (needed `MOBILEGL_ESPRYT_ENABLE_TEXTURE_VIEW=1` on the three arm environments AND on the `TcpServer.Start` fixture; without it every case green-skipped) | +| `TextureParamsWithoutASamplerViewScenario` | 4 | pass | pass | pass | — | +| `SampledSetStalenessScenario` | 2 | pass | pass | pass* | one lane-interaction flake, see below | +| `ImageSizeAfterRespecScenario` | 1 | pass | pass | pass | — | +| `ImageTargetKindScenario` | 29 | pass (24 run, 5 skip) | pass | pass | — the 5 skips are `*Texture2DMultisample*` capability skips that also skip under monolith | +| `IntegerBorderColorScenario` | 6 | pass | pass | pass | — | +| `SwizzleAccessRoutineScenario` | 4 | pass | pass | pass | — | +| `TextureViewAliasScenario` (this package) | 4 | 3 pass, 1 red | 3 pass, 1 red | 3 pass, 1 red | **`TheOwnerUploadDrainRunsAgainAfterADrawBoundary`**, excluded by name — see below | + +### The debt-table 待核 row: is the P6 inspection forwarder debt closed? + +`PLAN-PH-P34B-P7.md` §1.3 carries "债务表「22 → P4b/P7 texture readback」…待核" and names +`TextureParamsWithoutASamplerView` as the case that settles it. **It is closed for this half.** +All four G9 cases pass under inproc, spawn and tcp on the current head — the parameter sync does +not depend on a sampler view existing, under a transport any more than under monolith, and the +white-box half (`PipeApplyPeek`) agrees with Espryt's applied value in every arm. The scenario is +now registered in the three arms, so the answer is re-taken on every CI run rather than by +inspection. + +### `TextureViewAliasScenario.TheOwnerUploadDrainRunsAgainAfterADrawBoundary` — excluded by name + +Red on inproc, spawn AND tcp; green under monolith. **Not a lane problem — a product defect this +package found.** After a view has been SAMPLED once, a later `glTexSubImage` through the OWNER's +name never becomes visible through the view. + +* client half provably correct: the case's own emitter-counter assertions pass, so the records + were emitted and the applier accepted them; +* `BackendTextureObject::IsDrawSyncCleanByRecord` (`Managers.cpp:15433`) compares the VIEW's + `record.Serial` / `record.PendingUploads`; +* an owner-side `resource_subdata` moves only the OWNER's (`MG_Pipe/PipeApply.cpp:1175`); +* nothing propagates a serial bump from a storage owner to the records that view it — + `MGPResourceDesc::ViewOf` is a forward edge with no reverse index, read only by the + descriptor-equality helper (`PipeApply.cpp:666`); +* monolith works because the same gate reads `GetContentVersion()` THROUGH the view, which + `TextureObjectView` forwards to the owner (`TextureObjectView.cpp:100-102`); +* `MG_Remote/CONTRACT-P5E.md:387-395` states the split gate in full and has the same hole. + +**Owner**: not P7/P8/P9 — a new finding. The fix is at the gate (`Managers.cpp`, package D1's +file) or at the publisher (`MG_Pipe/PipeApply.cpp`'s `ApplyTextureUpload`, outside D2's +footprint), and the publisher form needs an O(#texture records) scan or a reverse index on +`MGPipeResourceRecord`, plus a `CONTRACT-P5E` amendment. `KHR-GL43.texture_view.coherency` is +exactly this test and reads Pass in the CTS baseline, which is a **monolith** reading. + +### `SampledSetStalenessScenario` on tcp + +`AQueuedClearIsMaterialisedWhenAFilterChangeCompletesTheTexture` aborted once in a full +`ctest -L integration-tcp -j 1` run (182 entries, 1 failure) and passes when run alone and on a +re-run of the whole lane. The tcp lane serialises through one supervisor +(`RESOURCE_LOCK mobilegl-tcp`) that serves one session at a time, so a subprocess abort there is a +session-reuse interaction rather than a property of this scenario. **Recorded as informational, +not excluded**; if it recurs it belongs with the tcp supervisor's own work, not with the texture +family. + +## Program family + +| scenario | cases | inproc | spawn | tcp | first blocker | +|---|---|---|---|---|---| +| `PostLinkAttachScenario` | 2 | pass | pass | pass | — | +| `RelinkStageSetScenario` | 3 | pass | pass | pass | — | +| `UniformInitializerScenario` | 3 | pass | pass | pass | — | +| `Glsl420DeclarationScenario` | 6 | pass (5 run, 1 skip) | pass | pass | — the skip is `AnArrayOfSamplerArraysIsHonouredOrDeclinedCleanly`, a capability skip that also skips under monolith | +| `IoBlockNameCollisionScenario` | 2 | pass | pass | pass | — | +| `ProgramPipelineScenario` beyond `*StorageBlock*` | 9 | **not registered** | | | **ScenarioFixture's armed-lane rule.** The two storage-block cases are already registered by the P5e i1 block. The other nine are pure name/state cases that draw nothing, and an armed `DirectGLES.Split.` case whose workload produced no record is RED by design (`ScenarioFixture.h:84-97`: the client encoder's record ordinal must move). That is the rule working, not a blocker to retire — registering them would be asserting "records crossed" about cases that have no records to send. | + +## DirectVulkan arms: none, deliberately + +No `DirectVulkan.Split.` / `.Spawn.` / `.Tcp.` **gating** entry is added for any of these. + +It is not an omission and it is not a coverage hole either: `mgl_itest_register_split_arms` +records every call, and the informational tier-2 block replays all 46 of them on DirectVulkan +under `integration-magma-all-{split,spawn,tcp}` — so every scenario in this census DOES get a +Magma × three-transport reading the day it is registered. What it does not get is a **gate**. + +Gating them would assert P7 wave 2's exit gate 1 ("集成 + trace 在 Magma push 与 split 下全绿") +from inside a P3b/P4b package, on a backend whose own `@P7` named refusals are still being retired +in waves A/B/C — the vertex-layout split, the blit/copy/mip cluster and the alignment cluster are +all in flight. A red there would be wave 2's to fix and would block this package's lane for +reasons it cannot act on. The tier-2 replay is exactly the right instrument for that: it produces +the red list without making it a gate. + +## What was re-run after + +* `scripts/ci/spawn_lane_parity.py build-split` +* the G14 name-only-grows check +* `ctest -L unit` + +See `espryt-d2.md` for the readings.