mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[Docs] (P8): CONTRACT-P8 (the rules P8 landed, each with its code anchor and its test), rulings ID-P8-14..18 (MD + MF and the create-indirect fixture's alignment, SE, SV, the dev merge, the wave 2 integration gate) and the debts wave 2 hands on
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
# CONTRACT-P8:server 侧仿真缺口与 split 覆盖
|
||||
|
||||
> P8(2026-09-29 起,重定界见 `docs/Disaggregated/notes/p8/PLAN-P8.md`)落地后的规则。每条写明:规则、代码落点、守住它的用例。包说明见 `docs/Disaggregated/notes/p8/{A,B,C,D,E,F,SE,SV,MF,S}.md`,裁定见 `INTEGRATOR-DECISIONS-P8.md`。
|
||||
|
||||
## 1. Espryt 生成 mip(B、SE)
|
||||
|
||||
- server 按记录的生成窗口 [BASE+1, min(MAX+1, 存储层数, 链长)) 生成,与 Magma 同口径:`GenerateMipmapWindowByRecord`(`DirectGLES.cpp:11759`);两条 blit 链都走这个窗口。
|
||||
- RGB16F / RGB32F:先试驱动原生生成;驱动拒绝时 server 从**自己的**基级做 2×2 box,永不读 client 影子。
|
||||
- 基级读不回来时,暂存 store 只在「整级、extent 相符、未被驱动写过」时可代替;否则具名拒绝 `generate-mipmap-store-declined`(`DirectGLES.cpp:13134`),生成的层保持原样。driver-written 标在本次生成自己打标之前读取。
|
||||
- 用例:`GenerateMipmapServerScenario`(两后端 × monolith / Split / Spawn / Tcp;Espryt 强制 CPU 臂 `.CpuMip.`、`.CpuMipRefused.` 只上 Split / Spawn)。
|
||||
|
||||
## 2. Espryt server 暂存副本与 GPU 写(C)
|
||||
|
||||
- shader 写过的 buffer(SSBO / 原子计数、可写 buffer image、XFB)在 server 孪生体上打 `serverGpuWritten` 标。
|
||||
- server 的 CPU 读者(restart 重写、multi-draw rebase、`*IndirectCount`、CPU 取用的 indirect 字段、XFB scatter、fp64 收窄)一律经 `SplitHostBytesForCpuRead`(`Managers.cpp:3613`):有标或有排队常驻写时先刷新再读;T0 store 先落写再 `glFinish`。
|
||||
- 用例:`GpuWrittenDrawInputScenario`(Espryt Split / Spawn / Tcp 门控)。
|
||||
|
||||
## 3. Magma wire 臂的 indirect(D、SV)
|
||||
|
||||
- `glDraw*Indirect` / `glMultiDraw*Indirect[Count]` 从 wire store 直接录成 `vkCmdDraw*Indirect[Count]`(`DrawWireIndirectNative`,`WireDraw.inc:627`);CPU 展开只留给设备发不出的 COUNT 形态(与 monolith 同条件)。
|
||||
- `glDispatchComputeIndirect` 同样原生(`WireDraw.inc:844`),无 CPU 路径。
|
||||
- 屏障规则:store 被 shader 写过(`MarkWireBufferGpuWritten`)后,首个 indirect 读之前录一次 MEMORY_WRITE → INDIRECT_COMMAND_READ。
|
||||
- 用例:`WireIndirectDrawScenario`、`WireIndirectDispatchScenario`(计数经 `WireIndirectPeek`:原生可发时 CPU 展开 = 0)。
|
||||
|
||||
## 4. 驱动拒读的纹理回读(E)
|
||||
|
||||
- split 的 `glGetTexImage` 只读 GPU。驱动拒绝时由 server 暂存 store 作答,条件同 §1(整级、extent 相符、未被驱动写过),否则具名拒绝 `texture-readback-store-declined`(`DirectGLES/WireTextureReadback.inc:411`)。
|
||||
- store 跟随同格式、单上传目标、源可信的 `glCopyImageSubData`(`FollowCopyImageInStagedStore`,`Managers.cpp:11032`);跟不了的形状打粘性 driver-written 标。
|
||||
|
||||
## 5. 分类与拒绝(F、SV)
|
||||
|
||||
- 我们的 client 发不出的形状一律 `ProtocolCorruption`:multi-draw `CLIENT_INDICES` / `INSTANCED`(`MultiDrawShapeLatch`,`PipeApplier.cpp:779`)、Magma `client-vertex-array`。
|
||||
- Magma 生成 mip 的形状 / 格式缺口是具名拒绝:`MipmapShaderFormatOrShape`、`MipmapDepthStencilAspect`(`WireFramebuffer.inc:1401`、`:1465`),判定在长链之前;3D 原生 blit 用 1 层、深度走 z 偏移。
|
||||
|
||||
## 6. 默认帧缓冲的 surface 发布(SE)
|
||||
|
||||
- push 构建里,只要 `OnSurfaceChanged` 回调在,Espryt 就发布默认帧缓冲的格式与尺寸,不再以本进程的前端占位为条件(`DirectGLES.cpp:16239`);spawn / tcp 的 client 由此拿到 server surface 的真实深度模板格式。pull 构建不变。
|
||||
|
||||
## 7. Espryt flush 阶梯(MF,dev `f973008c`)
|
||||
|
||||
- 部分范围的失效映射不得越过同一 store 上 GPU 还没跑的环形拷贝:两条阶梯(push `FlushPendingRangesFrom`、pull `FlushPendingRangesNow`)都以 `ringCopyRetireSerial` 守住(`Managers.cpp:1496`、`:1785`);整 buffer 映射除外。
|
||||
- G5 两个脚本把两条阶梯的评审后正文钉在 ID-P8-14。
|
||||
|
||||
## 8. 覆盖与门(A、SE)
|
||||
|
||||
- 归一化前缀后,每个 monolith 用例要么登上 split 门控臂,要么在 `scripts/data/split_coverage_exemptions.txt` 里有原因类(mechanism / single-backend / no-records / pending-fix):`scripts/ci/split_coverage.py`。
|
||||
- `MGPipeUnmigratedEmulation` 的名单与调用点一一对应:`scripts/ci/unmigrated_emulation_sites.py`。
|
||||
- server 读的旋钮车道:要么独立 tcp supervisor,要么只上 split + spawn,要么证明对其他用例惰性。
|
||||
|
||||
## 不变量
|
||||
|
||||
- G1:pull 构建符号不变(整阶段 0 / 0);pull 的 `.text` 只随 dev 修复变化。
|
||||
- 控制协议修订号不变(5);线上格式不变。
|
||||
@@ -1,6 +1,6 @@
|
||||
# 仍开放的债务(跨阶段)
|
||||
|
||||
> 路线图只列"有债务、看这里"。每条写明去向;已关闭的历史债与当时的完整债务表见 [`p5b/README.md`](p5b/README.md) 末节。开放问题另见 [`OPEN-QUESTIONS.md`](OPEN-QUESTIONS.md)。更新:2026-09-30(P8 第一波;按债务审查重排)。去向「需裁定」= 等用户定;「可进行」= 随时可开的小修,不依赖别的阶段。
|
||||
> 路线图只列"有债务、看这里"。每条写明去向;已关闭的历史债与当时的完整债务表见 [`p5b/README.md`](p5b/README.md) 末节。开放问题另见 [`OPEN-QUESTIONS.md`](OPEN-QUESTIONS.md)。更新:2026-09-30(P8 第二波;按债务审查重排)。去向「需裁定」= 等用户定;「可进行」= 随时可开的小修,不依赖别的阶段。
|
||||
|
||||
| 债务 | 去向 |
|
||||
|---|---|
|
||||
@@ -18,15 +18,21 @@
|
||||
| P11 转出(B2):handle 臂的 CPU 读者读采纳 / T0 映射前先落排队常驻写——split 半已由 P8-C 实现(`SplitHostBytesForCpuRead` 的 T0 臂:落写 + `glFinish`,ID-P8-9),但主机无 T0、未能证红 | 需设备验证(红米 Android 集成测试 + static-peek) |
|
||||
| P11 转出(B2):server 准了 T0 而 client 选了 T2 时,每个存储的 `map_persistent` 等 2 s 再具名拒绝(产品里 grant 与 caps 一致,只在变异下见过) | 可进行(小修:每会话一个「client 不要 T0」提示) |
|
||||
| P9 转出:Espryt 重铸保留路径上 framebuffer clear 后 `imageLoad` 偶读旧值(主机 3/30,加 barrier 后 0/30;`TextureRemintPullScenario` case C 暂钉 barrier),疑 llvmpipe(ID-P9-11);P11 合并 dev 后 push 单进程臂上也见过一次,`ImageBindableRemintScenario` 同样钉 barrier(ID-P11-6) | 可进行(在红米上不加 barrier 归因) |
|
||||
| P8 转出(D):应用省略 `glMemoryBarrier` 时(create-indirect 322 轮 cull→draw 里 320 轮),两臂在计算写与顶点着色器读之间都没有依赖(GL 未定义,但真实应用依赖它);D 的每轮屏障在真机上的开销未测 | 待归因(与第二波 Magma monolith 的计算→indirect 依赖一起看) |
|
||||
| P8 转出(D):应用省略 `glMemoryBarrier` 时,两臂在计算写与顶点着色器读之间都没有依赖(GL 未定义,但真实应用依赖它);D 的每轮屏障在真机上的开销未测;create-indirect 验证不了这两件事(ID-P8-14),需要一个「计算写命令、无应用屏障、不重写」的 fixture | 待归因(需新 fixture) |
|
||||
| P8 转出(E):driver-written 标按整张纹理打(`GenerateMipmap` 也打),驱动拒读时连基级也具名拒绝,偏保守;跨格式拷贝 store 不跟随;拒绝仍是会话 Fatal(要改回包状态才能答 `GL_INVALID_OPERATION`) | 小修(按 level 打标);其余按需 |
|
||||
| P8 转出(B):`PipeCalls.def:260` `GenerateMipmap` 仍是 `kWaitApplied`,裁定 14 的理由(CPU 滤波碰 client 影子)已不成立,可改 `kWaitNone` | 性能工作(协议行为变更,需单独裁定) |
|
||||
| P8 转出(C):server SSBO 标记过近似(窗口内每个绑定的 SSBO 都标);一个留在 SSBO 绑定上又当 restart EBO 用的 buffer 每次 draw 都回读 | 性能工作 |
|
||||
| P8 转出(monolith,ID-P8-13):9 条 monolith 缺陷真实内容 0 命中,不在 dev 上修——Espryt `*IndirectCount` / 原生 indirect `gl_BaseVertex` / fp64 收窄读未同步影子;Magma `glMultiDrawArraysIndirectCount` CPU 臂同病;Magma 录制中途 `SyncGpuWrites` → SIGSEGV;Espryt RGB16F / RGB32F CPU 滤波读陈旧影子、R11F / 深度链无视 BASE / MAX;Magma 无 BLIT 颜色格式缺着色器 mip 臂;Espryt 拷贝后 `glGetTexImage` 读拷贝前影子(证据见 `notes/p8/{B,C,D,E}.md`) | P13(monolith 换到已修好的记录臂) |
|
||||
| P8 转出(monolith,feat,ID-P8-14):feat 的 monolith 臂每次 indirect draw 在命令缓冲有 GPU 写时整 buffer 同步回读(`SyncClientSideVertexArraysForIndirectFetch`,`62bfe461`,dev 无);Magma 的 split 构建 monolith 深度 mip 不传 view 类型,无深度 `BLIT_DST` 的设备上 1D 深度链会拿到 2D view(推断,Release 下断言编译掉,SV) | P13(monolith 换臂) |
|
||||
| P8 转出(ID-P8-14):create-indirect fixture 在桌面上抓(SSBO 偏移对齐 16),Adreno 要求 64,任何臂任何后端都过不了;设备车道记为不适用 | 需要时在对齐 64 的设备上重抓 |
|
||||
| P8 转出(MD):dev 的 `RingAllocateSlow` 在出错的上下文上无上限地排水(设备上挂在 `glFinish`) | 小修(dev) |
|
||||
| P8 转出:`LogForwardChannel.APeerThatStopsReadingCostsWarnLinesNotTheCallersTime` 在负载下超时(两次),单跑必过 | 小修(放宽时限或隔离) |
|
||||
| P8 转出(SV):`gen_pipe_dirty_surface.py` 扫描集成测试源,测试成员名与 GLContext 成员同名(如 `m_parameters`)会静默弄坏它的自检;`.Mip3DValidation.` 在没装校验层的车道上是失败不是跳过 | 小修 / CI 记录 |
|
||||
| P8 转出(MF):两条 flush 阶梯附近几处注释仍写旧的冻结 / 钉住提交(`5cb826b0`、`3e298c9a`) | 文档小修 |
|
||||
| P8-0 转出:设备上基线就有的 SSIM < 0.99——1.21.11-main-menu(Espryt 0.890、Magma 0.165)、derivative-main(Espryt 0.851);两臂都有 | 待归因 |
|
||||
| P12 未做:D8 窗口种类白名单——X11 / MetalLayer / Win32Hwnd / None 仍被接受(`SurfaceOpCodec.cpp:138-141`),`HandleFromToken` 把 token 强转为指针(`ServerLoop.cpp:1228`,经 `UnpackWindowHandle`;下游是否交给 EGL 未追到底) | 可进行(Ph 类小修) |
|
||||
| P12 未做:修后的横屏 server 窗口未重测 | 可进行(红米只读检查) |
|
||||
| P11 转出(M2,给 dev):dev 的 `DirectVulkan.SplitRecording.` 车道没有 `RESOURCE_LOCK`(dev 上 `MG_IntegrationTest/CMakeLists.txt` 第 609 行)、其用例读字面日志路径——`-j` 下可能互相截断;P11 线的副本已修。另:dev 的 `853c5f12` / `7030d307` 与 B2 的 `7784d6bb` 修同一处 | 下次向 dev 回流时带上;那两处取一份 |
|
||||
| P11 转出(M2,给 dev):dev 的 `DirectVulkan.SplitRecording.` 车道没有 `RESOURCE_LOCK`、其用例读字面日志路径——`-j` 下可能互相截断;P11 线的副本已修(Magma 空 uniform 的重复修复已在 ID-P8-17 合成一条) | 下次向 dev 回流时带上 |
|
||||
| P11 转出(M2):超过 stage 分块预算的大层按分片发出,没有写入框覆盖的分片仍带整框(server 要靠它拼层图),会把影子盖到 GPU 写过的地方;修法要一个两个 server 都跳过的「只定位」区域写法,控制协议修订 +1(split 专属,早于 P11) | 小包或 P8 |
|
||||
| P11 转出(M2):上传仍有两种有损形状,各记一次日志——一层的精确写入框超过 4096 个时按存储的矩形表覆盖发出;applier 一个条目累计超过 4096 个区域时并成并集框。纹理带 GPU 写时两者都会把影子盖进空隙 | 小修,无触发报告 |
|
||||
| P10 转出(性能):设备上 tcp loopback 的 rd12 每帧 19.4 ms 中 ~11.2 ms 是生产者在 stream 传输里的停车(发送 + 环 / stage / ack 等待),credit 等待只有 ~0.2 ms(`notes/p10/C-MEASUREMENTS.md` §2,ID-P10-13) | 路线图推完后的性能工作 |
|
||||
|
||||
@@ -17,3 +17,8 @@
|
||||
| ID-P8-11 | 2026-09-30 | **E 落地**(`39cd8fb7`):审计前提不成立——split 的 `glGetTexImage` 只读 GPU、不碰影子;真实缺口是驱动拒绝 attach(Adreno RGB16 / 16 位 SNORM)时会话以 `Fatal{ReplyError,"ReadPixels"}` 结束。改为由 server 暂存 store 作答(整级、extent 相符、未被驱动写过),store 跟随同格式 `glCopyImageSubData`(FollowCopy),跟不了的打粘性 driver-written 标;否则具名拒绝。死闩 `CopyImageSubData+RENDERBUFFER` 删除,census 79 → 78。 | red-once 11 条。E 的 monolith 半(拷贝后读拷贝前的 CPU 影子)归第二波 dev。 | [`E.md`](E.md) |
|
||||
| ID-P8-12 | 2026-09-30 | **第一波集成头 `39cd8fb7` 整套门**:G1 符号增 0 减 0、`.text` `0xa5ba13`(pull 不变);fatal census 78;link ratchet 172;parity 0;修订 5;wire-declines 58 / 59 站点;卫生 12/12 + `split_coverage`(两后端 monolith 701,Espryt 门控 612 + 豁免 89,missing 0);unit 2721;split / spawn / tcp 735 / 649 / 661;Magma 271 / 248 / 216 / 668;gpu monolith / inproc 3684 / 3684;verify 5471;retrace 230/236(已知 6 例 iterationrp)。集成者裁定:契约旧措辞加 P8 修订注(`CONTRACT-P5B.md`、`CONTRACT-P5E.md`、`CONTRACT-P7.md`);monolith 缺陷共 12 条(报了 13 条,C、D 各报一次 Magma `glMultiDrawArraysIndirectCount`),取舍见 ID-P8-13;开放问题 9、11 关闭,15 答「是缺口」。 | 串行集成六次,每次整套门;两处追加冲突(`CMakeLists.txt`、`WireDeclines.def`)都两块保留,一次合并修复(A 的豁免行)。 | 树外 `~/w7/notes/p8/int-*.md` |
|
||||
| ID-P8-13 | 2026-09-30 | **第二波**:split 两包(SE Espryt + 文档、SV Magma)串行合入 `p8/main`;dev 一包(MD)只修 create-* 在 Adreno 上的三条真实负载缺陷,其余 9 条 monolith 缺陷留给 P13(`DEBTS.md`)。 | ID-P8-3 原意是「B2 的 monolith 半边上 dev」,第一波报出 12 条(13 条报告去重),全在 monolith 专属臂里、P13 换臂即消失;按 P8-0 真实内容命中收窄,只修 Create 在 Adreno 上会碰到的三条(dev 是现行产品)。这是对 ID-P8-3 的收窄,已告知用户。 | `PLAN-P8.md` 第二波 |
|
||||
| ID-P8-14 | 2026-09-30 | **MD + MF:Create 在 Adreno 830 上的真实缺陷**。(1) Espryt 部分范围失效映射越过排队的环形拷贝,Adreno 丢拷贝 → create-instancing 整块地形空(0.870);dev 修(`f973008c`,已推 origin dev),feat 的 push 阶梯镜像同一守卫(MF),G5 两条阶梯正文按本裁定重钉;红米两构建 monolith 0.870 → 0.99998 ×3,关守卫回 0.870。spawn 未受影响是时序运气(同样隐患,前面一串整 buffer 映射先把拷贝提交了),现在靠设计。(2) **create-indirect 在红米上坏(ID-P7-4)不是 MobileGL 缺陷**:fixture 在桌面上抓(SSBO 偏移对齐 16),Adreno 要求 64,按 GL 规则被拒的 `glBindBufferRange` 让 Flywheel 的拷贝着色器写乱 indirect 命令;接受 16 字节偏移的诊断构建让 Magma 到 0.99999。该 fixture 的设备车道记为不适用。(3) 每次 indirect draw 整 buffer 同步回读只在 feat 的 monolith 臂(`62bfe461`),dev 无;Magma「计算写 → indirect 读无依赖」被证伪(加屏障不变)。 | 设备 red-once 各一;主机无法显出丢拷贝(llvmpipe 不丢)。 | `Managers.cpp`、`Managers.h`、`p3a_untouched_regions.sh`、`p4a_untouched_regions.sh`;[`MF.md`](MF.md);树外 `md-report.md` |
|
||||
| ID-P8-15 | 2026-09-30 | **SE 落地**:spawn / tcp 的默认帧缓冲把 surface 发布给 client(原先前端占位为空就提前返回,client 留着 D32F_S8 猜测,blit 丢深度模板);A 的 pending-fix 豁免删除;CPU 生成 mip 在基级被驱动写过且读回被拒时具名拒绝;D 的 case 3 在 Espryt split 臂放开;`unmigrated_emulation_sites.py` 进 CI 与门,死名 `copy-image-shadow-mirror` 删除;包说明 87 处行号按内容重对。 | red-once 9 条。副作用:P12 server 自有窗口的尺寸事件在 spawn / tcp 下第一次生效(设计如此),由出口设备检查验证。 | [`SE.md`](SE.md) |
|
||||
| ID-P8-16 | 2026-09-30 | **SV 落地**:Magma 3D 原生 mip blit 用 1 层(校验层 VUID-00240 / 01707 / 01708 消失);深度模板 mip 拒绝有了 tally 行 `MipmapDepthStencilAspect`;1D 深度 mip 具名拒绝;wire 臂 `glDispatchComputeIndirect` 原生(无 CPU 路径,沿用 D 的屏障规则)。 | red-once 9 条;`.Mip3DValidation.` 需要校验层,只放在装了层的车道。 | [`SV.md`](SV.md) |
|
||||
| ID-P8-17 | 2026-09-30 | **合并 dev `f973008c`**(`37174242`):dev 的 Magma 空 uniform 修复与 P11 的 `7784d6bb` 是同一处,合成一条代码路径;dev 的 `UnboundUniformBlockScenario` 登上 split 各臂。G1 符号 0 / 0,pull `.text` `0xa5ba13` → `0xa5ba43`(dev 修复)。 | dev 是现行产品;ID-P8-3。 | `UniformManager.cpp`、`P8Coverage.cmake` |
|
||||
| ID-P8-18 | 2026-09-30 | **第二波集成头 `49430538` 整套门**:G1 符号 0 / 0、`.text` `0xa5ba43`;census 78;ratchet 172;parity 0;修订 5;wire-declines 61 / 66 站点;卫生 14/14(含 G5 两个、`split_coverage`、`unmigrated_sites`);unit 2724;split / spawn / tcp 747 / 661 / 673;Magma 277 / 253 / 220 / 678;gpu monolith / inproc 3744 / 3744;retrace 230/236(已知 6);verify 5514 中 1 例 `LogForwardChannel.APeerThatStopsReadingCostsWarnLinesNotTheCallersTime` 负载下超时,单跑 5/5 过(入债)。SV 的集成门途中 WSL 自动升级重启,重启后首轮 gpu monolith 的 664 个 tcp 失败是残留的 fixture 状态文件,重跑 3744 全过。 | 串行合入 dev、SE、SV、MF 四次,每次整套门。 | 树外 `~/w7/logs/p8/int-*-summary.log` |
|
||||
|
||||
Reference in New Issue
Block a user