From e19095269bdcc3ea534441a12b7d415a1128192f Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Tue, 22 Sep 2026 13:26:34 -0400 Subject: [PATCH] [docs, MG_Remote] (P7): the roadmap rows say what the tree says, and CONTRACT-P7 is drafted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ROADMAP.md: the Ph / P3b-P4b / P7 rows carry the audit's verdicts and the factual corrections it found - the @P7 refusal list is 15 sites in 4 files (the row printed 8), the 29-commit DirectVulkan shape wave was never recorded, the device divergence is two observations with no per-case attribution and no lockstep control, SetupDrawSnapshot / content-addressed CSO are declined for this stage, "XFB scatter to client" is retired in favour of the two real holes, readback/pack state splits into closed and open halves, the NDK size pin is obsolete, PACK-PBO readback landed in 70df57bb, the ABI fingerprint landed in P6.5, and OQ-8 / OQ-10 / OQ-13 / OQ-21 get their current answers. P6-ENDSTATE-REVIEW.md:284 qualifies an Init.cpp citation the lint reported ambiguous. MG_Remote/CONTRACT-P7.md: rules I (no std::abort on the Magma wire arm) and J (every fix reds once on a two-process arm), the five exit gates in testable form, the retire-vs-decline table for every @P7 name, the ratchet's definition and P7 target, the nine-subsystem denominator for the 40% checkpoint, the wave-2 file partition, and the amendments to CONTRACT-P6. Census, ratchet and lane numbers are marked 待填 until wave 0's packages report them. --- MobileGL/MG_Remote/CONTRACT-P7.md | 158 +++++++++++++++++++++++ docs/Disaggregated/P6-ENDSTATE-REVIEW.md | 2 +- docs/Disaggregated/ROADMAP.md | 22 ++-- 3 files changed, 170 insertions(+), 12 deletions(-) create mode 100644 MobileGL/MG_Remote/CONTRACT-P7.md diff --git a/MobileGL/MG_Remote/CONTRACT-P7.md b/MobileGL/MG_Remote/CONTRACT-P7.md new file mode 100644 index 00000000..31215301 --- /dev/null +++ b/MobileGL/MG_Remote/CONTRACT-P7.md @@ -0,0 +1,158 @@ +# CONTRACT-P7 — Magma(DirectVulkan)全量走完拆分路径 + +权威:本文,与 `CONTRACT-P5.md`(表 0、字节载体、字段归属、R-1…R-17)、`CONTRACT-P5C.md`(规则 E、两个具名豁免、`SEG_EVENT`、守卫)、`CONTRACT-P5E.md`(规则 F、等待规则)、`CONTRACT-MAGMA-RUNAHEAD.md`、`CONTRACT-P6.md`(规则 G/H、死亡漏斗、§12 记录债)、`CONTRACT-P65.md`(两轴传输、布局指纹、`LinkTerms`)并列;与它们不一致处以本文为准,§10 逐条列出。基线:`feat/disaggregated @ 78b7d6be`。`file:line` 均在该提交上读取;路径在 `MobileGL/` 下,除非以 `docs/` 开头。 + +**怎么改。** 集成者的文件。wave 2 的实现包(A / B / C / D / E / F,§9)需要改行时经集成者;包从第一天起就对着下面的行编译。 + +**写自什么。** [`notes/p7/PLAN-PH-P34B-P7.md`](../../docs/Disaggregated/notes/p7/PLAN-PH-P34B-P7.md)(三行逐项审计,66 个代理,每个 done / unnecessary 判定两名反驳者)与 [`notes/p7/INTEGRATOR-DECISIONS-P7.md`](../../docs/Disaggregated/notes/p7/INTEGRATOR-DECISIONS-P7.md)(ID-P7-1..11)。本文只写**规范**——树必须变成什么样、门怎么判;为什么这样定在裁定日志里。 + +--- + +## §0 P7 是什么,以及一条高于每一行的规则 + +P7 收官 = 五道出口门同时成立(§2–§7),而不是路线图 P7 行的交付列逐字做完。路线图行里两项**本阶段拒做**(ID-P7-5:`SetupDrawSnapshot` 探测字段塌 dirty mask、`VertexInputStateFactory` 内容寻址 CSO——它们是 monolith 路径上的性能项,`VulkanRenderer::SetupDraw` 在任何非 monolith 传输下分支到 `SetupWireDraw`,split 下不跑,且改它们动 pull `.text`),一项只做窄半(内部 shader 烘焙的 monolith 臂退役与直通 TCS 烘焙归 P13 / OQ-7 宽半)。 + +**规则 I — Magma 的 wire 臂上没有 `std::abort()`。** 树上每一处 `@P7` 具名拒绝今天都是 `MGLOG_F` + `std::abort()`,绕过 `Session::Fail`、不给对端 `SessionFault` 帧、普查门看不见。P7 之后,`MG_Backend/DirectVulkan` 下任何 wire 臂的拒绝只有两种形状:(a) **decline**——`MGLOG_E_ONCE` + 返回失败 + 与 monolith 臂相同的可观测(屏蔽属性、跳过 blit……);(b) **具名 Fatal**——经 `MG_Pipe` 的 `MGPipeSessionFailHook` 进 `MG_Remote::SessionFail`,带 `FatalFamilies.def` 里的家族词。`MG_Backend` 不 include `MG_Remote`(include 闭包门),hook 由 server 角色初始化安装。规则 I 的牙齿是 §3 的普查门:扩到 server 镜像后,`MG_Backend` 下裸 abort 的站点数只能下降。 + +**规则 J — 每个修复先在两进程臂上红一次。** wave 0 之前树上没有一条车道能让 Magma 两进程用例变红(四条 split 臂硬编码 `MOBILEGL_BACKEND_TYPE=DirectGLES`,`MG_IntegrationTest/CMakeLists.txt:2002/:2025/:2031`),所以 ID-P7-10:车道落地前不派 `@P7` 退役的活;落地后每个退役都带一条在 `integration-magma-spawn`(或 `-tcp`)上先红后绿的用例。 + +--- + +## §1 与前序契约的关系:什么已经不是 P7 的 + +| 项 | 谁做了 | 证据 | +|---|---|---| +| `DynamicBackendParameters` / `MGPCaps` / `RenderStateParameters` 定宽 + 布局指纹 | P6.5 wf(`fe27380a`) | `CONTRACT-P65.md` 「握手与布局」;`CONTRACT-P6.md:666` 仍记在 P7 名下,§10 更正 | +| server buffer consumers、Android 旋转 blit | `38919d45` | `notes/p5f/magma-inproc-fix.md` | +| Magma run-ahead、GPU 延迟退休、VAO 身份碰撞 | `194382c9` | `notes/p5f/magma-runahead.md`;`MG_Backend/Init.cpp:101` `kMGPipeMagmaRunAheadReady = true` | +| packed-float mip 原生 blit、resolve、占位图像、copy-image 端点、XFB 捕获 span、纹理回读 | `ed507b1a..d56c0e83`(随 `e1bf3677` 合入) | `WirePlaceholderImages.inc`、`WireFramebuffer.inc:634-636` | +| 颜色 blit 烘焙(仅 split 臂) | P5f fv | `Renderer/WireColorBlit.{vert,frag,inc}`、`WireColorBlitSpirv.h` | +| D-B8 具名 UBO 的载体 | 直绑常驻 `VkBuffer` range 的备选已在树上 | `UniformManager.cpp:2375` 直绑分支;欠一次 `stage-ubo-named` 字节/帧测量后关 OQ-6 | + +--- + +## §2 出口门 1:集成 + trace 在 Magma 的 push 与 split 下全绿 + +**2.1 车道形状(wave 0 包 L)。** `mgl_itest_register_split_arms` 获得后端维度;DirectVulkan × {Split(inproc), Spawn, Tcp} 三臂的环境为 `MGL_ITEST_VULKAN_{SPLIT,SPAWN,TCP}_ENVIRONMENT`(`MOBILEGL_BACKEND_TYPE=DirectVulkan` + monolith `DirectVulkan.` 臂已用的 ICD 钉)。两档标签: + +- **gating**:`integration-magma-split`(inproc,含义不变)、`integration-magma-spawn`、`integration-magma-tcp`——今天 `integration-magma-split` 的 73 条(及 magma-buffers / magma-runahead / magma-caches 子标签)重铺三臂;三臂**同数绿**才算门 1 的集成半边成立。 +- **informational**:`integration-magma-{spawn,tcp}-all`——所有经共享宏注册的场景 × DirectVulkan × 两进程。首轮红名单是 wave 2 的工作清单;不进 CI 门,直到某条目连续绿后**按名**升入 gating(`test.yml` 的 require_green 名单)。 + +名集合纪律不变:`scripts/ci/spawn_lane_parity.py` 规范化后 split / spawn / tcp 三集合相等;G14 只增不删;每条目私有角色日志(`SplitLogPaths.cmake.in` 由宏累积)。 + +**2.2 臂证明。** Magma 两进程条目必须在 client 私有日志里同时有 `transport=spawn`(或 `control=tcp data=stream`)与 `backend=DirectVulkan`(或等价的 ConfigLoader 行)——一条 Magma 车道静默跑成 GLES 会满足其它所有门。`junit_tally.py` 的 `--require-spawn` / `--require-tcp-ran` 各加后端断言。 + +**2.3 死亡通知前提。** `MG_Remote/Client/WireTables.cpp:740` 只在 DirectGLES 下安装对象死亡通知,Magma 两进程 client 的 `ObjectDeaths` 恒为 0。改成后端无关(wave 0 L);Magma 自己的 `StateObjectDeathOps` 表(wave 2-C)落地前,`CtWireScenario` 的死亡用例在 Magma 臂上按名 skip 并列入 §12。 + +**2.4 trace 半边。** `retrace-split` 已是 39 case × 2 后端 × {inproc, spawn}(`test.yml:2449/:2470`);欠 `iterationrp × DirectVulkan` 的三个旋钮在 retrace-split 作业里与 `:2183` 同样导出(wave 0 L)。门 1 的 trace 半边 = 78 条 DirectVulkan split 行全部达阈值。 + +**2.5 门 1 的判据。** gating 三臂同数绿(【待填:L 包首轮的 73/73 × 3】)+ parity 通过 + retrace-split 78 条 DV 行达阈值 + informational 车道的红名单为空或每条按名归入 P8 / P9 / P13 并在 `notes/p7/` 有票。 + +--- + +## §3 `@P7` 具名拒绝:普查、退役与 decline + +**3.1 普查数(钉住)。** 基线上 `grep -rn "@P7" MobileGL/ --include=*.cpp --include=*.inc --include=*.h` = **【待填:C 包实测;审计两次分别数得 14 串 / 13 语句与 15 处 / 4 文件——以 C 包的 `fatal_census.py --json` 为准】**处,全部在 `Renderer/UniformManager.cpp`、`Renderer/WireFramebuffer.inc`、`Renderer/WireDraw.inc`、`Renderer/VulkanRenderer.cpp`。另有两项 P7 归属但不带 `@P7` 字样:`Fatal{RoleViolation, "buffer-legacy-arm"}`(`WireDraw.inc:14/:204`)与「Magma 无 `StateObjectDeathOps`」(两条集成用例 skip)。 + +**3.2 退役表。** 「退役」= 实现该形状,与 monolith 臂同可观测;「decline」= 规则 I (a)。 + +| 名 | 站点 | 判定 | 形状 | +|---|---|---|---| +| `uniform-buffer-byte-tail` | `UniformManager.cpp:2391` | **退役**(真机 MC 报告 §5 的活边界) | 拷贝窗口外扩到 4 字节边界进 transient slice,再 `vkCmdCopyBuffer` 对齐内部到正确子字目的;`CopyWireBufferRangeToSlice` 扩 | +| `copy-image-in-place` | `VulkanRenderer.cpp:10383` | **退役** | `srcImage == dstImage` 时单次转 `GENERAL`、两侧布局 GENERAL、一次写回;同 mip+layer 且矩形重叠 → decline(GL 未定义) | +| `vertex-layout` | `WireDraw.inc:245`、`VertexInputStateFactory.cpp:439-500` | **拆分** | `buffer-window` 一种保留为协议错(经 hook 的具名 Fatal——它抓过 Redmi 的 VAO 哈希碰撞);其余六种形状/格式原因改 monolith 的「屏蔽该属性继续画」,`BuildWireVertexInput` 出 `unsupportedAttribMask` | +| `default-color-blit-shape` | `WireFramebuffer.inc:601` | **退役** | 恒等变换回落 `vkCmdBlitImage` 臂(`:611-624`);非恒等旋转先 resolve/copy 进 scratch 2D RGBA 再 shader blit(复用 `:560-590` 的 scratch);四旋转之外 decline | +| `multisample-blit-shape` / `-aspect` | `WireFramebuffer.inc:631/:641` | **退役** | shape:resolve 进 scratch 单采样再 `vkCmdBlitImage` 缩放/翻转;aspect:MS 深/模板 → 单采样用 `VK_KHR_depth_stencil_resolve`(`DynamicBackendParameters` 里查扩展)或 `texelFetch(sampler2DMS)` 写 `gl_FragDepth` 的 shader resolve;单采样 → MS 尺寸不同 decline | +| `depth-stencil-mipmap` | `WireFramebuffer.inc:753` | **退役**(随烘焙 (A)) | `GenerateWireMipmap` 深度分支接 `WireDepthMipmap.{vert,frag}` 烘焙程序 | +| `texel-buffer-native-format` | `UniformManager.cpp:1153` | decline | 可选:重打包回落 | +| `unaligned-{texel,storage,atomic}-buffer-range` | `:1161/:1551/:1552` | decline 或拷入对齐 transient | 可选;SSBO 可写范围的 copyback 未定 | +| `storage-buffer-native-range` / `uniform-block-native-range` | `UniformManager.cpp` | decline(钳/拆) | 可选 | +| `uniform-buffer-dynamic-offset` | `:2400` | decline | 可选(>4 GiB) | +| `vertex-format-conversion` | `WireDraw.inc:272` | decline | 可选:packed converter | +| `buffer-legacy-arm` | `WireDraw.inc:14/:204` | 具名 Fatal 经 hook(`RoleViolation`) | 已是拒绝,只换漏斗 | + +**3.3 普查门(wave 0 包 C)。** `scripts/ci/fatal_census.py` 的扫描根扩到 server 镜像(`MG_Remote`、`MG_Pipe`、`MG_Backend`、`MG_Impl/Pipe`、`MG_State`,MG_Test / MG_Benchmark / MG_IntegrationTest 除外);`abort_sites` 成为**向下棘轮**;每个 `Fatal{Word` 在 `FatalFamilies.def` 有行;`Refuse{Word}` 对 `protocol.fbs` `RefuseCode` 校验。baseline 数:【待填:C 包】。 + +--- + +## §4 出口门 4:184 符号棘轮下降 P7 的 101 个 + +**4.1 定义(wave 0 包 R,`scripts/link_ratchet.py`)。** 在 disaggregated 构建的对象树上:按 `notes/p6/a6-link-experiment-data.md` 的路径规则把 `MobileGL.dir` 下对象分 SERVER / FRONTEND / SHARED;集合 = (SERVER 未定义) − (SERVER 已定义) − (SHARED 已定义) ∩ (FRONTEND 已定义)。baseline 存**符号列表**(`scripts/data/link_ratchet_baseline.txt`),`--assert-monotone` 只对新增符号红,消失只提示重基线(ID-P7-7)。基线数:【待填:R 包;a6 为 184 = P7 101 / P3b-P4b 14 / 共有 60 / P6 自己 6】。 + +**4.2 P7 的目标。** `--bucket` 归到 DirectVulkan 引用对象的那一桶(a6 的 101)降到 **0**。唯一还在构造前端 `SamplerObject` / `ShaderObject` / `ProgramObject` 的 DirectVulkan 站点是 `VulkanRenderer.cpp:4526-4583 / 4624-4684`(monolith 臂的隐藏 blit / 深度 mip 程序),其 early-return 是运行时而非 `#if`,所以符号仍被引用。降到 0 的路径:在 **disaggregated 构建里** monolith 臂也改用烘焙模块(§5.2 的 (B')),pull 构建的代码逐语句原样——G1 不动。若 wave 3 实测某桶符号无法在不动 pull `.text` 的前提下消失,按名记入 §12 并在 baseline 里 `# P13` 标注,不算门 4 失败。 + +**4.3 与 P3b/P4b 的 14 个。** 不是 P7 的目标;棘轮落地后 P3b/P4b 的 Tier 1 才可调度。 + +--- + +## §5 内部 shader、反射归档与 resident 上传(wave 2-B / 2-C 的规范) + +**5.1 烘焙 (A)(D)。** `WireDepthMipmap.{vert,frag}` + 生成的 `WireDepthMipmapSpirv.h` + `WireDepthMipmap.inc`(深度附件 render pass + pipeline),`GenerateWireMipmap`(`WireFramebuffer.inc:752-769`)深度分支接入;新鲜度门 `MOBILEGL_BAKED_INTERNAL_SHADERS`:MG_Test 用树内 glslang 重编每个签进树的 SPIR-V 头并逐字节比对,**表驱动**,覆盖 `MG_Util/SelfTest/DriverPostIterationRPWitnessSpv.h` 与 `PrimitivesGeneratedNoXfbProbeSpv.h`。 +**5.2 (B') disaggregated 构建的 monolith 臂改用烘焙模块**(§4.2 需要):`InitializeBlitResources` / `InitializeDepthMipmapResources` / `BlitWithShader` / `GenerateDepthMipmapWithShader` 在 `#if MOBILEGL_BUILD_DISAGGREGATED` 下走烘焙管线;`#else` 分支保留今天的代码逐语句原样。两处 `MagmaP7AllocatorDebtScope` 随之删除(先用临时断言证明它们在非 monolith 传输下从不武装)。 +**5.3 OQ-8。** `LinkArtifacts` 加有序 `storageBlocks{name, binding, dataSize}`(顺序 = stage 序 → 规范化描述符名 → binding,跨 stage 去重,与 `MagmaProgramSource.h:194-195` / `DirectVulkan.cpp:220-260` 今天的资源查询序相同),进 `Visit()`,archive codec 版本 +1(`wireFingerprint` 随之变);`MagmaProgramSource::EnsureStorageBlocks` 与 `DirectVulkan.cpp` 的 `GetProgramResourceCache` 都改读它;`g_programResourceCaches` 及其 rehash 悬挂风险随之删。单测:多 stage + 数组 SSBO + atomic-counter block 的索引序与 SPIRV-Reflect 逐项相同。 +**5.4 OQ-10。** `MG_Backend/Init.cpp` `InitServerRoleCommon` 按 **server 自己的 wire 资源表** 判 `SubDataResident != nullptr` 发布 `kCapResidentSubData`(不按后端枚举猜——ID-39 的教训);`RemoteClientTest.cpp:594` 改期望;integration-magma-buffers 与 integration-split 各一条白盒用例证明发出的是 `BufferSubDataResident(49)`;26.3 in-world 回归。 +**5.5 Magma `StateObjectDeathOps`。** 镜像 `DirectGLES/Managers.cpp:335-474` 的表,从 DirectVulkan 后端注册处安装;删六处 Magma 特判;`PipeSlotPeek` 断言死亡后槽位回落;red-once = 卸表看槽位泄漏断言红。 + +--- + +## §6 出口门 2:verify 零分歧 + +verify 今天只在 monolith 注册(`MG_IntegrationTest/CMakeLists.txt:1684-1760`)。门 2 = **verify × {monolith, split(inproc)} × Magma 零分歧**,且两条既有负控(`VERIFY_CORRUPT`、`POISON_OMIT`)在 split 臂上各红一次。前置债:verify+split 撞旧 `PipeRespecifyScope` 断言(`notes/p65/validation-status.md:118`)——放宽为「按 level 的 producer 各自覆盖其宣告范围」,正反单测各一。trace 侧:8 个 verify case × DirectVulkan × inproc 一轮,分歧计数 0。 + +--- + +## §7 出口门 3 与 5:真机与 CTS + +**7.1 门 3 分母(ID-P7-4)。** `trace_cases.json` 的 CI split 子集 × DirectVulkan × `--use-pbuffer`,排除 `minecraft-1.21.4-rd12-odinlite-in-world` 与 `create-indirect`(OQ-17:`dev@81b17c0b` 起在 Adreno 830 上就坏);`iterationrp` 带 `apk.yml:460-462` 的三个 Magma 旋钮。 +**7.2 门 3 判据。** 同一 reboot-clean 会话内:monolith 对照 1.0;inproc **与** spawn(或 tcp)三遍 ≥ 各 case 现有阈值、OpenRA 1.0、三遍逐位相同(零翻转);`RUN_AHEAD=0` 对照臂一遍记录。证据目录 `docs/Disaggregated/notes/p7/device-window-/`。定位实验顺序 E0–E6 见计划 §3 wave 1。 +**7.3 门 5。** 块:`KHR-GL46.texture_*`、`shader_image_*`、`packed_pixels`、`direct_state_access.*`、`uniform_buffer_object*`;caselist 入库 `tools/cts/caselists/p7-*.txt`(记 suite 版本);先 monolith × DirectVulkan 基线入库 `tools/cts/baselines/`,迁移落地后 inproc × DirectVulkan 比对:每块 pass 率差 ≤ 0.5 pp(Pass/(Pass+Fail),NS 不入分母),**新增 crash = 0 单独硬红**。完整 caselist(~56k)在合 `dev` 前跑,不在关键路径。 + +--- + +## §8 子系统分母与 40% 检查点 + +分母 9 项:(1) Magma 两进程车道 gating 三臂同数绿;(2) §3.2 的六个「退役」;(3) `StateObjectDeathOps`;(4) 烘焙 (A)(D);(5) OQ-8;(6) OQ-10;(7) verify×split;(8) 真机 ssim 1.0;(9) CTS 五块 ≤0.5 pp。**中点** = wave 2 的 A / B / C 三簇全部合入集成树之时;届时完成 < 4/9 → 停下重定基线(路线图唯一幸存的再基线绊线,此前没有分母、不可执行)。 + +--- + +## §9 wave 2 的文件分区与合并规则 + +| 簇 | 文件 | 内容 | +|---|---|---| +| A | `Renderer/UniformManager.cpp` | §3.2 的 UBO / SSBO / texel 对齐与 native-range 行 | +| B | `Renderer/WireFramebuffer.inc`、`Renderer/VulkanRenderer.cpp`、新 `WireDepthMipmap.*` | copy-image、default-color-blit、multisample、深度 mip 烘焙 (A)(D)、(B')、AllocatorDebtScope | +| C | `Renderer/VertexInputStateFactory.cpp`、`Renderer/WireDraw.inc`、`Renderer/VkBufferManager.cpp`、`MG_Backend/Init.cpp`、`Renderer/MagmaProgramSource.h`、`MG_State/.../ProgramArtifacts.h` | vertex-layout 拆分、`StateObjectDeathOps`、OQ-10、OQ-8 | +| D | `MG_Backend/DirectGLES/*`、`MG_State/*`、`MG_Impl/Pipe/*`、`MG_IntegrationTest/*` | P3b/P4b 的 Espryt 项(与 A/B/C 零重叠) | +| E | `docs/`、契约 | 已落地项更正、OQ 关闭、`MEASUREMENTS.md` §7.2 同名重跑 | +| F | `MG_Remote/Transport/*`、`MG_Remote/Server/ServerMain.cpp`、`Handshake.h`、`Protocol/protocol.fbs` | Ph 小件(令牌、D11 五处、PH-8 单测) | + +合并规则:集成者串行合并;每次合并后 gating 三臂 + `link_ratchet.py --assert-monotone` + G1 + parity;**棘轮上升的提交拒收**;每包一条 red-once 记在 `notes/p7/`;性能只记录不设门(ID-P7-9)。实现方 `opus`、审查方 `fable`(ID-P7-8)。 + +--- + +## §10 对前序契约的更正 + +1. `CONTRACT-P6.md:666`(§10.3)把 `DynamicBackendParameters` 定宽记在 P7 名下——已由 P6.5 wf 落地,P7 不再持有。 +2. `CONTRACT-P6.md` §12.1「棘轮在 CI 里重算 184 并断言只降」——由 wave 0 包 R 落地为 `scripts/link_ratchet.py`;「移交 P6.5」从未被 P6.5 接收,归 P7。 +3. `CONTRACT-P6.md` §12.2 D11 把五行中的三行分给 P6 `dl`——树上五处全部仍在原状态(`PipeApply.cpp:1575`、`PipeApplier.cpp:444`、`ProgramArtifactsCodec.cpp:309`、`StagedTextureStore.h:440`、`SlotTables.h:347/:371`);归 Ph(计划 §1.1 D11),wave 2-F 做。 +4. `CONTRACT-P6.md` §5.2「`Session::Fail` 在 P6 保持 `[[noreturn]]`」——Ph 的翻转按 ID-P7-1 重定界,不做 98 站点的字面翻转;`Server/StagedShadow.h:115`、`Server/StagedTextureStore.h:344` 两处旁路由 wave 0 包 C 收进漏斗。 +5. `ARCHITECTURE.md` §8.5「XFB scatter 在 client」——树上取的是 server staged shadow + `OnBufferWriteback`(P5c/P5f);`OnXfbScatterReady` 是死声明,删除。 + +--- + +## §11 不是 P7 的 + +- `SetupDrawSnapshot` dirty mask、`VertexInputStateFactory` 内容寻址 CSO(ID-P7-5)→ 优化阶段。 +- 内部 shader 烘焙的 pull 构建 monolith 臂退役(动 pull `.text`)、直通 TCS 烘焙(64 模块)→ P13 / OQ-7 宽半。 +- `MG_Util` 头/对象库拆分 → P13。 +- Ph 的 fuzz 臂 2(对端字节可达站点逐站点闩转换)、PH-6、PH-7 (4)(5) → P7 之后(计划 wave 5)。 +- P3b/P4b 的 CTS AFTER、Iris 普查的 P9 例外(`texture-remint-pull`)→ 各自阶段。 + +--- + +## §12 记录债 + +- Magma 两进程 client 在 `StateObjectDeathOps` 落地前 `ObjectDeaths=0`:`CtWireScenario` 死亡用例在 Magma 臂按名 skip(§2.3)。 +- 门 3 的「不确定」在 wave 1 E0 之前无法区分「同 case 多次结果不同」与「不同 case 各自低于阈值」;两个历史点值(0.988998 / 0.976494)无 per-case 归属。 +- `MEASUREMENTS.md` §7.2 的同名比对自 P5b 起未重跑;「22 → texture readback」「3 → query」两行债务的关闭以 wave 3 的重跑为准。 +- Android 模拟器 retrace 车道每轮 2–6 例 flaky(含 monolith 对照):门 1 的任何模拟器证据都先过「连续 N 轮绿」再算数。 diff --git a/docs/Disaggregated/P6-ENDSTATE-REVIEW.md b/docs/Disaggregated/P6-ENDSTATE-REVIEW.md index 5ddeca60..dbf2e7a9 100644 --- a/docs/Disaggregated/P6-ENDSTATE-REVIEW.md +++ b/docs/Disaggregated/P6-ENDSTATE-REVIEW.md @@ -281,7 +281,7 @@ red-once:**改成从超时置位闩锁,则配对的正控制"server 落后 > `MGPipeRunAheadCapBitsFor(...)` 与 `ConsumedSubsystemsFor(ActiveBackendType)` 要挪到 server 侧。 > 注意一个被多处写错的细节:**CallMask 的能力位那一半已经读 server 自己的 backend 了** -> (`Init.cpp:184-211` 读 `loop.Backend()->GetBackendFunctions()`,代码里带了理由)。只有那两个函数需要搬。 +> (`MG_Backend/Init.cpp:184-211` 读 `loop.Backend()->GetBackendFunctions()`,代码里带了理由)。只有那两个函数需要搬。 ### 5.5 `t6` 的出口门加三条负控制、两个必测数字 diff --git a/docs/Disaggregated/ROADMAP.md b/docs/Disaggregated/ROADMAP.md index 7735982e..4db13470 100644 --- a/docs/Disaggregated/ROADMAP.md +++ b/docs/Disaggregated/ROADMAP.md @@ -1,6 +1,6 @@ # MGPipe 路线图 -> 状态:**P0、P0.5、P1、P2、P3a、P4a、P5、P5b、P5c、P5d、P5e、P5f 已收官**。P5f 于 2026-09-20 完成主机门、Redmi 六个 clean-boot 臂、跨模型族审查及修复验证;最终验收代码为 WSL `cfca93c7885fd8db1e881f91189ba59090ae9c52`(Windows `c42577a4` 等价)。证据见 [`notes/p5f/close-report.md`](notes/p5f/close-report.md)、[`close-review.md`](notes/p5f/close-review.md)、[`device-report.md`](notes/p5f/device-report.md)。**P6 已收官(2026-09-22)**:全部包(a6 / c6 / lk / so / sm / cp / hs / dl / st / t6)已落地于 `feat/disaggregated`(头 `16bfab10`,2026-09-21),出口门第 1–6 项此前已达成;**第 7 项**(Redmi `2f7cbe2e` 的 reboot-clean 同热窗口配对 A/B)与**第 8 项**(三个强制性能数)已于 2026-09-22 采齐——门 7 判读为 **tie**(inproc vs spawn 的 client CPU p50 差 −0.15% / +0.16%,均在臂内散布 0.2–4.2% 之内,符号随臂序翻转;monolith 基线约贵 30%),门 8 三数齐:门铃 A/B tie(`clipark` 略差)、`SEG_STAGE` 字节/帧、分块后记录/帧。证据 [`notes/p6/gate7-device-ab.md`](notes/p6/gate7-device-ab.md)、[`notes/p6/gate8-doorbell-device.md`](notes/p6/gate8-doorbell-device.md)、[`notes/p6/gate8-wire-counters.md`](notes/p6/gate8-wire-counters.md)。逐包状态、出口门逐项、证据见 [`CURRENT_STAGE_PROGRESS.md`](CURRENT_STAGE_PROGRESS.md);设计见 `ARCHITECTURE.md`。P5e 的历史性能与 E1 对照债保留在阶段行、[`P5E-RUNAHEAD.md`](P5E-RUNAHEAD.md) 和 `MEASUREMENTS.md`,不由 P5f 的新对照代为关闭。**CI / inproc 功能补齐已收官(2026-09-21)**:拆分主产物 + inproc 主验收、完整 retrace 双 transport、18 项 CI 门、双 ABI APK / AVD 全绿并合入 `feat/disaggregated`(`e1bf3677`),见 `CURRENT_STAGE_PROGRESS.md` §2.8。 +> 状态:**P0、P0.5、P1、P2、P3a、P4a、P5、P5b、P5c、P5d、P5e、P5f 已收官**。P5f 于 2026-09-20 完成主机门、Redmi 六个 clean-boot 臂、跨模型族审查及修复验证;最终验收代码为 WSL `cfca93c7885fd8db1e881f91189ba59090ae9c52`(Windows `c42577a4` 等价)。证据见 [`notes/p5f/close-report.md`](notes/p5f/close-report.md)、[`close-review.md`](notes/p5f/close-review.md)、[`device-report.md`](notes/p5f/device-report.md)。**P6 已收官(2026-09-22)**:全部包(a6 / c6 / lk / so / sm / cp / hs / dl / st / t6)已落地于 `feat/disaggregated`(头 `16bfab10`,2026-09-21),出口门第 1–6 项此前已达成;**第 7 项**(Redmi `2f7cbe2e` 的 reboot-clean 同热窗口配对 A/B)与**第 8 项**(三个强制性能数)已于 2026-09-22 采齐——门 7 判读为 **tie**(inproc vs spawn 的 client CPU p50 差 −0.15% / +0.16%,均在臂内散布 0.2–4.2% 之内,符号随臂序翻转;monolith 基线约贵 30%),门 8 三数齐:门铃 A/B tie(`clipark` 略差)、`SEG_STAGE` 字节/帧、分块后记录/帧。证据 [`notes/p6/gate7-device-ab.md`](notes/p6/gate7-device-ab.md)、[`notes/p6/gate8-doorbell-device.md`](notes/p6/gate8-doorbell-device.md)、[`notes/p6/gate8-wire-counters.md`](notes/p6/gate8-wire-counters.md)。逐包状态、出口门逐项、证据见 [`CURRENT_STAGE_PROGRESS.md`](CURRENT_STAGE_PROGRESS.md);设计见 `ARCHITECTURE.md`。P5e 的历史性能与 E1 对照债保留在阶段行、[`P5E-RUNAHEAD.md`](P5E-RUNAHEAD.md) 和 `MEASUREMENTS.md`,不由 P5f 的新对照代为关闭。**CI / inproc 功能补齐已收官(2026-09-21)**:拆分主产物 + inproc 主验收、完整 retrace 双 transport、18 项 CI 门、双 ABI APK / AVD 全绿并合入 `feat/disaggregated`(`e1bf3677`),(原记 `CURRENT_STAGE_PROGRESS.md` §2.8;该文档已为 P6.5 重写,原文在 git 历史)。**2026-09-22 起进入 Ph / P3b-P4b / P7 统筹推进**:三行逐项审计、判定与波次见 [`notes/p7/PLAN-PH-P34B-P7.md`](notes/p7/PLAN-PH-P34B-P7.md),裁定见 [`notes/p7/INTEGRATOR-DECISIONS-P7.md`](notes/p7/INTEGRATOR-DECISIONS-P7.md)。 > **P5f 后续 Magma run-ahead 已完成**(`194382c9`,2026-09-20):主机真实排队、credit、负控及 Vulkan 同步验证通过,Redmi 同包 Magma 开/关与 GLES 三臂 FCL 世界实测通过。见 [报告](notes/p5f/magma-runahead.md)。P6 / P7 全阶段状态不因此改变。 @@ -36,11 +36,11 @@ | **P5f** 一切状态上 wire | ✅ **已收官(2026-09-20)**;验收代码 Windows `c42577a4` / WSL `cfca93c7885f` | f0 普查、f1 双块、fc 控制帧、fe Espryt 字段、fm Magma record consumers、fs 静态世代/角色及 liveness、fr registry、fv 反向回调均已合并。字段归属 **41 RECORD_SUPPLIED / 6 APPLIER_DERIVED / 0 BARRIER_PULLED / 16 FATAL**;strict / dualblock 预期 marker 集合均空。控制帧与静态量工作已完成,不再列为 P6 待实现项 | unit **2310 = 2300 PASS + 10 skip**;GPU **1377** 零失败;ordinary / strict split **180 = 176 PASS + 4 skip**;双块 **212 = 206 PASS + 6 精确具名 skip**;双后端 RSP 门 **2 PASS / 0 skip**、逐帧 rsp=0。G1 `.text` 10806051、symbols 27815 恒等且 0/0/0/0;G2 3016 同名;G14 3646→3744 无删名。逐包与收官修复均有 red-once;Claude 异族终审 P1/P2 已修;Redmi 六 clean-boot 臂 **60 PASS / 6 skip / 0 failed**、36 个窗口 rsp=0。详见 [`close-report`](notes/p5f/close-report.md) | | **P6** spawn transport | ✅ **已收官(2026-09-22)**;全部包已落地于 `feat/disaggregated`(头 `16bfab10`,2026-09-21),出口门第 1–6 项此前已达成,第 7/8 项于 2026-09-22 采齐。收官前核出的三项:server 进程侧 `PipeStats` 从未初始化(`srv=0 srvpark=0` 是结构性零,门 8 无 server 半边)**已在收尾中修好**;184 符号棘轮 CI 门(契约 §12.1)与契约 §2 分给 hs 的 `LinkTerms` / `Refuse` / 指纹拆分**未落地**,移交 P6.5(负控 S6 随之) | 十包全落地:**a6** 进程装配/链接边界审计 → **c6** 规范契约 + 数据面缝惰声明 → **lk** `RingControl` 按写者重组 → **so** `SocketTransport`(AF_UNIX SOCK_STREAM + SCM_RIGHTS,12 条契约用例)→ **sm** 两个独立启动的进程(非 fork,name 汇合、共享匿名段,四守卫接线)→ **cp** EGL 控制帧跨进程并应答(`InitCapabilities` wire kind 11)→ **hs** build stamp 显式 present 入指纹 + `abiMajor/Minor` 补检 + 真实 pid → **dl** device-lost 闩(取自描述符挂断绝不取自超时)+ `Session::Fail` 漏斗(`FatalFamilies.def` 词表 + 90 站点归一 + `SessionFault` 帧命名家族)+ Fatal 普查门 → **st** fb-slot memo 具名 Fatal → **t6** `integration-spawn` 车道(102/102)+ 名集合结构性一致门 + per-role 日志(`.client.log` / `.server.log`)。Android CI 新增 `spawn-acceptance` 臂,App 从 `nativeLibraryDir` 解析 server 路径。真机 Redmi `2f7cbe2e` 上 `OpenRA.DirectGLES` spawn ssim=1.0 连跑三次 + 6 case 绿;`DirectVulkan` 真机分离路径不确定分歧(inproc 与 spawn 同表现→ Magma × 真实 GPU,非 P6,桌面 lavapipe 为 1.0)。边界仍为 pbuffer / surfaceless / 离屏;真窗口归 P12。契约 [`MG_Remote/CONTRACT-P6.md`](../../MobileGL/MG_Remote/CONTRACT-P6.md);a6 产出 [`a6-audit-v1.md`](notes/p6/a6-audit-v1.md)、[`a6-link-experiment.md`](notes/p6/a6-link-experiment.md)(**server 不能不链 `MG_Impl`**:184 符号,P7 101 / P3b-P4b 14 / 共有 60 / P6 自己 6);终局重审 [`P6-ENDSTATE-REVIEW.md`](P6-ENDSTATE-REVIEW.md)。**收尾四项(2026-09-22,工作树未提交)**:wire 计数器——`PipeStats` 新增 `ByteClass::StageSegmentBytes`(`PipeWireCodec.cpp:878` `StageAllocate` 唯一收口)与 `CallClass::WireRecords`(`:1188` `EncodeRecord` 提交路径)+ staged-blob 直方图,汇总行新增 `seg=` / `wrec=`;`ServerMain.cpp` 补 `PipeStats::Init()` / `Shutdown()`(spawn server 此前从不武装计数器——修前 0 条汇总行、修后 29 条,SSIM 1.0 不变);`MOBILEGL_PIPE_STATS_FILE` 按角色派生 `.client.json` / `.server.json`(走 `RoleLogPath` 同一导出规则,基名不指向文件);工具入库 `tools/device_bench/p6/{ab_session.py,render_ab.py,README.md}` 与 `tools/trace_replay/run_android_retrace_local.py`(+19 行 `MOBILEGL_TRACE_PACKAGE`),`pin_device.sh` 新增 `2f7cbe2e` 条目(本板 GPU 钳 1050 MHz:`thermal_pwrlevel` 写 0 读回 1、`max_gpuclk` 只读 1 050 000 000;绝对值与 1100 MHz 时代的 `35d0befa` 行不可比)。 | 出口门(契约 §9)1–6 ✅:G1 pull 0/0/0/0、`.text` 恒 `0xa52203`;`integration-spawn` 与 split 名集合一致(可比 102==102)且同数绿;进程树运行时恰多一子进程、结束为零;每条 spawn 条目记子进程 pid 与 `transport=spawn`(`--require-spawn` 门);每包 red-once。**7/8 已采(2026-09-22)**:**门 7** 真机 reboot-clean 同热窗口配对 A/B(Redmi `2f7cbe2e` / M332BF / SM8750 / Adreno 830v2,CPU 定频 little 1555200 / big 1958400,GPU 钳 1050 MHz(本板 `thermal_pwrlevel` 写 0 读回 1、`max_gpuclk` 只读 1 050 000 000;绝对值与 1100 MHz 时代的 `35d0befa` 行不可比,只有同会话配对可比),`minecraft-1.21.4-rd12-odinlite-in-world` + DirectGLES,~1471 draws/帧;六臂交错 × best-of-3:18/18 runner 退出 0、36/36 pin check `PINNED`、0 `Fatal`;client CPU p50 ms/帧 inproc 7.880/7.889 vs spawn 7.876/7.869,均值 **−0.15%**,符号随臂序翻转,臂内散布 0.2–4.2%;第二会话 inproc/spawn 交错 × best-of-2:4/4 OK、8/8 `PINNED`、0 `Fatal`,7.987/7.989 vs 7.992/8.009 = **+0.16%**)——判读 **tie**(差值在臂内噪声内),如实记录、不设门;monolith 基线约贵 30%(−29.8% / −29.9%)。**门 8①** socket 门铃 vs inproc condvar:client 121.1 waits/帧、5.6–6.1 parks/帧,两传输逐字相同(run total 30 401–30 407);server inproc 10 866–11 963 waits/帧、5.0–6.2 parks/帧,spawn 10 415–10 416 waits/帧、4.66–4.90 parks/帧——socket 阻塞读**既不更便宜也不更贵**(契约 §9「阻塞读可能更便宜」未兑现),spawn server waits 少 8.9–12.9% 归因于 handoff 纪律而非门铃本身,唯一 socket 略差的列是 `clipark/f`(6.07 vs 5.60/5.75)。**门 8②③**(inproc,真实 trace retrace):`SEG_STAGE` 字节/帧 OpenRA 130.8 KB median / 8.01 MB steady mean(含启动负载 8.07 MB),rd12 816.2 KB median / 1.53 MB steady mean(含负载 10.79 MB,rd12 首帧 981 654 draws vs 稳态 ~1471,run-wide mean 约 7× 稳态,两个读法都报);分块后记录/帧 OpenRA 211 median / 206 mean,rd12 7 497 median / 7 504 mean;`maxrec=1808` 与分块前相同(默认 8 MiB chunk 预算在这些负载上从未被打到)。证据 [`notes/p6/gate7-device-ab.md`](notes/p6/gate7-device-ab.md) / [`notes/p6/gate8-doorbell-device.md`](notes/p6/gate8-doorbell-device.md) / [`notes/p6/gate8-wire-counters.md`](notes/p6/gate8-wire-counters.md) | | **P6.5** 传输栈两轴化 + 跨机 | **第一波已落地**(`feat/disaggregated@fe27380a`,2026-09-22):全 TCP 控制 + StreamLink 数据,WSL client ↔ Redmi server。四切片代码审查无硬缺陷 + 两修复(`AcceptPair` 重试 `EINTR`/`ECONNABORTED`、supervisor 自设 `MOBILEGL_IPC_ROLE=server`,均 `MG_Remote` 门内 G1 不动,见 [`code-review-findings.md`](notes/p65/code-review-findings.md));固定制品(两端 stamp `p65-acceptfix-20260922`)再验收:unit 2399、integration-tcp loopback 102、**device-102 102 全 ARMED**、代表性 retrace OpenRA 1.0 全 ARMED。**残余(CI/后续)**:完整 39 例 device golden 矩阵 + 必测数。设计见本表下方「立即的下一项」节 | 包:**wf** wire 定宽与布局摘要——`wireFingerprint` = `PipeFields.def` 派生的逐成员 name / `offsetof` / `sizeof` 摘要 + 有序目录摘要 + 记录头布局 + 两个 blob codec 版本 + `kOpCount` + 字节序 / 指针宽度,**保留** `sizeof(MGPCaps)` / `sizeof(DynamicBackendParameters)`(wire 事实)、删 `sizeof(GLFunctionsTable)`;`buildFingerprint` 只在 `Dial == Fork` 下比较;`DynamicBackendParameters` / `MGPCaps` / `RenderStateParameters` 整块 blob 的定宽化(两端是不同编译器产的不同二进制,`long` / padding / 位域差异都是静默读错状态);`Refuse{code, detail, 对端值}` 控制消息,握手路径零 abort → **ct** 控制面端点种类(`fork` 继承 fd / `unix:` / `tcp://host:port`;`DialMode{No, Fork, Connect}` 与 `MGPipeShouldDial()` 按契约 §3 补齐;TCP keepalive 失败**作为传输层报告的挂断**进 dl 的闩,不是 apply 超时)→ **nd** 数据面协商(`LinkTerms{dataPlane, delivery, wireForm, maxReplyBytes, cmdWindowBytes, stageWindowBytes}` 入 Hello / Welcome,四个尺寸由 **server** 陈述;`dataPlane ∈ {SharedSegments, Stream}`;`auto` 的判据是**段实际交付成功**而不是地址判断,回落必须具名入日志与 stats;链路工厂在会话建立时选定一对,之后不变——缝是 setup-time 的,契约 §8.2)→ **sd** 共享段交付与控制面解耦(`ShmLink` 自带 AF_UNIX aux 汇合名、在 `Welcome` 里公布,`SCM_RIGHTS` 只走它;于是**控制面 TCP + 数据面共享段**在同机是合法配对;`ITransport` 收窄为纯控制帧,描述符传递归数据面)→ **sl** `StreamLink`(分块封帧;watermark 变消息且**规则逐字保留**——late-never-early、`>=` 不是 `==`、倒退是 Fatal;`appliedSeq` 修正案 + flush-on-idle;reply 变自带 seq 的消息,本链路上删 slot 池 / 取模 / stamp 自检;`SEG_STAGE` 变发送窗口,三个 cursor 要么完整复活要么不用、不留中间态;program archive 与 `draw_vbo` range 尾分片;`GetCaps` 两个 blobref 变消息;每方向每进程一条专用读线程)→ **t65** 车道。上层纯度:`SessionProducer` / `SessionConsumer` / `ServerLoop` / `PipeWireEncoder`、`ClientSession.cpp` 的 `kSegEvent` 挂载与 `ResourceTracker.h` 的 writeback 解析都只经 `ILink`。设计 `ARCHITECTURE.md` §11.9 | 门:inproc / spawn 车道结果数与逐线程 CPU 逐字不变(`ILink::ReserveRecord` 虚调用代价**实测**,`RingProducer::Reserve` 失去内联是具体风险);纯度 grep——`ShmLink` / `StreamLink` / `RingControl` / `ReplySlotPool` / `EventRingConsumer` / `m_shm.` 只出现在 `Transport/` 与其测试,上层零链路种类分支;**2×2 矩阵车道**(控制面 {unix, tcp} × 数据面 {shm, stream},loopback)名集合与 spawn 一致且同数绿,每条目记 `control=… data=…` 的 arm 证明(ID-124 的形状);跨机臂一条真 trace 逐像素;wf 三条 red-once(临时树里同宽成员互换 → 摘要变而 stamp 不变;`wireMajor = 99` → 两端具名拒绝、server exit 0、client 不回落 monolith;仅 stamp 不同的对端在 `Dial != Fork` 下连接成功——正控制);**必测数**:逐帧 `kWaitReply` 次数(`ResourceCreate` / `SetTextureParams` / 纹理半边 `ResourceSubData` 都在此列,TCP 上每次即一个 RTT)、`SEG_STAGE` 字节/帧对链路带宽、`PRESENT_CREDIT` 1..3 配对、混搭(tcp + shm)对(unix + shm)的逐线程 CPU 差 | -| **Ph** 不可信对端加固 + 配对 | 待排,**P12 非 loopback 监听之前** | `Session::Fail` 的策略翻成每会话闩(每个依赖 `[[noreturn]]` 的站点造真实返回路径,不是一个函数翻一下;P6 dl 已把站点收口到一处);handle slot 预算(`BackendSlotTable` 的两条拒绝从 `MOBILEGL_ASSERT` 变 release 下的具名拒绝,杜绝静默 null twin);readback 尺寸门挪 server 侧且在 resize **之前**设绝对上限;`StagedTextureStore` 按该 level 宣告范围设界;`ArchiveVector` 按 `count * sizeof(element)` 设上限;`SEG_EVENT` 溢出不再能让一个仅仅不排空的对端 60 秒杀掉宿主渲染器;**配对 / 认证**(`Hello` 带配对令牌,无令牌只允许 loopback;令牌够不够、要不要 TLS 见开放问题 21);段 / 窗口尺寸由 server 钳制(P6.5 nd 已陈述) | 非 loopback 监听在无令牌时具名拒绝;畸形帧 / 超界计数 / 不排空对端的模糊臂下 server **不 abort、会话闩住、下一连接照常服务**;`Session::Fail` 站点普查门继续零新增;契约 §12.2 五处无界分配各一条 red-once | -| **P3b / P4b** 深化(Espryt) | 待排 | 按存储属主键控的发射游标与 view 索引重映射;`g_fboTextureSyncList`;`ResolvedTextureBindingMemo` / `SamplerPassMemo` / image sweep / program registry 重键;XFB scatter 搬到 client;删 fragColor 重推导 workaround 与 `g_broadcastMemo*`;raw-depth-fetch sampler 的 monolith 清理(transport 原生臂已由 P5f fs 落地);回读 / pack state;P4a 记下的 R-3 / R-4 / R-5 / R-7 / R-10 / R-11;`ProgramArtifacts.h` 的 NDK 尺寸钉;链接实验分给它的 **14 个符号**(D12) | 纹理 / program 场景;CTS `texture_*` / `shader_image_*` / `packed_pixels` 在 0.5 pp 内;每一个 Iris trace;`TextureUploadShapeScenario` 升级成门 | -| **P7** DirectVulkan(Magma)全量迁移 | 部分已提前落地,阶段未收官 | `38919d45` 已补实际游戏的 server buffer consumers 和 Android 旋转 blit([报告](notes/p5f/magma-inproc-fix.md));`194382c9` 又完成 Magma run-ahead、GPU 延迟退休与 VAO 身份碰撞修复([报告](notes/p5f/magma-runahead.md));其余工作:其余子系统:`SetupDrawSnapshot` 探测字段塌成 dirty mask;占位纹理原生化;具名 UBO host payload(D-B8);内部 shader 烘焙;`VertexInputStateFactory` 内容寻址 CSO;D18 容器纪律保留。**P6 真机发现(2026-09-22 归此)**:`DirectVulkan` 分离路径在 Redmi 上分歧且不确定(0.976–0.989,inproc 与 spawn 同表现,pbuffer monolith 1.0)——Magma × 真实 GPU;树上 `@P7` 具名拒绝清单(multisample-blit、depth-stencil-mipmap、vertex-format-conversion、texel-buffer-native-format、unaligned-*-range、uniform-buffer-byte-tail / dynamic-offset、copy-image-in-place、Magma 无 `StateObjectDeathOps`);链接实验分给 P7 的 **101 个符号**(D12)。`DynamicBackendParameters` 定宽重写**不再是 P7 的**——它是跨平台 wire 的前提,归 P6.5 wf | 集成 + trace 在 Magma 的 push 与 split 下全绿;verify 零分歧;真机 DirectVulkan split ssim 回到 1.0;184 符号棘轮(契约 §12.1)下降 P7 的 101 个——原 "`nm -D libMobileGLServer.so \| grep glslang` 为空" 不可达,D12 裁定 server 镜像就是整个 `libMobileGL.so`;CTS 0.5 pp 内。**再基线检查点:中点完成子系统 < 40% 立即重定基线** | +| **Ph** 不可信对端加固 + 配对 | **已审计(2026-09-22,`notes/p7/PLAN-PH-P34B-P7.md` §1.1)**:P6.5 已在 LAN 上跑 `tcp://0.0.0.0`,「P12 之前」的顺序陈述落后于树。必需小件(supervisor 命名子进程死亡、两处漏斗旁路、D11 五处上限、常量时间令牌 + 数据面绑定、`SEG_EVENT` 弃投闩)随 P7 波次推进;fuzz 臂 2 在 P7 之后;OQ-21 已裁定令牌足够(ID-P7-3) | `Session::Fail` 的策略翻成每会话闩(**按 ID-P7-1 重定界**:98 处 `SessionFail` + 6 处 `WireLogFatal` 的字面翻转拒做——≥9 处返回引用没有诚实返回值;只对对端字节可达站点 latch-and-decline;P6 dl 收口到的是**两个漏斗 + 两处头层旁路**(`Server/StagedShadow.h`、`Server/StagedTextureStore.h`),不是一处;P6.5 fork-per-session 已给出「下一连接照常服务」);handle slot 预算(`BackendSlotTable` 的两条拒绝从 `MOBILEGL_ASSERT` 变 release 下的具名拒绝,杜绝静默 null twin);readback 尺寸门挪 server 侧且在 resize **之前**设绝对上限;`StagedTextureStore` 按该 level 宣告范围设界;`ArchiveVector` 按 `count * sizeof(element)` 设上限;`SEG_EVENT` 溢出不再能让一个不排空(或仅涓流排空)的对端在 30 秒内、乃至瞬间用 `Fatal{EventRingOverflow}` 打掉承载它的 server 进程(drop-with-latch,不等 PH-1,ID-P7-2;原文「60 秒」是两轮 30 s 的算术上界);**配对 / 认证**(`Hello` 带令牌与无令牌只 loopback **已由 P6.5 ct 落地**;欠常量时间比较、`Refuse{Authentication}` 入词表、≥16 字节、**数据面按 `Welcome.dataNonce` 绑定到已认证的控制连接**(今天 `AcceptPair` 按到达顺序配对、从不查 peer)、fork 前认证;OQ-21 裁定令牌足够、不做 TLS);段 / 窗口尺寸由 server 钳制(P6.5 nd 已陈述,欠一条钳制单测) | 非 loopback 监听在无令牌时具名拒绝(机制已在;名字入词表 + `tcp_supervisor_smoke.py` 接 CI 后算达成);畸形帧 / 超界计数 / 不排空对端的模糊臂下 server **不 abort、会话闩住、下一连接照常服务**(臂 1 机制已在、欠端到端脚本;臂 2 = PH-1 (3)(4) + D11;臂 3 = PH-6);`Session::Fail` 站点普查门扩到 server 镜像且 `abort_sites` 变棘轮(今天只扫 `MG_Remote`、站点数记了不比,wave 0);契约 §12.2 五处无界分配各一条 red-once(**五处全开**,不是两处) | +| **P3b / P4b** 深化(Espryt) | **已审计(2026-09-22,`notes/p7/PLAN-PH-P34B-P7.md` §1.2)**;Espryt 项与 P7 文件零重叠,作为 P7 的并行流(wave 2-D)推进 | view/属主发射游标**别名场景**(代码半已由 P4a `TextureEmit.h` 属主键控游标 + `TextureObjectView::ToOwner*` + P5e tx2 落地,欠验证);`g_fboTextureSyncList`(分离安全——记录臂先返回、退路是具名 Fatal;四个 resolver 改启动期具名 stop,文本删除受 P5e 裁定 1 约束归 P13);memo 重键**已落地**(P4a/P5f),补纯度 grep 门;~~XFB scatter 搬到 client~~(P5c/P5f 以 server staged shadow + `OnBufferWriteback` 落地;剩两处真洞:孤儿捕获目标被静默丢弃、回写事件无界——>128 KiB 即 `Fatal{EventRingOverflow}`);删 fragColor 重推导 workaround 与 `g_broadcastMemo*`(动 pull `.text`,归 P13,只改注释);raw-depth-fetch sampler 的 monolith 清理(可选);**回读收口**(pack 半已关:`set_pixel_pack_state` APPLIER_DERIVED + server 中性读 + client 侧 PACK-PBO 散射;readback 半开:`get-tex-image-shadow` / `copy-image-shadow-mirror` 非 monolith 下仍 abort、split 零覆盖);P4a 的 R-5(D-K2 规则合一处)/ R-11 必须,R-3 / R-4 / R-7 / R-10 可选;~~`ProgramArtifacts.h` 的 NDK 尺寸钉~~(P6.5 portable archive v2 + 布局指纹取代);链接实验分给它的 **14 个符号**(D12,棘轮落地后 Tier 1) | 纹理 / program 场景(split 三臂零覆盖,先普查首阻塞再注册);CTS `texture_*` / `shader_image_*` / `packed_pixels` + P4a 欠的 `direct_state_access.framebuffers*` 在 0.5 pp 内(caselist 入库 + monolith 基线 + delta 工具,今天三者皆无);每一个 Iris trace(CI 管道 P6 已建,欠当前头的结果与 `texture-remint-pull` 的 P9 例外表);`TextureUploadShapeScenario` 升级成门(Mali 增量无设备,按 Adreno 记录) | +| **P7** DirectVulkan(Magma)全量迁移 | **进行中(2026-09-22 起)**:审计 + 五波计划见 `notes/p7/PLAN-PH-P34B-P7.md` §1.3 / §3;wave 0(Magma 两进程车道、`scripts/link_ratchet.py`、普查门扩容 + Magma 漏斗入 `Session::Fail`、`CONTRACT-P7.md`、设备跑器选后端)开工;子系统分母 9 项,中点 = wave 2 合并完成 | `38919d45` 已补实际游戏的 server buffer consumers 和 Android 旋转 blit([报告](notes/p5f/magma-inproc-fix.md));`194382c9` 又完成 Magma run-ahead、GPU 延迟退休与 VAO 身份碰撞修复([报告](notes/p5f/magma-runahead.md));`ed507b1a..d56c0e83` 29 个 DirectVulkan 提交的 shape 波(随 `e1bf3677` 合入,本行此前未记)已退役 packed-float mip 原生 blit(`5310ff62`)、resolve(`ec4ca06d`)、占位图像(`WirePlaceholderImages.inc`)、copy-image 端点、XFB 捕获 span、纹理回读;`70fb6689` 链关闭 inproc RD32 性能回归(86.85→116.73 fps)。其余工作(2026-09-22 审计改判):~~`SetupDrawSnapshot` 探测字段塌成 dirty mask~~ 与 ~~`VertexInputStateFactory` 内容寻址 CSO~~ **本阶段拒做**(`SetupDraw` 在非 monolith 传输下分支到 `SetupWireDraw`,monolith 快照机制在 split 下不跑;无性能门;ID-P7-5);占位纹理原生化**已落地**(缺 split 车道条目);具名 UBO host payload(D-B8)走了直绑常驻 `VkBuffer` range 的备选,欠一次测量 + 裁定关 OQ-6;内部 shader 烘焙**半已落地**(颜色 blit `WireColorBlitSpirv.h`,仅 split 臂),欠深度 mip 烘焙 + `MOBILEGL_BAKED_INTERNAL_SHADERS` 新鲜度门(0 处);D18 按 ID-P7-6 读法一句闭。**新增必须项**:Magma `StateObjectDeathOps`(六处特判)、OQ-8 归档 `storageBlocks`(`MagmaProgramSource::EnsureStorageBlocks` 每 draw 重跑 SPIRV-Reflect)、OQ-10 `kCapResidentSubData` 从未发布(split 下双后端退回就地 memcpy)、两处 `MagmaP7AllocatorDebtScope`。**P6 真机发现(2026-09-22 归此)**:`DirectVulkan` 分离路径在 Redmi 上两次观测 0.988998 / 0.976494(inproc 与 spawn 同表现,pbuffer monolith 1.0;case 归属、重复次数未记录,原始证据不在树内;取自 run-ahead ARMED 下,**lockstep 对照从未在 golden 口径下跑过**——wave 1 的 E1)——Magma × 真实 GPU;树上 `@P7` 具名拒绝**实为 15 处 / 4 文件**(`multisample-blit-shape` / `-aspect`、`depth-stencil-mipmap`(已窄化到 D\|S 合并)、`vertex-layout`、`vertex-format-conversion`、`texel-buffer-native-format`、`unaligned-{texel,storage,atomic}-buffer-range`、`storage-buffer-native-range`、`uniform-block-native-range`、`uniform-buffer-byte-tail` / `-dynamic-offset`、`copy-image-in-place`、`default-color-blit-shape`;外加 Magma 无 `StateObjectDeathOps` 与 `buffer-legacy-arm`),**全部是绕过 `Session::Fail` 与普查门的裸 abort**;必须退役 `.6/.8/.9/.11/.12/.13`,其余改 decline 即可;链接实验分给 P7 的 **101 个符号**(D12)。`DynamicBackendParameters` 定宽重写**不再是 P7 的**——它是跨平台 wire 的前提,归 P6.5 wf | 集成 + trace 在 Magma 的 push 与 split 下全绿(inproc 半已是硬门;**spawn / TCP 臂今天 DirectVulkan 条目为 0**——四条 split 臂硬编码 `MOBILEGL_BACKEND_TYPE=DirectGLES`,wave 0 补后端维度);verify 零分歧(verify 今天只注册 monolith,verify+split 撞旧 `PipeRespecifyScope` 断言,先清);真机 DirectVulkan split ssim 回到 1.0(分母排除 rd12 in-world 与 create-indirect,ID-P7-4;必须带 `RUN_AHEAD=0` 对照臂);184 符号棘轮(契约 §12.1)下降 P7 的 101 个——原 "`nm -D libMobileGLServer.so \| grep glslang` 为空" 不可达,D12 裁定 server 镜像就是整个 `libMobileGL.so`;仪器 `scripts/link_ratchet.py`(存符号列表、只对新增红)归 wave 0;CTS 五块(`texture_*` / `shader_image_*` / `packed_pixels` / `direct_state_access.*` / `uniform_buffer_object*`)先立 monolith×DirectVulkan 基线再比 inproc,≤0.5 pp 且新 crash = 0 单独硬红。**再基线检查点:中点完成子系统 < 40% 立即重定基线**(分母 = `notes/p7/PLAN-PH-P34B-P7.md` §4 的 9 项) | | **P8** emulation 下放 + 索引宿主镜像 + 协议广度 | 待排 | `MG_Impl/Pipe/HostResolve.cpp`(~~client 数组范围~~ 已由 `beba0256` 落地为 owned buffer;最大索引扫描、`*IndirectCount` 解析,逐站点 reconcile);`Server/IndexHostMirror` **待重裁**(树里 0 处;a6 §6 实测宿主索引 span 无 producer、client 索引已是 owned buffer——按 `kCapNeedsHostIndexBytes` 的真实消费者重新裁定,不照抄 `ARCHITECTURE.md` §10.3);multi-draw client indices(`MultiDrawElements+CLIENT_INDICES` 仍具名拒绝);CopyImage 镜像搬到 client;viewport-array 回放验证;`generate_mipmap` 计划 + CPU 回退纹素;`texture-remint-pull` 仿真下放(15 处具名拒绝);大 blob carrier 只剩 **program archive 与 `draw_vbo` range 尾**(a6 §6;与 P6.5 sl 共用同一分片);`kCapDriverOrderedXfbCapture`(0 处);~~无 present fence tick~~ 只记在 P10 | `'^DirectGLES\.Split\.'` 与 `'^DirectGLES\.'` 逐名相同;trace split 双后端 SSIM ≥ 0.99 含两个 `coherent_as_flush` fixture;`ClientArrayAfterComputeWriteScenario`;`create-indirect` 上 `roundtrips-per-frame` 读零;`index-mirror-bytes` 逐用例发布 | -| **P9** 反向通道 | 待排,**P6.5 之后**(2026-09-22 重定范围) | **异步 reply 语义**,机制建立在 P6.5 的消息式 reply 之上(不再造 `SEG_REPLY` slot 池——池今天就有,stream 链路会删它);2 MiB reply cap 与 chunked readback(契约 §10.2.3 从 P6 改判至此,ID-47);PACK-PBO 回读 fire-and-forget + client 侧 `MarkGpuWritten`(ID-57,P6 未做);十个回调里未武装的五个:`OnXfbScatterReady`、`OnTextureWriteback`、`OnTexturePullRequest`、`OnMipLevelsGenerated`、`OnLog` 分级(`ClientSession.cpp:429`;`OnBufferWriteback` / `OnGpuWritten` / `OnSurfaceChanged` / `OnGlError` / `OnCapsInvalidated` 已武装);`OnGpuWritten` 收窄;`OnBufferWriteback` 批处理 + epoch 排序;`OnGlError` 有序(CONTRACT-P5C §4.2);纹理拉取四条缓解 + 终止符;XFB 命名空间(`DeleteTransformFeedback` 的 server 侧泄漏——按裁定无行、最后两个 class-C 之一)。~~`SEG_EVENT` 溢出策略~~ 机制已由 P5e 落地(`ARCHITECTURE.md` §11.7),剩余的"不排空对端杀宿主"归 Ph | 回读 / XFB 场景在 split 下绿;`TextureRemintPullScenario`(含无解用例);拉取计数逐 trace 发布;两条故障注入 | +| **P9** 反向通道 | 待排,**P6.5 之后**(2026-09-22 重定范围) | **异步 reply 语义**,机制建立在 P6.5 的消息式 reply 之上(不再造 `SEG_REPLY` slot 池——池今天就有,stream 链路会删它);2 MiB reply cap 与 chunked readback(契约 §10.2.3 从 P6 改判至此,ID-47);PACK-PBO 回读 fire-and-forget + client 侧 `MarkGpuWritten`(ID-57,P6 未做);十个回调里未武装的四个:`OnTextureWriteback`、`OnTexturePullRequest`、`OnMipLevelsGenerated`、`OnLog` 分级(`OnXfbScatterReady` 是零生产者、零消费者、无 EventKind 的死声明——随 P3b/P4b 删除,`kMGPipeCallbackCount` 10→9;`ClientSession.cpp:429`;`OnBufferWriteback` / `OnGpuWritten` / `OnSurfaceChanged` / `OnGlError` / `OnCapsInvalidated` 已武装);`OnGpuWritten` 收窄;`OnBufferWriteback` 批处理 + epoch 排序;`OnGlError` 有序(CONTRACT-P5C §4.2);纹理拉取四条缓解 + 终止符;XFB 命名空间(`DeleteTransformFeedback` 的 server 侧泄漏——按裁定无行、最后两个 class-C 之一)。~~`SEG_EVENT` 溢出策略~~ 机制已由 P5e 落地(`ARCHITECTURE.md` §11.7),剩余的"不排空对端杀宿主"归 Ph | 回读 / XFB 场景在 split 下绿;`TextureRemintPullScenario`(含无解用例);拉取计数逐 trace 发布;两条故障注入 | | **P10** sync / query / present 节奏 | 待排 | ~~client 铸造 query handle~~(已是:`QueryCreate` 为 `kWaitNone`);轮询入口成门铃点 + `MOBILEGL_IPC_POLL_ESCALATE`(0 处;TCP 上是首要杠杆之一);DirectGLES 的 fence 完成度来自逐 fence 退休(`g_completedFrameSerial` 仍只在 `Present` 前进;Magma 那半已由 run-ahead 落地);非 present fence tick(唯一记载处);`present` 1:1(已是);~~credit 默认 1~~(已是默认,`ConfigLoader.cpp:414`);**`PRESENT_CREDIT > 1` 从未量过**(重审 §8.7)——带延迟链路上的首要杠杆,inproc 臂上即可取;roundtrip 计数器与输入延迟直方图(今天只有 `MapPersistentRoundtrips`);`SetSwapInterval`(最后一个手写 class-C,`EmitTables.cpp:1665`) | query / XFB / `AsyncCompile` 场景在 split 下绿;trace 上 draw / state / upload 路径 roundtrip 读零;零 timeout 轮询有界退出;credit 1..3 在 TCP loopback 与跨机臂上的配对记录;配对 A/B 记录 | | **P11** persistent map 与 ≥16 MiB 采纳 | 待排,**同机臂专属、已让位**(2026-09-22) | T0 / T1 只对共享映射成立:`dataPlane = Stream` 上点名 T0 / T1 是具名拒绝并强制 T2(重审 §6 第 5 项),今天 `MOBILEGL_IPC_ADOPT_TIER` 0/1 已是 Fatal-at-use、`kSegAdopt` 只有枚举;前置开放问题 3。POST 探针档位选择(T0 主攻,Adreno 可选 T1,T2 回退);`SEG_ADOPT` 生命周期绑 `completedFrameSerial`;**`gPipeInputs` 版本化 / 双缓冲**(P5d 研究:draw barrier 延后一个 verb 的前提,须在 P3b/P4b 的句柄键控 twin 表之后)。**P5e 的更正**:P5e 退役 draw lockstep **没有**需要它——ra2 实测证明字段**值**已由 `SuppliedFieldMask` 分区,当时那次竞态在**元数据标量**上,修法是让守卫测事实而非断言未来(ID-135)。本行保留采纳存储的一般版本/时序问题;契约 §3.2 的 per-role stamp 已由 P5f 落地,不再是待办 | `LargeArenaAdoptionScenario` 在所选档下绿;26.3 与两个 Create fixture SSIM ≥ 0.99;Adreno 830 上 p99 帧时与峰值 RSS 对采纳基线(163→21 ms / 40→115 fps / ~400 MB)回归不超过 10% | | **P12** Android 生产窗口路径 | 待排,**Ph 之后** | **按重审 §6 改小**:~~Service 收 Java `Surface`~~ 删掉 Surface 传递那一半——server app 拥有自己的 SurfaceView,client 根本没有窗口,于是 minSdk 26 没有扁平化 `ANativeWindow` 的 NDK API 这条约束不再成立;`WindowKind::ServerOwned`;两个后端各一条 `CreateEGLWindowSurface` 臂;`m_windowHandle` 四处写点 + `sameHandle` 去重键(a6 §6);DirectGLES `g_Display` / `g_Surface` / `g_Context` 去全局;`kEventSurfaceChanged` 的 Width / Height 缺口(Espryt 只发布格式,server 拥有显示时 client 默认 FBO 会停在 512×512 占位值);client 侧不再无条件发 `SetWindowHandle`(`BackendObject_Remote.cpp:215`——今天 FCL 里开 spawn,第一次 `eglCreateWindowSurface` 就在 server 进程 abort);server app 监听 `unix:` 与 `tcp://`(后者 Ph 之后);server 生命周期绑 Activity;cached-app freezer(SPAWN-PLAN §8.2);多 context(契约 §11);FCL env 与 plugin APK 开关表接线 | 两个门:(a) Minecraft 经 FCL **同机 spawn** 在 Adreno 830 双后端入世界,杀 server 产生干净 device-lost latch;(b) **另一台机器上的 client 经 TCP** 在 Redmi 上进世界(数据面 stream),并记录 P6.5 的必测数 | @@ -241,8 +241,8 @@ P5c 当时移交的对象类 BARRIER-PULLED、transport registry 前端键、EGL | `rsp` residual inputs | **P5f 已关闭残余读取**:字段归属 41 record / 6 derived / 0 barrier / 16 fatal;strict 与双块 marker 表均为空,双后端逐帧 RSP 门 2 PASS / 0 skip,Redmi 36 个统计窗口 rsp=0。P5e 的“rsp 只计被采纳设障 pull”是历史计数规则,八对 admitted 的历史观察不再是当前允许集合 | | `SEG_REPLY` 2 MiB 单槽 payload cap | → **P9**(契约 §10.2.3 改判,ID-47);stream 链路上 reply 本就是消息,cap 变成 P6.5 nd 的 `maxReplyBytes` 窗口 | | `GetCaps` 的两个 blobref | 目前不骑 record;一旦运输,必须有 server→client carrier rule,不能套 `SEG_STAGE` | -| PACK-PBO readback | P5 具名拒绝;真实形状是 server 写 buffer resource、client `MarkGpuWritten`;**P6 未做,→ P9**(ID-57) | -| ABI fingerprint | → **P6.5 wf / nd**:尺寸不再进指纹而进 `LinkTerms` 由 server 陈述;指纹改成 wire 布局摘要(hs 只落了 build stamp 显式化与 `abiMajor/Minor` 补检,`wireFingerprint` / `buildFingerprint` 拆分与 `PipeFields.def` 摘要这一半没做) | +| PACK-PBO readback | P5 曾具名拒绝;`70df57bb`(2026-09-20)起 **client 侧已实现**(bounce 紧凑 reply + 按 PACK 步长逐行 `UploadSubData`,`EmitTables.cpp`;`glGetTexImage` 同形且按 `MaxReplyBytes` 分块);剩余只是 fire-and-forget(`MarkReadPixelsPackBuffer` 全仓无生产调用者)→ **P9**(ID-57) | +| ABI fingerprint | **已由 P6.5 wf / nd 落地(`fe27380a`)**:`wireFingerprint` 布局摘要 + `buildFingerprint` 拆分(只在 `Dial==Fork` 或 `MOBILEGL_IPC_REQUIRE_SAME_BUILD=1` 下比较)、`LinkTerms` 四个尺寸由 server 陈述、`DynamicBackendParameters` 定宽;`CONTRACT-P6.md:666` 仍把定宽记在 P7 名下,待改 | | 默认 32 MiB staging | 目标负载单次 128 MiB 上传装不进默认 stage;**内容侧分块已落地**(buffer 范围走查 `1e7c372e`、纹理整宽 slab `9469d48e`,预算 `MGPipeStageChunkBytes()` = 默认 segment/4 = 8 MiB),故普查 / Redmi 的显式 256 MiB profile 不再是这两条路径的必需;未接入分片的 record 类型与专用 carrier 仍归 P8(开放问题 11) | | P5b 的 inproc 依赖 | 历史的 scoped client binding、mip registry 查询与 FBO death mailbox 已经 P5c/P5f 改为记录、句柄和控制/事件路径;P6 核验并装配已有载体,不再重做这些迁移 | | 未迁移与仿真路径 | **class-C 已归零到两个**(2026-09-22 核):`EmitTables.cpp` 的 `MGR_UNMIGRATED_*` 列表全空,只剩手写的 `SetSwapInterval`(P10)与按裁定无行的 `DeleteTransformFeedback`(P9);契约 §11 / SPAWN-PLAN §8 的"511 class-C entries"是 P5 joint 树上的旧普查(`notes/p6/census-classC.md`),不是当前数;~~client vertex arrays~~(已实现:`beba0256` 起 wire 复制到 owned buffer 并保留 baseVertex/baseInstance/drawID,本轮补齐 monolith 臂 `62bfe461..e258a822`)、multi-draw client indices、RGB 三通道 CPU mip、renderbuffer copy endpoint、未绑定 named clear、`texture-remint-pull` 仿真保留具名拒绝 → P8 / P9;Magma split compute / image 的“82 个错答”是 P5b 历史普查计数,不是当前失败清单;P5f 后续已补应用 buffer consumers 与 Android 旋转 blit,Magma inproc 已能运行所测 MC 世界;后续 run-ahead 已完成([报告](notes/p5f/magma-runahead.md));XFB、部分不对齐范围、placeholder/native-format 及进一步性能工作仍归 P7([报告](notes/p5f/magma-inproc-fix.md)) | **P5e 补 → CI 收尾更正**:client vertex arrays 曾是 run-ahead 下的具名拒绝(ID-82)与预期红车道 `integration-clientarrays-split`(ID-134);`beba0256` 起已实现,`347bb90c` 已把该车道翻转为**硬绿门**并纳入主 GPU/split 标签,本轮补齐 monolith 臂(`62bfe461..e258a822`);staging 仍归 P8 @@ -262,12 +262,12 @@ P0 已回答的不再列出(spike A 的域、spike B 的分档、`posix_spawn` 5. **无存储的 capability。** 已答(P2):`FramebufferSrgb`、`DepthClamp`、`TextureCubeMapSeamless` 三个都补了真存储,`sizeof(RenderStateParameters)` 仍 1168。 6. **具名 UBO host payload 的形状(D-B8)。** Magma 在 26.3 世界每帧重打包 331 KB 具名 UBO 字节,Espryt 为 0。要么冻结第二变长尾形状,要么走备选(Magma 直接描述符绑定常驻 `VkBuffer` range,独立 `dev` PR)。P7。 7. **`MG_Util` 的切割缝。** server 需要 SPIRV-Cross / ESSL 转译缓存 / 格式处理器 / POST 探针,client 需要 glslang 与反射层;`MG_Util` 内部是否有干净的 Transpile-vs-Reflect 缝未审计。P7。 -8. **一份反射归档能否服务三个消费者。** Espryt 那一半已答(P4a):能且不需要复制。Magma 的两个消费者(`DirectVulkan.cpp` 为 `glGetProgramResource*` 重跑反射)未答。P7。 +8. **一份反射归档能否服务三个消费者。** Espryt 那一半已答(P4a):能且不需要复制。Magma 的第一个消费者已由 P5f fm 答:`MagmaProgramSource` 全部从 wire `ProgramArchive` 取,无前端对象、无复制。第二个(storage block 表)今天是**否**且变差了:split 下 `MagmaProgramSource::EnsureStorageBlocks` **每 draw** 重跑 SPIRV-Reflect(monolith 臂 `DirectVulkan.cpp:177-200` 至少有持久缓存);答案是往 `LinkArtifacts` 加有序 `storageBlocks`(数据已在 `blockReflection` 里),两个消费者都改读它。P7 wave 2-C。 9. **viewport-array 回放能否塞进一次 `draw_vbo`**:各遍之间观察到的状态是否与今天一致未验证。P8。 -10. **`ResidentSubData` 的不对称。** P3a 原样保留:`SubDataResident` 是 `kOptional`,Magma 未补实现、`kCapResidentSubData` 未接线。P7 / 独立 `dev` PR。 +10. **`ResidentSubData` 的不对称。** 已答一半(2026-09-22 核):**Magma 的实现已补**(`VkBufferManager.cpp:123` monolith 表、`:148` wire 表,`fff9d639f`)。**仍未答:`kCapResidentSubData` 从未被 server 发布**——`MG_Backend/Init.cpp:192-219` 是全树唯一的 `SetCapabilityBits` 生产调用点,只 OR 了 XFB、三个 query 位与 run-ahead 位;于是 `PipeFill.cpp:848` 在 split 下恒 false,**两个后端在拆分模式下都退回 `BufferObject.cpp:711-716` 的就地 memcpy**,Magma 的实现在 split 里是死代码。P7 wave 2-C(按 server 自己的 wire 表判 `SubDataResident != nullptr` 发布,~0.5 天)。 11. **`SEG_STAGE` 的上限。** 内容侧已答(2026-09-20):**分块已实现**——buffer 范围走查(`1e7c372e`)与纹理整宽 slab(`9469d48e`)按 `MGPipeStageChunkBytes()`(默认 32 MiB 的 1/4 = 8 MiB)切成多条 `resource_subdata`,所以单次 128 MiB 上传不再需要显式 `MOBILEGL_IPC_STAGE_MB=256`;单片仍超 arena 或该 record 类型未接入分片时仍是 `Fatal{RingOverrun, "SEG_STAGE"}` 兜底。**仍未答(2026-09-22 收窄)**:a6 §6 实测没走查的只剩 **program archive**(唯一无界 blob)与 **`draw_vbo` 的 `NumDraws*12` range 尾**;宿主索引 span 无 producer(划掉),`set_global_constants` 有走查。二者的分片是 P6.5 sl 与 P8 共用的同一件事,stream 发送窗口对着它们定尺。MC in-world / Create 的占用分布仍未量(门 8 已给出两条负载的字节/帧与记录/帧,逐 blob 分布只在 integration 车道取到)。 12. **P13 之后 split-only 渲染 bug 的 server 侧第二意见。** verify 构建 + recorder 只覆盖推送内容,不覆盖后端对它的解释。 -13. **烘焙后的内部 shader 能否在没有活 `ProgramObject` 的情况下表达 uniform location 与 UBO 布局。** 未做原型。P7。 +13. **烘焙后的内部 shader 能否在没有活 `ProgramObject` 的情况下表达 uniform location 与 UBO 布局。** 颜色 blit 已答(P5f fv:`WireColorBlit.{vert,frag}` 用 push constant,`WireColorBlitSpirv.h` 签进树);窄化到深度 mip 程序(今天在 split 下被编译掉、其 split 路径是具名 Fatal)与直通 TCS(`ProgramFactory.cpp:4060-4262`,第三个未盘点的内部 shader 生成器)。P7 wave 2-B 随烘焙 (A) 关闭。 14. **推送模型改变哪些按拉取模式调过的缓存命中率。** 幸存者容量在 P13 重调。一条线索:设备上 26.3 Espryt 的 `sve` ≈ draw 数(每 draw 重发一次 sampler-view 集合),桌面只有 ~0.07/draw;列入 P3b/P4b 优化清单。 15. **monolith 的 `*IndirectCount` 不调 `SyncGpuWrites()` 是不是潜在缺口。** 独立 `dev` 问题,拆分不得借机顺手修。 16. **索引宿主镜像的实际内存占用。** MC / Sodium / Iris 语料里 element-array buffer 总量未测;若显著超 64 MiB,退化路径的频率与代价必须实测。P8。 @@ -275,7 +275,7 @@ P0 已回答的不再列出(spike A 的域、spike B 的分档、`posix_spawn` 18. **split 两侧的负载平衡。** P5e 解锁出来的新问题:VD32(~3550 draws/帧)下 apply 线程 **11-12 ms**、client **15.7 ms**,**client 是瓶颈且打满 ~94%**。把工作从 client 挪到 apply 会直接降瓶颈——这在 lockstep 下毫无意义(两侧串行相加),**run-ahead 才使它成为一个杠杆**。供选:编码侧的 emitter、tracker 走查、持久映射的脏页追踪(`change_protection` 在侧写里占 1.3%)。需先重新侧写:等待消失后尾部各项的分母都变了。排在 P5e 之后;无主,2026-09-22 建议挂在路线图推完后的优化阶段,P6.5 的 2×2 矩阵车道顺带重新侧写 19. **链路带宽预算与压缩。** TCP 终局下 `SEG_STAGE` 字节/帧对的是 Wi-Fi / USB(量级 30–100 MB/s),不是内存;`ARCHITECTURE.md` §14 的 ~1 MB/帧预算在 60 fps 是 60 MB/s,已贴着 Wi-Fi 上限。是否对 stage 载荷做 LZ4 类压缩、纹理上传是否按内容哈希在 server 侧去重,要等门 8 的分布出来再定。P6.5 契约写下第一行之前必答。 20. **大单次上传的停顿。** 128 MiB 一次上传在 50 MB/s 上是 2.5 s;内容侧分块解决的是"装不装得下",不是"要等多久"。跨机臂上要么接受并记录,要么给上传做异步化(与 P9 的语义一起想)。不假装解决。 -21. **配对 / 认证的形式。** 令牌足够还是要 TLS?局域网上的 GL 命令流不含凭据,但一个能被随便连的渲染 server 是一条远程代码路径。Ph 定。 +21. **配对 / 认证的形式。** **已裁定(ID-P7-3,2026-09-22):令牌足够,不做 TLS。** 威胁模型是「任何人都能连的远程代码路径」而不是窃听:令牌常量时间比较、≥16 字节、无令牌只 loopback、数据面以 `Welcome.dataNonce` 绑定到已认证的控制连接、fork 前认证。TLS 作为 P12 的开放项保留。 22. **client 平台范围。** 默认先 Linux + Android(现有 CI 能验),Windows client 第二批(`ShmSegmentWin32` 在;`pipe:` 具名拒绝作废、TCP 替代),macOS 仍不拆分。这决定 `ARCHITECTURE.md` §15.3 "Windows 机器不是正确性门"要不要改。 23. **半开连接的检测。** Wi-Fi 掉线不产生挂断事件;dl 的闩取自描述符挂断,TCP 上需要 keepalive / 心跳超时并**由传输层报告为挂断**——这与"绝不取自 apply 超时"不矛盾,写清楚免得重吵。P6.5 ct。 24. **E1 对照的重定义(ID-122)无主。** 建议并入 P6.5 的门设计:S8 的好路径断言(`SessionFaultCount() == 0`)已是它想表达的形状,缺的是一个能被证伪的负控。