Files
MobileGL/docs/Disaggregated/notes/recovered/wf4/part3.md
T
swung0x48 aba329cc53 [Docs] (Disaggregated): P6's plan and contract draft; the working notes move from a local directory into the repository
Two things land together: the plan and contract draft P6 needs before it starts, and the
working notes that until now existed on exactly one machine.

1. P6's plan and contract draft (neither started; not one line of code)

     docs/Disaggregated/P6-SPAWN-PLAN.md      the package plan
     docs/Disaggregated/P6-CONTRACT-DRAFT.md  the contract draft (moves to
                                              MG_Remote/CONTRACT-P6.md when c6 lands)

   The three findings that mattered, all written into the documents:

   a. P6 is SMALLER than its roadmap cell suggests. The transport primitives are already in
      the tree and already tested: SocketDoorbell including hangup detection and the two
      lost-wakeup fences (Doorbell.cpp:211-360, four cases in FdPassingTest), SCM_RIGHTS fd
      passing, ShmSegment::Adopt, and the SurfaceOp / WindowKind schema already defined in
      protocol.fbs. inproc uses a real second shm mapping rather than an alias, and
      SessionRings.h:22-28 says that was done so today is not the first time it runs. P6 is
      assembly plus a control plane plus a process, not "write a socket transport".

   b. The evidence for "P6 is only a transport swap" has EXPIRED. It was bought by P5c, whose
      audit found 59 direct memory accesses in a tree that already looked clean. P5e changed
      the tree again. So the first package, a6, is a read-only audit that writes no code, and
      every contract row that depends on it is marked PENDING a6 rather than decided in
      advance.

   c. P6 does not get a game running on the phone. ANativeWindow* is meaningless in the child,
      and protocol.fbs:186-196's own comment says Android transfers the window out of band -
      that band is P12. P6 lands pbuffer / surfaceless / offscreen, which is what HeadlessGL,
      the split-equivalent lane and trace replay need, and which is exactly what P6's own exit
      gate measures. A real window reaching the server is a named refusal. This gets its own
      section because "P6 is done" would otherwise read as "the game runs now".

   The contract adds rule G: a role may not name a process-local handle. It extends P5c's
   rule E (a role may not name the other role's memory) from memory to identity - EGLDisplay /
   EGLSurface / EGLContext / ANativeWindow* / fd number / pid / mapped address either cross as
   a token this contract defines or they do not cross, and a descriptor crosses only through
   SCM_RIGHTS, where the kernel renumbers it.

   What P5e left for P6 gets its own section. The latch semantics are already designed
   (ARCHITECTURE.md:504) and are copied unchanged. What is new is that after run-ahead the
   client no longer waits while the peer process can DIE: the client holds records that were
   published and will never be applied, and Android's freezer suspends the child without
   closing anything. So slow and dead must be distinguishable WITHOUT a timeout threshold.
   That is P6's only new design; everything else is carriage. It shares a predicate with E1's
   outstanding re-specification (ID-122), and the two should be designed together.

   Two gates carried over from P5e's lessons: G2 requires integration-spawn's test-name set to
   match integration-split's name for name, because a differing set means the lane is quietly
   running less; and the arm-proof gate requires every entry to record the child pid and
   transport=spawn in its OWN private log - ID-124 established that this kind of false green
   really happens, and a spawn lane that actually ran monolith would pass every other gate.
   S2's shape must be settled before it is written, and the document says why: E1 is the
   cautionary case.

2. The working notes move into the repository (docs/Disaggregated/notes/, 415 .md files)

   ROADMAP / CURRENT_STAGE_PROGRESS / MEASUREMENTS cite ruling numbers, audit line numbers and
   the provenance of gate figures from ~/w7/notes/, a directory that exists on one machine and
   is under no version control. A record cited hundreds of times that lives only locally is not
   a record, so it moves in whole, with its directory structure intact.

   Only .md moves. Scripts, run logs, census and gate result JSON, patches, APKs and nm dumps
   stay where they are: they are evidence DATA rather than documents - large, regenerated per
   run, and mostly carrying absolute paths and device serials that mean something only on the
   machine that produced them. The mapping and this split are written in
   docs/Disaggregated/notes/README.md.

   Two exceptions are recorded there too: P6's BRIEF has been promoted to a first-class
   document and keeps no copy under notes/, so the two cannot drift apart; and recovered/ holds
   material salvaged from failed workflow runs, which may duplicate the like-named phase
   directories and is kept because a few of those were the only complete version at the time.

   CI's citation lint takes docs/Disaggregated/*.md only (non-recursive), and notes/ is
   deliberately outside it: those notes' file:line citations were written against their own
   code heads, and resolving them against today's HEAD would fail wholesale - which is not an
   error, it is their correct state as a historical record. To check one, use the revision it
   declares (--rev).

3. Inconsistencies fixed in passing

   - README.md's status line still said P5e was in progress while the stage table already said
     closed.
   - CURRENT_STAGE_PROGRESS's next-step item 1 still listed the exit gate as pending, though
     (a) and (b) were run in the previous commit; rewritten to closed plus the one item that
     actually remains (E1).
   - ROADMAP's P6 row still had the pre-phase plan in three of its cells; it now carries the
     package order, the scope boundary and the two new gates.

Checked with check_doc_citations.py: 125 citations across docs/Disaggregated/*.md, 0 problems.
2026-09-18 23:31:39 -04:00

27 KiB
Raw Blame History


4. (b) Verb-boundary entry points, and which accessors are reachable from each

The verb boundary is struct GLFunctionsTable (MobileGL/MG_Backend/BackendObject.h:117-289) — 69 function pointers plus one plain Bool policy flag (PrefersCpuXfbPrimitiveAccounting, BackendObject.h:265) — wrapped by struct GlobalBackendFunctionsTable (BackendObject.h:293-300), which adds Present (:295) and SetSwapInterval (:298). 72 entries total. Both tables are filled once, lazily, in BackendObject_DirectGLES::GetBackendFunctions() (DirectGLES/BackendObject_DirectGLES.cpp:1230-1325) and BackendObject_DirectVulkan::GetBackendFunctions() (DirectVulkan/BackendObject_DirectVulkan.cpp:694-777).

4.1 Fill-site differences between the two backends (a per-verb fill/validate must cope with both)

entry DirectGLES DirectVulkan
GetTextureImage not filled BackendObject_DirectVulkan.cpp:736
PatchParameteri BackendObject_DirectGLES.cpp:1319 not filled
BeginTransformFeedback / End / Pause / Resume / Bind / Delete :1320-1325 (all six, XfbImpl::*) none filled — Magma drives capture from its own draw recording
PrefersCpuXfbPrimitiveAccounting = true at :1312 left false
SetSwapInterval :1231 not filled
Present :1230 :698
timer-query group (IsTimerQuerySupported…GetGpuTimestampNs) :1292-1296 + :1313-1315, gated on AreTimerQueriesSupported() :754-761, gated on !MG_Config::Features.DisableTimerQuery

4.2 Verb → reachable accessors

Reachability was traced by following the helper call graph out of each entry point (caller greps cited in §4.3). "direct" = the site's enclosing function is the entry point itself.

DirectGLES (Espryt)

verb entry point (impl) reachable accessors
DrawArrays (DirectGLES.cpp:4564) direct: GetBoundVertexArray. Via PrepareForDraw: everything in the draw closure below.
DrawElements, DrawElementsBaseVertex, DrawElementsInstanced*, DrawRangeElements*, DrawArraysInstanced* (DirectGLES.cpp:4556-4931, 14 PrepareForDraw call sites) the draw closure + ResolveRestartSubstitution/ScopedRestartIndexSubstitution (IsCapabilityEnabled×2, GetPrimitiveRestartIndex×2) + BoundElementArrayBuffer (GetBoundVertexArray)
MultiDrawArrays (:4597) direct GetBoundVertexArray; + draw closure
MultiDrawElementsIndirect (:4646), MultiDrawArraysIndirect (:4754), DrawElementsIndirect (:4956), DrawArraysIndirect (:5003) direct GetBufferBindingSlot(DrawIndirect); + draw closure; + ResolveIndirectCommandBytes (:261)
MultiDrawElementsIndirectCount (:4685), MultiDrawArraysIndirectCount (:4793) direct GetBufferBindingSlot(DrawIndirect) and (Parameter); + draw closure
the draw closure = PrepareForDraw (:2949) GetBoundVertexArray (:2957), GetProgramForDraw (:2968) → SyncNeccessaryBuffers (:538→GetBufferBindingSlot), CaptureDrawTextureSyncKeys (:1513→GetTextureContextId, GetMaxTouchedTextureUnit, GetSamplingResolutionGeneration), SyncNeccessaryTextures (:1527→GetTextureUnitObject, fb-slot fast cache), SyncCurrentVertexAttributeValues (:1237→GetBoundVertexArray, GetCurrentVertexAttribute), SyncRenderState (:2022→GetRenderStateParametersVersion, GetRenderStateParameters, GetViewport, IsCapabilityEnabled), SyncCurrentProgram (:2722→GetPatchVertices, GetPatchDefaultOuterLevel, GetPatchDefaultInnerLevel, fb-slot fast cache), BindCurrentProgramWithResources (:3371→GetBufferBindingPoint(Uniform), GetTextureUnitObject), BindCurrentTextures (:3299/:3361→GetProgramForDraw), ResolveAndBindUnitTextures (:3023→GetTextureUnitObject), BindCurrentUnitSamplers (:3200→GetTextureUnitObject), SyncBufferBindingPoints (:351→GetTouchedBufferBindingPointCount, GetBufferBindingPoint), MarkShaderStorageBuffersGpuWritten (:460), SyncAtomicCounterBuffers (:470), SyncBoundBuffer (:514), BeginViewportRoutingPasses (:3792→IsTransformFeedbackActive, IsCapabilityEnabled, GetRenderStateParameters), XfbImpl::StartPendingTransformFeedback (:981→GetTransformFeedbackProgram, GetBufferBindingPoint(TransformFeedback)), CurrentProgramMayNeedPerSubDrawBuiltins (:3711), GetCurrentBackendProgram (:3661)
DispatchCompute (:6983), DispatchComputeIndirect (:6991) PrepareForCompute (:4054) → GetProgramForDispatch, plus CaptureDrawTextureSyncKeys, SyncNeccessaryTextures, BindCurrentProgramWithResources, SyncBufferBindingPoints, MarkShaderStorageBuffersGpuWritten, SyncBoundBuffer(DispatchIndirect), MarkWritableImageBufferTexturesGpuWritten (:1816)
Clear (:4111) direct GetRenderStateParameters (:4156), GetFramebufferBindingSlot(Draw) (:4215); + SyncRenderState(forColorClear) (:4121), SyncNeccessaryTextures (:4115)
ClearBufferfv/iv/uiv/fi (:7424, :7437, :7453, :7469, :7506) SyncNeccessaryTextures + SyncRenderState(forColorClear); no direct pulls
ClearNamedFramebuffer* (DirectGLES.h:60-67) same, plus the SharedPtr<FramebufferObject> handle argument
BlitFramebuffer (:6015) direct GetFramebufferBindingSlot(Read) + (Draw) (:6044-6045); + SyncCurrentFBO, SyncRenderState (:6029), BindCurrentFBO×2, SyncNeccessaryTextures (:6021), ResolveThenBlit (:5093→IsTransformFeedbackActive, IsTransformFeedbackPaused)
BlitNamedFramebuffer (:6055) same + two FBO handle arguments
CopyTexImage2D (:6676) GetActiveTextureUnit, GetTextureUnitObject; + SyncNeccessaryTextures (:6683), SyncRenderState (:6691)
CopyTexSubImage2D (:6769) same pair at :6794-6795; + :6777, :6785
CopyImageSubData no direct pulls; both endpoints arrive as CopyImageEndpoint handles
GenerateMipmap (:6928) GetActiveTextureUnit, GetTextureUnitObject
ReadPixels (:8999) GetPixelStoreParameters (:9041), GetBufferBindingSlot(PixelPack) (:9084); + PackStateFromContext (:6184), StoreReadbackRowsToClient (:7552), ReadPixelsViaFormatConversion (:8526), Utils::StoreClientRows (Utils.cpp:2294)
GetTexImage (:9166) GetActiveTextureUnit+GetTextureUnitObject (:9194-9197), GetPixelStoreParameters (:9420), GetBufferBindingSlot(PixelPack) (:9510); + GetTexImageViaShadowConversion (:8759)
ShaderStorageBlockBinding (:7355) ValidateProgramName, GetProgramObject; + SyncNeccessaryTextures (:7376), SyncRenderState (:7378)
BindImageTexture (→TextureImpl::SyncImageTextureBinding, :7317) GetImageTextureBinding (:1728)
BeginTransformFeedback (:969) / EndTransformFeedback (:1102) EndTransformFeedback→ScatterCapturedRecords (:885→GetTransformFeedbackCapturedVertices)
PauseTransformFeedback (:1131), ResumeTransformFeedback (:1140), BindTransformFeedback (:1147), DeleteTransformFeedback (:1167), PatchParameteri (:6923) no pulls
Present (:10550), SetSwapInterval (:9945) no pulls
sync / timer / occlusion / xfb-query group no pulls in DirectGLES
GetIntegeri_v no pulls
error reporting (RecordGLError, :6365) reachable from every entry above RecordError

Two more DirectGLES pull sites sit on paths reached from several verbs and are worth calling out separately because they are in Managers.cpp, not DirectGLES.cpp:

site function reached from
Managers.cpp:5355 GetReadColorAttachment readback + SyncReadBufferToBackend (framebuffer sync)
Managers.cpp:5460 IsFixedPointFallbackReadAttachment readback
Managers.cpp:6230 BoundImageUnitFormat program link (image-unit format)
Managers.cpp:7193/7201/7204 AttachPassthroughTessControlStage program link (SyncToBackend)
Managers.cpp:8751 BackendSamplerObject::SyncToBackend sampler sync — RecordError
Managers.cpp:3645/3646/3774/3775/3845/3846/4735/4736/4737 StampViewSyncKeys / SyncMipmapsToBackend texture upload, from every verb that calls SyncNeccessaryTextures
MultiDraw.cpp:45/51/52/87/95 RestartSentinelFor, RestartActive, BoundDrawIndirectBufferId, BoundIndexBuffer the CPU multi-draw flattener, reached from MultiDrawElements*

DirectVulkan (Magma)

Every DirectVulkan.cpp entry point opens with MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::<verb> called with null GL context") — that is 30 of the 58 non-arrow lines, and it is the cleanest possible marker of the verb boundary: each of those asserts is exactly where a per-verb PipeInputs fill/validate would go.

verb entry point (impl) reachable accessors
DrawArrays (DirectVulkan.cpp:815), DrawElements (:840), DrawElementsBaseVertex (:975), MultiDrawArrays (:863), MultiDrawElements (:968) / MultiDrawElementsImpl (:894→GetBoundVertexArray), MultiDrawElementsBaseVertex (:998), DrawElementsInstancedBaseVertexBaseInstance (:493), DrawArraysInstancedBaseInstance (:564), BuildClosedLineLoopIndices (:779→GetBoundVertexArray) the draw closure below
DrawElementsIndirect (:521), DrawArraysIndirect (:580), MultiDrawArraysIndirect (:392), MultiDrawElementsIndirect (:387) direct GetBufferBindingSlot(DrawIndirect) (:533, :586, :402) + ResolveIndirectCommandBytes (:277-278); + draw closure
MultiDrawArraysIndirectCount (:448), MultiDrawElementsIndirectCount (:442) direct GetBufferBindingSlot(Parameter) (:465); + VulkanRenderer::MultiDrawElementsIndirectCount (:12074→GetBoundVertexArray, GetBufferBindingSlot(DrawIndirect), (Parameter))
the draw closure = VulkanRenderer::SetupDraw (:6420) and its fast path TrySetupDrawFastPath (:6034) GetProgramForDraw (:6043, :6434, :6472), GetBoundVertexArray (:6105, :6471), GetFramebufferBindingSlot(Draw) (:6110, :6464), GetPipelineStateVersion (:6121, :6972), GetTextureBindGeneration (:6122, :6526, :6650, :6973), GetRenderStateParameters (:6130), GetSamplingResolutionGeneration (:6304, :6532, :6669, :6999), IsTransformFeedbackActive (:6091, :6512), IsCapabilityEnabled(DepthTest/StencilTest) (:6830-6831); via GetBaseTransformFlagsRaw (:6005→GetFramebufferBindingSlot, and GetShaderTransformFlags :2985); via ResolvePrimitiveRestartEnable (:4935→GetRenderStateParameters); via GetOrCreatePipeline (:4950, 25 sites: GetPipelineStateVersion, 6×IsCapabilityEnabled, GetFramebufferBindingSlot×2, GetStencilState×2, GetPolygonModeFront, IsCapabilityEnabled(SampleShading), GetMinSampleShadingValue, GetPatchVertices, GetCullFaceMode, GetDepthMask, GetDepthFunc, GetLogicOp, GetPatchDefaultOuterLevel, GetPatchDefaultInnerLevel, GetBlendFuncIndexed, GetBlendEquationIndexed, IsCapabilityEnabledIndexed(Blend), GetColorMaskIndexed); via ComputePipelineStateHash (:4820→GetRenderStateParameters) and ResolveEffectiveSampleMask (:4812→2×IsCapabilityEnabled, GetRenderStateParameters); via SelectProvokingVertexMode (:12737→GetProvokingVertexMode); via ApplyDynamicDrawStateTail (:5901→GetRenderStateParametersVersion, GetRenderStateParameters) → ComputeGLViewport (:450→GetViewportIndexed, GetDepthRangeIndexed), ComputeGLScissorRect (:5855→GetRenderStateParameters), ApplyBlendConstants (:522→GetBlendColor), ApplyPolygonOffsetState (:555→GetPolygonOffsetUnits, GetPolygonOffsetFactor), ApplyLineWidthState (:569→GetLineWidth), ApplyStencilState (:648→GetStencilState×2); via UploadAndBindVertexBuffers (:3580→GetCurrentVertexAttribute :3926) → TryComputeMaxIndexFromHostBytes (:3409→2×IsCapabilityEnabled); via UploadAndBindIndexBuffer (:4031→GetRenderStateParameters :4060); via UniformManager::BindProgramUniformBuffers (UniformManager.cpp:2346) → the whole descriptor group below; via BeginXfbCaptureForDraw (:11266) / EndXfbCaptureForDraw (:11366)
descriptor group (UniformManager.cpp) ResolveSamplerDescriptor (:464→GetTextureUnitObject :506, GetFramebufferBindingSlot(Draw) :555), ResolveSamplerTexture (:808→GetTextureUnitObject :821), ResolveSamplerTextureRaw (:834→:847), ProgramSamplesOnlySingleLevelTextures (:750→:782), ResolveSampledBinding (:1643→:1662), ResolveStorageTexelBufferDescriptor (:986→GetImageTextureBinding :1016), ResolveStorageImageDescriptor (:1259→:1295), ResolveStorageBufferDescriptor (:1146→GetBufferBindingPointCount :1189, GetBufferBindingPoint :1194), ResolveUniformBufferPayload (:1962→GetBufferBindingPointCount :2013, GetBufferBindingPoint(Uniform) :2018), CollectStorageImageTextures (:1801→GetImageTextureBinding :1850), CollectSamplerImageFeedback (:1883→:1938)
xfb group BeginXfbCaptureForDraw (VulkanRenderer.cpp:11266): IsTransformFeedbackActive :11268, IsTransformFeedbackPaused :11274, GetTransformFeedbackProgram :11277, GetBufferBindingPoint(TransformFeedback) :11316, GetTransformFeedbackGeneration :11347; EndXfbCaptureForDraw (:11366): GetTransformFeedbackProgram :11370; CurrentXfbCounterSlot (:11217): GetBoundTransformFeedbackLifetimeId :11219, HasOpenTransformFeedbackSpan :11236
DispatchCompute (DirectVulkan.cpp:642 → VulkanRenderer.cpp:7031) GetProgramForDispatch :7036; + BindProgramUniformBuffers → descriptor group
DispatchComputeIndirect (:648 → VulkanRenderer.cpp:7084) GetProgramForDispatch :7088, GetBufferBindingSlot(DispatchIndirect) :7132; + descriptor group
MemoryBarrier / MemoryBarrierByRegion (:654) no pulls beyond the null assert
Clear (:756 → VulkanRenderer.cpp:7251, 13 sites) IsCapabilityEnabled(RasterizerDiscard) :7257, GetFramebufferBindingSlot(Draw) :7260, GetClearColor :7268, GetClearDepth :7269, GetClearStencil :7270, IsCapabilityEnabled(ScissorTest) :7277, GetColorMaskIndexed :7300/:7389/:7410, GetDepthMask :7327/:7369, GetStencilState :7340/:7373; + PrepareScissoredClear (:7188→GetScissorBox×2)
ClearBufferfi/fv/iv/uiv (DirectVulkan.cpp:335-356) QueueClearBufferPayload (VulkanRenderer.cpp:7626→GetFramebufferBindingSlot(Draw) :7628) → QueueClearBufferPayloadForFramebuffer (:7434, 5 sites: IsCapabilityEnabled(RasterizerDiscard) :7439, (ScissorTest) :7481, GetDepthMask :7512, GetStencilState :7514, GetColorMaskIndexed :7526) → RecordScissoredClearBuffer (:7568: GetColorMaskIndexed :7583, GetDepthMask :7601, GetStencilState :7609) + PreCompensateSrgbClearColor (VkClearManager.cpp:53→IsCapabilityEnabled(FramebufferSrgb) :57)
ClearNamedFramebuffer* (DirectVulkan.cpp:359-386) same minus the GetFramebufferBindingSlot (the FBO arrives as a handle)
BlitFramebuffer (:1005 → VulkanRenderer.cpp:8583) GetFramebufferBindingSlot(Read) :8586, (Draw) :8587; → BlitNamedFramebuffer (:8591→IsCapabilityEnabled(ScissorTest) :8619, GetScissorBox :8620)
BlitNamedFramebuffer as above, FBOs by handle
CopyTexImage2D (:613), CopyTexSubImage2D (:619 → VulkanRenderer.cpp:9196) GetTextureUnitObject+GetActiveTextureUnit :9214, GetFramebufferBindingSlot(Read) :9222
CopyImageSubData (:625) endpoints by handle; no direct pull
GenerateMipmap (:636 → VulkanRenderer.cpp:10940) GetTextureUnitObject+GetActiveTextureUnit :10963
ReadPixels (:739 → VulkanRenderer.cpp:9927) GetFramebufferBindingSlot(Read) :9933; → PackReadbackToClientOrPbo (:2732→GetClampReadColor :2771), ReadDepthStencilImageToClient (:10424→GetBufferBindingSlot(PixelPack) :10688, GetPixelStoreParameters :10689)
GetTexImage (:744 → VulkanRenderer.cpp:10716) GetTextureUnitObject+GetActiveTextureUnit :10719; + the same pack path
GetTextureImage (:749) texture by handle; + the same pack path
ShaderStorageBlockBinding (DirectVulkan.cpp:709) RecordError :716; + TryGetDirectVulkanProgram (:269→ValidateProgramName :270, GetProgramObject :273)
BeginXfbPrimitivesQuery (DirectVulkan.cpp:1275) GetTransformFeedbackPausedPrimitiveCounter :1284
GetQueryResult64 (DirectVulkan.cpp:1209) GetTransformFeedbackPausedPrimitiveCounter :1237
Present (DirectVulkan.cpp, table :698) no pulls
BindImageTexture, GetIntegeri_v, sync group, timer group, occlusion group, EndXfbPrimitivesQuery no pulls
init/caps — BackendObject_DirectVulkan::InitCapabilities (:370) and ApplyVulkanCapabilitiesForTesting (:781) InvalidateCompileEnv (:389, :787) — the only pulls outside a GL verb
framebuffer/render-pass helpers reachable from every drawing verb VkRenderPassManager::ComputeHash (:602→IsCapabilityEnabled(FramebufferSrgb) :613), GetOrCreateRenderPass (:767→:965), ConvertTextureInternalFormatToVkEnum (:1044→:1111), VkTextureManager::GetOrCreateAttachmentViewAtMipLevel (:898→:952), VkTextureManager::SyncTextureAndGetDescriptor (:752→GetTextureObject :809)
error reporting reachable from many verbs RecordClearBufferError (VulkanRenderer.cpp:1242), RecordTextureCopyError (:1246), RecordUnsupportedFramebufferError (:1302) — all RecordError

4.3 Caller evidence used for the reachability above

PrepareForDraw 14 call sites DirectGLES.cpp:4556,4569,4587,4602,4663,4703,4771,4811,4856,4869,4894,4916,4931; PrepareForCompute :6983,6991; SyncRenderState 13 call sites :2994,4121,6029,6064,6691,6785,7378,7424,7437,7453,7469,7489,7506; SyncNeccessaryTextures 13 call sites :2983,4066,4115,6021,6063,6683,6777,7376,7422,7435,7451,7468; SyncCurrentProgram :2993,4069; BindCurrentProgramWithResources :3012,4084; SyncBufferBindingPoints :678,687,688; MarkShaderStorageBuffersGpuWritten :679,689; SyncBoundBuffer :664,691; SyncAtomicCounterBuffers :3523; SyncCurrentVertexAttributeValues :3009; SyncImageTextureBinding :1841,7317; XfbImpl::StartPendingTransformFeedback :3016; ScatterCapturedRecords :1123; PackStateFromContext :9027,9270; StoreReadbackRowsToClient :8159,8271,8322. Vulkan: SetupDraw VulkanRenderer.cpp:11422,11744,11780,11985,12127,12224,12289; TrySetupDrawFastPath :6450; GetOrCreatePipeline :6371,6896; ApplyDynamicDrawStateTail :6407,6949; ApplyStencilState :5911,5986; ApplyBlendConstants :5908,5983; ApplyPolygonOffsetState :5909,5984; ApplyLineWidthState :5910,5985; ComputeGLViewport :510,5889; ComputeGLScissorRect :5890; ResolveEffectiveSampleMask :4845,4862,5290; ComputePipelineStateHash :4989,6338; ResolvePrimitiveRestartEnable :6067,6897,6960; GetBaseTransformFlagsRaw :6139,6510,6974; GetShaderTransformFlags :6026; UploadAndBindVertexBuffers :6400,6937; UploadAndBindIndexBuffer :6404,6945; TryComputeMaxIndexFromHostBytes :3601; BeginXfbCaptureForDraw :11430,11753; EndXfbCaptureForDraw :11439,11763; CurrentXfbCounterSlot :11346,11372; PrepareScissoredClear :7279,7483; QueueClearBufferPayload :7641,7661,7758,7779; QueueClearBufferPayloadForFramebuffer :7632,7683,7708,7723,7737; RecordScissoredClearBuffer :7489; PackReadbackToClientOrPbo :10111,10119,10936; ReadDepthStencilImageToClient :10368,10420,10817; SelectProvokingVertexMode :4433,5309; BindProgramUniformBuffers :4754,6394,6928,7071; CollectStorageImageTextures :5687; CollectSamplerImageFeedback :5787; ProgramSamplesOnlySingleLevelTextures :6556; UniformManager internals ResolveSamplerDescriptor :2619, ResolveSamplerTexture :875, ResolveSamplerTextureRaw :505,773, ResolveStorageTexelBufferDescriptor :2522, ResolveStorageBufferDescriptor :2543, ResolveStorageImageDescriptor :2569, ResolveSampledBinding :1742,1785,1901, ResolveUniformBufferPayload :2257.


5. (c) SyncPersistentMappedRange and SyncGpuWrites call sites

Both are methods on MG_State::GLState::BufferObject. They are the two places a backend forces the frontend's CPU shadow to become authoritative before it reads bytes out of it — i.e. the two places a pipe boundary would otherwise hand the server stale memory.

5.1 SyncPersistentMappedRange() — 20 sites

Semantics: pushes writes made through a non-adopted persistent map (which mutate the shadow with no API call and therefore bump no change serial) down into the backend resource. A no-op for every buffer that is not such a map.

# file:line receiver enclosing function verb that owns it what it syncs
1 DirectGLES/DirectGLES.cpp:263 drawBuffer ResolveIndirectCommandBytes (:260) draw (indirect, CPU fallback) GL_DRAW_INDIRECT_BUFFER before the CPU reads the command struct out of MappedData()
2 DirectGLES/DirectGLES.cpp:4468 indexBuffer ScopedRestartIndexSubstitution (:4433) draw (primitive-restart rewrite) the element-array buffer before the whole-buffer restart-index rewrite
3 DirectGLES/DirectGLES.cpp:4722 drawBuffer MultiDrawElementsIndirectCount (:4685) draw (indirect count) GL_DRAW_INDIRECT_BUFFER
4 DirectGLES/DirectGLES.cpp:4723 parameterBuffer same draw (indirect count) GL_PARAMETER_BUFFER
5 DirectGLES/DirectGLES.cpp:4824 drawBuffer MultiDrawArraysIndirectCount (:4793) draw (indirect count) GL_DRAW_INDIRECT_BUFFER
6 DirectGLES/DirectGLES.cpp:4825 parameterBuffer same draw (indirect count) GL_PARAMETER_BUFFER
7 DirectGLES/Managers.cpp:1569 bufferObject EnsureBufferResource (the GLES buffer-resource ensure path) buffer op (draw/dispatch resource sync) pushes map writes before the respecify / pending-range flush decision at :1575-1584
8 DirectGLES/MultiDraw.cpp:510 indexBuffer the CPU multi-draw index flattener draw (MultiDrawElements flatten) the element-array buffer before flattening indices
9 DirectVulkan/DirectVulkan.cpp:280 drawBuffer ResolveIndirectCommandBytes (:277) draw (indirect, CPU fallback) GL_DRAW_INDIRECT_BUFFER
10 DirectVulkan/DirectVulkan.cpp:471 parameterBuffer MultiDrawArraysIndirectCount (:448) draw (indirect count, CPU fallback) GL_PARAMETER_BUFFER before memcpying the draw count
11 DirectVulkan/DirectVulkan.cpp:795 indexBufferShared line-loop / CPU index path (:788) draw (index read) the element-array buffer before reading indices
12 DirectVulkan/Renderer/UniformManager.cpp:2023 bufferObject ResolveUniformBufferPayload (:1962) program/uniform sync (UBO) the bound UBO before its bytes are staged into a descriptor
13 DirectVulkan/Renderer/VkBufferManager.cpp:628 bufferObject AcquireResidentSlice (:620) buffer op (any verb that acquires a resident slice) the buffer before its GPU-resident slice is used
14 DirectVulkan/Renderer/VkBufferManager.cpp:679 bufferObject AcquireStreamedSlice (:672) buffer op (streamed upload) the buffer before the transient copy is taken
15 DirectVulkan/Renderer/VulkanRenderer.cpp:3434 indexBufferShared TryComputeMaxIndexFromHostBytes (:3409) draw (index range scan) element-array buffer before the max-index scan
16 DirectVulkan/Renderer/VulkanRenderer.cpp:3513 bufferObject vertex-buffer fast-path revalidation inside UploadAndBindVertexBuffers (:3580's memo check block at :3500-3520) vertex sync (draw fast path) each bound vertex buffer before its slice epoch is trusted
17 DirectVulkan/Renderer/VulkanRenderer.cpp:3828 sourceBufferShared 64-bit attribute conversion inside UploadAndBindVertexBuffers vertex sync (fp64 narrowing) the source vertex buffer before CPU-side conversion
18 DirectVulkan/Renderer/VulkanRenderer.cpp:7137 indirectBuffer DispatchComputeIndirect (:7084) dispatch (indirect) GL_DISPATCH_INDIRECT_BUFFER
19 DirectVulkan/Renderer/VulkanRenderer.cpp:12132 drawBuffer MultiDrawElementsIndirectCount (:12074) draw (indirect count) GL_DRAW_INDIRECT_BUFFER
20 DirectVulkan/Renderer/VulkanRenderer.cpp:12133 parameterBuffer same draw (indirect count) GL_PARAMETER_BUFFER

Split: 8 DirectGLES / 12 DirectVulkan. By verb: draw 13, buffer op 3, vertex sync 2, dispatch 1, program/uniform sync 1. (Two further mentions are comments, not calls: DirectGLES/Managers.cpp:1461, :2681, DirectVulkan/Renderer/VulkanRenderer.h:1214.)

5.2 SyncGpuWrites() — 6 sites

Semantics: a submit-and-wait plus writeback for a buffer flagged gpu-write-pending (XFB capture, SSBO, storage texel buffer). Always paired with a CPU read of MappedData().

# file:line receiver enclosing function verb that owns it what it syncs
1 DirectGLES/DirectGLES.cpp:4469 indexBuffer ScopedRestartIndexSubstitution (:4433) draw (primitive-restart rewrite) pulls shader-written index bytes back before the rewrite
2 DirectGLES/Managers.cpp:2643 bufferObject the fp64 vertex-attribute converter (ConvertAttributeStream, in BackendVertexArrayObject) vertex sync (fp64 narrowing) pulls shader writes back before the CPU narrows doubles to floats
3 DirectGLES/MultiDraw.cpp:511 indexBuffer CPU multi-draw index flattener draw (MultiDrawElements flatten) shader-written indices before flattening
4 DirectVulkan/Renderer/VulkanRenderer.cpp:3433 indexBufferShared TryComputeMaxIndexFromHostBytes (:3409) draw (index range scan) recorded-but-unexecuted GPU writes into the coherent index mapping
5 DirectVulkan/Renderer/VulkanRenderer.cpp:3827 sourceBufferShared 64-bit attribute conversion in UploadAndBindVertexBuffers (:3580) vertex sync (fp64 narrowing) XFB/SSBO/texel-buffer writes into the source vertex buffer
6 DirectVulkan/Renderer/VulkanRenderer.cpp:4161 indexBufferShared UploadAndBindIndexBuffer (:4031), restart-substitution branch draw (primitive-restart rewrite) shader-written indices before the whole-buffer rewrite

Split: 3 DirectGLES / 3 DirectVulkan. By verb: draw 4, vertex sync 2. (Three further mentions are comments: DirectGLES/DirectGLES.cpp:459, :509, DirectGLES/Managers.cpp:2681.)

P1 note on both lists. Every one of the 26 sites is a synchronous, blocking call that the backend makes on a frontend object in order to read host bytes. Twelve of them are followed immediately by MappedData() (DirectGLES.cpp:269, 4470, 4740; MultiDraw.cpp:512; DirectVulkan.cpp:282, 477, 796; UniformManager.cpp:2025; VulkanRenderer.cpp:3435, 3830, 4163). Under disaggregation there is no shared address space for MappedData() to point into, so each of these 26 becomes either a pull-host-bytes reverse call or a client-side pre-resolution that ships the bytes with the verb. MG_Pipe/MGPipeHostSpan.h and the HostSpanCount field of MGP_FIELDS_MGPShaderBuffers (PipeFields.def) are the existing hooks; nothing in PipeFields.def covers the index buffer host span, which is what sites 1-3, 8, 11, 15 and 4/6 above need.