mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 18:13:23 +09:00
P3b/P4b espryt D1 slice 1, landing under the P7 program (notes/p7/PLAN-PH-P34B-P7.md
§1.2 row "XFB scatter", §3 wave 2-D).
ScatterCapturedRecords is a read-modify-write of the capture destination's pre-capture
bytes - a gl_SkipComponents hole has to come back holding whatever the application left
there - and under a transport those bytes are the server's staged shadow rather than a
frontend MappedData(). The split arm read a null shadow as "this target has no
pre-capture bytes, discard it". A null shadow is not an error: MGPResourceDesc's
HasDefinedContent == 0 is the store the application ORPHANED with glBufferData(size,
NULL), and Managers.cpp's own M-3 comment says every byte it has not staged since is
undefined by its own declaration. So the continue threw a whole capture away for the
ordinary streaming idiom (orphan, upload part of it, capture into it), leaving the
application's buffer holding its pre-draw bytes under GL_NO_ERROR. The partly uploaded
shape did not even reach the continue: it has a shadow, so it asked RequireStagedCoverage
for the whole bound range and died on Fatal{StageSnapshotTooNarrow,
"xfb_scatter_pre_capture"}.
Monolith has always been right here and is right by construction: `Vector<Uint8>
staged(rangeBytes)` is value-initialised, so scattering over an unreadable source scatters
over zeroes and uploads them, which is byte for byte what a fresh MappedData() hands back.
The split arm now skips only the Memcpy, never the target. Discard-with-log is kept for
splitResource == nullptr alone, which really is impossible and has no backendId to upload
into either. RequireStagedCoverage is guarded by ResourceContentIsDeclared, exactly as
Managers.cpp's pool-reuse ladder guards its own whole-store MGL_SERVER_STAGED_REQUIRE: a
declared store still Fatals on a coverage gap, an orphaned one does not.
ResourceContentIsDeclared moves out of Managers.cpp's anonymous namespace to namespace
scope beside RequireStagedCoverage and is declared in Managers.h. The two callers must not
be able to answer "did the application declare these bytes" differently. Both live inside
#if MOBILEGL_BUILD_DISAGGREGATED, so the pull build compiles neither.
Red-once (R-16): XfbAfterClipDistanceScenario.OrphanedCaptureTarget{WithAPartialUpload,
WithNoUploadAtAll}KeepsItsVaryings, registered on the three split arms under the Xfb.
prefix. With the fix reverted the six split entries go red - the partial-upload three on
Fatal{StageSnapshotTooNarrow, "xfb_scatter_pre_capture"} ([0, 696) of a buffer whose
staged coverage does not include it), the whole-orphan three on a captured varying that is
still zero - while the two ambient monolith entries pass, which is what makes it a
transport fact. Details and the lane numbers in docs/Disaggregated/notes/p34b/espryt-d1.md.
The narrow filter is deliberate: the rest of XfbAfterClipDistanceScenario is a DirectVulkan
allocation-pattern regression that has never run under a transport, and it joins the arms
in slice 2 once the writeback event it posts is sliced.
Gates: integration-split 188/188 (186 + 2), integration-spawn 104/104, integration-tcp
107/107, ctest -L unit 2408/2408, the monolith DirectGLES XFB + readback families 66/66,
spawn_lane_parity / fatal_census / link_ratchet (186, unchanged) all green, G1 .text
0xa52203 with both nm lists byte-identical to ~/w7/p7-before.
工作笔记(原 ~/w7/notes/)
这一层是 MGPipe 各阶段的工作笔记原件:包计划(BRIEF-*.md)、契约草稿、集成者逐条裁定
(INTEGRATOR-DECISIONS-*.md)、只读审计、普查、设备记录、包任务书(TASK-*.md)与阶段报告。
它们此前只存在于一台机器的 ~/w7/notes/ 下。上层那几份文档(ROADMAP.md、
CURRENT_STAGE_PROGRESS.md、MEASUREMENTS.md …)大量引用它们——裁定编号、审计行号、
逐门数字的出处几乎全在这里。一份引用了几百次、却只存在于本地未跟踪目录的记录,等于没有记录。
所以整体移进仓库。
路径映射
~/w7/notes/<phase>/<file>.md → docs/Disaggregated/notes/<phase>/<file>.md
上层文档里凡写作 ~/w7/notes/... 的 .md 引用,都按这条规则读。
移进来的是什么,没移的是什么
| 移进来了 | 全部 .md,415 份,约 11 MB,目录结构原样保留 |
| 没有移 | 脚本(.sh / .py)、运行日志(.log / .out / .err)、普查与门的结果数据(.json / .txt / .tsv)、补丁、APK 与 .idsig、nm 转储 |
没移的那些仍在 ~/w7/notes/ 与各构建树下。它们是证据数据而不是文档:体积大、随每次运行
重新产生、且多数只在产生它的那台机器上有意义(绝对路径、设备序列号、构建目录)。上层文档引用
它们时给的是路径,不是内容。
两个需要知道的例外
- P6 的包计划已提升为正式文档:原
~/w7/notes/p6/BRIEF-P6.md现在是../P6-SPAWN-PLAN.md,本目录不再保留副本,避免两份同源文档各自漂移。 契约草稿同理,见../P6-CONTRACT-DRAFT.md。 recovered/是从失败的 workflow 运行里捞回来的材料(wf1…wf5),与同名阶段目录 可能重复,保留是因为其中几份是当时唯一的完整版本。查阶段记录请先看阶段目录。
不受 citation lint 管
CI 的文档引用 lint 只吃 docs/Disaggregated/*.md(非递归,.github/workflows/test.yml),
本目录不在其中,这是有意的:这些笔记的 file:line 是写在各自当时的代码头上的,拿今天的
HEAD 去解析必然大面积失败,而那不是错误——那是它们作为历史记录的正确状态。要核对某份笔记的
引用,用它自己声明的那个 revision:
python3 scripts/check_doc_citations.py --rev <当时的头> docs/Disaggregated/notes/<phase>/<file>.md