mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 10:03:23 +09:00
4.6 KiB
4.6 KiB
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-drawCLIENT_INDICES/INSTANCED(MultiDrawShapeLatch,PipeApplier.cpp:779)、Magmaclient-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、pullFlushPendingRangesNow)都以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);线上格式不变。