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.
27 KiB
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.