[Docs] (Disaggregated): record the P1 landing and what its verify lane found

- README status, the ROADMAP P1 row with the measured site and accessor counts, and the
  ARCHITECTURE correction from 293 to the 277 arrow sites the tree actually has
- MEASUREMENTS gains the P1 scale table, the two classes of finding the verify lane
  produced (nine missing fill rows, three fields a backend moves inside its own verb) with
  the push-on-mutation decision and its three hooks, and the acceptance numbers
This commit is contained in:
2026-09-06 06:17:12 -04:00
parent 62a7786184
commit e7a6a72f6a
4 changed files with 51 additions and 4 deletions
+1 -1
View File
@@ -341,7 +341,7 @@ struct PipeInputs {
| 阶段 | 改什么 | 证明 |
|---|---|---|
| A 别名 | 机械 `sed``MG_State::pGLContext->``MGB_CTX->`293 处)+ 手工转换 58 行非箭头用法(~34 处 `MOBILEGL_ASSERT` 删除、7 处空守卫、3 处三元、`.get()` 裸指针捕获与 `decltype` 别名、14 处 `!= nullptr`、1 处注释);逐 verb 类填充点填 `gPipeInputs` | `nm --defined-only` 不变;`.text` 差异可逐行归因(空守卫/三元的重写推迟到 P2) |
| A 别名 | 机械 `sed``MG_State::pGLContext->``MGB_CTX->`**实测 277 处**293 出自过期的 vendored 清单)+ 手工转换 58 行非箭头用法(~34 处 `MOBILEGL_ASSERT` 删除、7 处空守卫、3 处三元、`.get()` 裸指针捕获与 `decltype` 别名、14 处 `!= nullptr`、1 处注释);逐 verb 类填充点填 `gPipeInputs` | `nm --defined-only` 不变;`.text` 差异可逐行归因(空守卫/三元的重写推迟到 P2) |
| B 推送 | tracker 填 `gPipeInputs`,填充器按 `MOBILEGL_PIPE_PUSH` 位图逐字段让位 | `MOBILEGL_PIPE_VERIFY=1`:tracker 再填一份快照版,G4 比对器逐字段每 draw 比一次 |
| C 句柄化 | `SharedPtr<前端对象>` 字段 → `MGPipeHandle` + POD 描述符;memo 重键;写回变回调 | 全套门(§13) |
+48 -1
View File
@@ -1,4 +1,4 @@
# P0 实测
# 实测记录(P0、P1
> 每张表都写明设备、提交与命令,以便复现。设备:`35d0befa` = Xiaomi 24129PN74CAdreno 830Android 16`3B159D009VZ00000` = Oppo PLG110MaliAndroid 16ColorOS)。设备运行日期 2026-09-05。设备锁协议照旧。
@@ -94,3 +94,50 @@ python3 tools/trace_replay/run_android_retrace_local.py \
3. `--env` 值里嵌入的 `/data/...` 会被 runner 的 bash.exe 做 MSYS 路径转换(`MSYS2_ARG_CONV_EXCL="/data/*"` 只覆盖开头匹配)——用 `MSYS_NO_PATHCONV=1` 跑。
4. `coherent_as_flush` 管线完好:`--ez coherent_as_flush true``trace_replay_core.cpp``setenv`,独立于 `--env` 透传。
5. **`minecraft-1.21.1-neoforge-create-indirect-in-world` 在两台设备上都失败**Adreno 830Espryt ~4.5 分钟后黑帧,Magma 纹理上传提交时 `VK_ERROR_DEVICE_LOST`MaliSSIM 0.85 / 0.45)。Adreno 830 上用 `dev@81b17c0b` 基线 APK 复现,**是基线就有的问题,不是本分支造成**;它是 P3a/P8 验收清单里的用例,需先在 `dev` 修。
---
# P1 实测(`feat/disaggregated`lavapipe / llvmpipe
## 6. 规模:站点、访问器、填充点
| 量 | 值 | 出处 |
|---|---|---|
| 后端 `pGLContext->` 箭头站点 | 277Espryt 113、Magma 164 | 计划写 293,出自过期的 vendored 清单 |
| 非箭头行 | 58Espryt 9、Magma 49,其中 43 条是 Magma 的逐 verb `MOBILEGL_ASSERT` | 与计划一致 |
| `PipeInputs` 字段 | 63 | 计划写 61`GetBoundTransformFeedbackLifetimeId``HasOpenTransformFeedbackSpan` 是 D21 之后新增的读点 |
| 后端调用的不同访问器 | 62Espryt 32、Magma 56 | `GetBoundTransformFeedbackName` 已无人读,留作已标注的死行 |
| 填充点 | 83 条 `MGP_FILL`,覆盖 69 个 verb、9 个类 | `MG_Pipe/FillPoints.def` |
| `SyncPersistentMappedRange` / `SyncGpuWrites` | 20 / 6 | 与计划一致 |
## 7. verify 通道发现的两类真问题
**缺填充行(9 处)。** 逐 verb poison 在 79 例 retrace 与 818 条 integration-verify 上抓出三组:`kReadback``IsTransformFeedbackActive`/`IsTransformFeedbackPaused`(深度/模板回读仿真的 `ScopedEmulationDrawState` 会暂停在飞的捕获)、`kTextureOp``kDispatch``IsCapabilityEnabled``kBlitOrCopy`/`kTextureOp` 缺着色器 blit 用到的 viewport 与顶点/缓冲绑定。其中 8 行是静态过近似(代码路径可达但通道未跑到),过近似会让那对 (类, 字段) 的 poison 永久失效,**P2 收紧填充表时先复查这 8 行**。
**verb 内后端改前端(3 个字段)。** Magma 在自己的 draw 里写前端对象(为未绑定采样器合成回退纹理、材质化排队清除、覆写采样器 filter),把边界已经拷走的值挪了位,8 条 DirectVulkan 用例与 2 条 trace 因此报 `Fatal{PipeVerifyDiffer, "GetSamplingResolutionGeneration@Draw*", where=read}`。**选定的解法是 push-on-mutation**:前端计数器移动时用 `MGP_NOTE_MUTATION(Field)``MG_Pipe/PipeMutation.h`)刷新推送块里的那一个字段(只刷值不刷戳记),"推送块在每次读取时都等于活上下文"这条不变式因此字面成立,也正是 P2 tracker 需要的形状。
三个被这样处理的字段与它们的钩子:
| 字段 | 钩子 |
|---|---|
| `GetSamplingResolutionGeneration` | `TextureState::BumpSamplingResolutionGeneration()` |
| `GetTextureBindGeneration` | `TextureState::BumpTextureBindGeneration()``NoteUnitTouched()``bindingChanged` 分支 |
| `GetMaxTouchedTextureUnit` | `NoteUnitTouched()` 的高水位分支 |
钩子挂在**计数器**上而不是四十个写入点上:后端写前端的全部路径(`SamplerObject` 的 8 个 setter、`ITextureObject` 的 6 个、纹理单元绑定路径)都经由这三个计数器,`BufferObject`/`ProgramObject`/`VertexArrayObject` 的后端写入不移动任何推送字段(它们是句柄类读点)。
## 8. P1 验收(合入后在 `~/w7/pipe` 实测)
| 门 | 结果 |
|---|---|
| pull 构建符号与 `.text` | 0 增 / 0 删 / 0 改尺寸 / 0 重命名,`.text` 字节不变 |
| `MG_Backend` 里的 `pGLContext` | 0(唯一保留处是开关头文件的 pull 分支) |
| 单元(pull / push / verify | 1485 全绿 × 3 |
| `integration-gpu`pull | 878 全绿 |
| `integration-verify` | 818 全绿,零 `Fatal{` |
| 79 例 retrace`MOBILEGL_PIPE_VERIFY=1` | 79/79 通过,79/79 带 armed 摘要,零 `Fatal{` |
| 两个阴性对照 | 4 条专用条目全绿(篡改字段变红、抽掉一个填充戳记在那条 verb 上变红) |
| 测试名 | 0 删除,+29 |
**verify 构建的代价**`integration-verify` 818 条在 4 路并行下约与 `integration-gpu` 同量级;79 例 retrace 在 4 路下约 20 分钟。
+1 -1
View File
@@ -1,6 +1,6 @@
# MGPipeMobileGL 前后端拆分
> 状态:**P0、P0.5 已落地**`feat/disaggregated@5d99ee43`,基线 `dev@50fb1343`)。下一步 P1 → P2,第 43 天 GO/NO-GO。见 `ROADMAP.md`。
> 状态:**P0、P0.5、P1 已落地**`feat/disaggregated`,基线 `dev@50fb1343`)。下一步 P2,第 43 天 GO/NO-GO。见 `ROADMAP.md`。
## 是什么
+1 -1
View File
@@ -14,7 +14,7 @@
|---|---|---|---|---|
| **P0** 卫生、度量、门、骨架 | 9–11 | ✅ 边界计数器(字节 / 动态 accessor / 六个 memo 门 / 上传形状);`PipeCalls.def` 完整目录 + payload POD + 七个生成器 + CI `pipe-gates``gen_pipe_dirty_surface.py``check_doc_citations.py`;八个 `MOBILEGL_PIPE_*` 开关;`MG_Remote/{Protocol,Transport}` 骨架(`SCM_RIGHTS` 第一优先、双 tail 双三元组的 `RingControl`、双向 doorbell、校验型 `Framing``ShmSegment``InProcessTransport`+ `protocol.fbs` + `flatc-check` + `MG_Test/Wire` 五个套件;三个严格 no-op 收益(`GetInteger64i_v`/`GetProgramiv` 退役、`RenderbufferObject::GetLifetimeId()`、D21 XFB 计数槽重键);compute 限制进 `DynamicBackendParameters`spike A、spike Bretrace 通道 `--env` 透传 | ✅ 单元/集成/40 trace 逐名不变;wire 层测试(fd 传递、doorbell、ring、封帧、inproc)绿;两台设备的字节/调用基线在案;spike A/B 出结论;citation lint 绿 | — |
| **P0.5** 值头与制品头抽取 | 6–9 | ✅(`5d99ee43``MG_Pipe/MGPipeValueTypes.h``RenderStateParameters``SamplerParameters``PixelStoreParameters``VertexAttribute`… 不 include `MG_State/GLState`);`MG_State/GLState/ProgramState/ProgramArtifacts.h`(五个反射类型,不 include `ShaderObject.h`/`SpvcSession.h`8 个 includer 零改动——类内 `using` 别名保住每一种既有拼写);`Visit()` 归档 + `sizeof` 绊线;CI `-H` include 闭包断言(`scripts/check_include_closure.py`text + clang 两模式、自带阴性对照、`--require-all` 棘轮;`scripts/symbol_report.py` 做逐符号归因)。实测落地:测试名零删除、`MG_Backend` 零 diff、`.text` 字节不变、符号 0 增 / 0 删 / 42 重命名;`DynamicBackendParameters` 未搬(含 `SizeT``TextureTarget` 成员,搬动不是纯移动),`MGPipeTypes.h` 仍 include `BackendObject.h`,闭包门 A 因此断言 `MGPipeValueTypes.h` | 全套测试逐名不变(纯搬移);两条闭包断言绿且人为加回一个 `MG_State` include 能变红;`nm`/`.text` 变化可逐符号归因 | P0;**P1 与 P7 的硬前置** |
| **P1** `PipeInputs` 替换与 verify harness | 1013 | `MG_Backend/MGPipe/PipeInputs.h`Espryt 32 / Magma 55 访问器);`sed` 293 处 + 58 行非箭头清单逐条转换(显式交付物);逐 verb 类填充点(G5 表,~93 个边界站点);逐 verb 世代 poison;G4 影子比对器 + 第三种 CI 模式;20 处 `SyncPersistentMappedRange` + 6 处 `SyncGpuWrites` 的逐站点归属表 | pull 构建 `nm --defined-only` 不变、`.text` 差异逐行归因(空守卫/三元重写推迟到 P2);40 trace + 全部集成测试在 `MOBILEGL_PIPE_VERIFY=1` 下零分歧;故意损坏一个快照字段能让 verify 变红;故意在 `glGenerateMipmap` 的填充表漏一个字段能在**那条 verb** 上触发 poison Fatal | P0.5 |
| **P1** `PipeInputs` 替换与 verify harness | 1013 | `MG_Backend/MGPipe/PipeInputs.h`63 字段;Espryt 32 / Magma 56 访问器);**实测 277 处箭头 + 58 行非箭头**Espryt 113+9、Magma 164+49)逐条转换;逐 verb 类填充点(G5 表,~93 个边界站点);逐 verb 世代 poison;G4 影子比对器 + 第三种 CI 模式;20 处 `SyncPersistentMappedRange` + 6 处 `SyncGpuWrites` 的逐站点归属表 | pull 构建 `nm --defined-only` 不变、`.text` 差异逐行归因(空守卫/三元重写推迟到 P2);40 trace + 全部集成测试在 `MOBILEGL_PIPE_VERIFY=1` 下零分歧;故意损坏一个快照字段能让 verify 变红;故意在 `glGenerateMipmap` 的填充表漏一个字段能在**那条 verb** 上触发 poison Fatal | P0.5 |
| **P2** 渲染状态 CSO + 第一片 Track H + 残余值块 | 1826 | `MG_Impl/Pipe/Tracker`(dirty 位、5 个聚合世代、抑制器骨架);`gen_pipe_dirty_surface.py` 首轮映射成门;`MGPipeRenderStateSpans` + G7 setter 一致性测试;`CsoCache`64 项,键 = pipeline 子集);`create/bind_render_state` + `set_dynamic_state`Espryt `SyncRenderState` 一行不动;Magma `ComputePipelineStateHash`/`GetOrCreatePipeline`/`ApplyDynamicDrawStateTail` 改从 CSO 与动态 payload 取);`set_pixel_pack_state``set_patch_state``set_vertex_attrib_defaults``set_residual_value_state` + `ResidualValueBlock` 绊线;**第一片 Track H**Espryt 0b`SlotAllocator` + 6 个 registry → slot 数组 + 删 `TwinLookupMemo`×3/`OwnerEquals`/`g_fbSlotCache`/GC)与 Magma 子系统 4`VertexInputStateFactory`/`VaoDrawMemo` 重键,删前端 VAO 里的后端裸指针);`MOBILEGL_PIPE_LEGACY_MEMOS`;补 `FramebufferSrgb`/`DepthClamp` 存储 | 集成 × 2 后端 × {pull, push} 逐名相同;40 trace push 下 SSIM ≥ 0.99 双后端;verify 零分歧;`HandleRecycleScenario` 绿且重键前红;G7 测试绿且拿掉一个字段能红;两台设备配对逐线程 CPU p50/p99 不差且 tracker 绝对 ns 在上限内;Blaze3D blend-toggle 微基准;CSO 内容寻址关闭的负面对照 | P1 |
| **P3a** handle wave 1Espryt):buffer、VAO | 1823 | 7 个 `BufferBackendOps``resource_*``buffer_subdata_resident`(可 null)、`resource_flush_range``resource_readback``map_persistent`(不碰实现);pool 与延迟释放原样搬;vertex elements 三件(两个视图都带);`set_vertex_buffers``baseInstance` 显式字段);`set_index_buffer`Adreno SIGSEGV workaround 保留 | 全套门;buffer/VAO 族场景(`LargeArenaAdoption``StorageBufferRegrow` 发布 `map-persistent-roundtrips``VertexAttribBinding``MultiDraw``PrimitiveRestart`…);Create/rd12/26.3/sodium traceMC 26.3 在 Adreno 上 p99 不变。**再基线检查点 1:超过 27 天必须重定基线** | P2 |
| **P4a** handle wave 2Espryt):FBO / 纹理 / sampler / program 身份与描述符 | 2634 | `set_framebuffer_state`(解析后的 `ReadSurface`、内联格式、`ContentHash``{0,1}`);sampler CSO(含 `borderColorForm`);sampler view + `set_texture_params``set_sampler_views`/`bind_sampler_states`/`set_shader_images`shader CSOSPIR-V + 归档);`set_draw/dispatch_program``set_global_constants``CompositeResolver`;纹理/renderbuffer 的 `resource_*`。emulation 在 split 下显式 Fatal 直到 P8 | 全套门;framebuffer/纹理/program 族场景;**新增"只作 attachment / image 单元 / CopyImage 端点的纹理其 `glTexParameter` 生效"场景(落地前必须红)**;两台设备 `KHR-GL46.direct_state_access.framebuffers*` 与整个 `packed_pixels` 块(~3300 例,句柄复用压力测试)。**再基线检查点 1b:超过 39 天** | P3a |