Commit Graph
3236 Commits
Author SHA1 Message Date
swung0x48 60bc3ca113 [MG_Backend] (Disaggregated): P5f fm - request native storage usage through texture views 2026-09-19 23:06:44 -04:00
swung0x48 e3919cee57 [MG_Backend] (Disaggregated): P5f fm - normalize storage image layer semantics by target 2026-09-19 23:06:17 -04:00
swung0x48 5855101d45 p5f fm: verify non-layered texture ignores image binding layer 2026-09-19 23:05:18 -04:00
swung0x48 4fd3a6b0e6 [MG_IntegrationTest] (Disaggregated): P5f fm - reconcile measured strict markers without widening 2026-09-19 23:05:05 -04:00
swung0x48 20f48d6e40 [MG_Pipe, MG_IntegrationTest] (Disaggregated): P5f fm - ratchet retired Magma clear and shared copy pulls 2026-09-19 23:03:30 -04:00
swung0x48 6c3662be9b [Docs] (Disaggregated): P5f fm - document implementation and verified gate checkpoint 2026-09-19 23:03:24 -04:00
swung0x48 e49414250c [MG_Backend] (Disaggregated): P5f fm - respect unrestricted sampler view windows 2026-09-19 23:03:18 -04:00
swung0x48 76b8a983d8 [MG_IntegrationTest] (Disaggregated): P5f fm - pin format behavior and the buffer refusal boundary 2026-09-19 23:02:35 -04:00
swung0x48 cff1493a49 p5f fm: pin VBO refusal and sRGB and 1D framebuffer behavior 2026-09-19 23:01:52 -04:00
swung0x48 b394a09f5b [MG_IntegrationTest] (Disaggregated): P5f fm - exercise server sampler and image programs 2026-09-19 22:59:17 -04:00
swung0x48 9852e41698 p5f fm: exercise wire sampler uniforms and storage image dispatch 2026-09-19 22:58:18 -04:00
swung0x48 73a0e96177 [MG_Test] (Disaggregated): P5f fm - pin independent object consumer emission gates 2026-09-19 22:58:10 -04:00
swung0x48 7b2253c8b7 [MG_Backend] (Disaggregated): P5f fm - retain framebuffer format and dimensionality rules 2026-09-19 22:54:51 -04:00
swung0x48 e6571e61e4 [MG_Backend] (Disaggregated): P5f fm - keep wire endpoint and transform checks role local 2026-09-19 22:53:35 -04:00
swung0x48 03620744c0 [CI] (Disaggregated): P5f fm - require named execution of the native format negative probe 2026-09-19 22:49:38 -04:00
swung0x48 9867425d64 [MG_IntegrationTest] (Disaggregated): P5f fm - identify preexisting native mip format debt 2026-09-19 22:48:55 -04:00
swung0x48 08927e79eb [MG_IntegrationTest] (Disaggregated): P5f fm - keep each wire scenario registration unique 2026-09-19 22:46:52 -04:00
swung0x48 54e015ef9f [MG_Backend] (Disaggregated): P5f fm - keep monolith named-blit clipping byte identical 2026-09-19 22:45:52 -04:00
swung0x48 a204b357e7 [MG_Pipe] (Disaggregated): P5f fm - correct texture staging record type 2026-09-19 22:45:02 -04:00
swung0x48 c747fa1fc2 [MG_Backend] (Disaggregated): P5f fm - preserve mipmap view windows and array extents 2026-09-19 22:44:39 -04:00
swung0x48 2e3088e6c4 [MG_Pipe] (Disaggregated): P5f fm - retain named null-data mip definitions 2026-09-19 22:43:44 -04:00
swung0x48 2c9b9d2a9f [MG_Backend] (Disaggregated): P5f fm - retire draw attachments after GPU completion 2026-09-19 22:43:35 -04:00
swung0x48 01e00bc495 [MG_Test] (Disaggregated): P5f fm - verify hookless texture staging lifecycle 2026-09-19 22:43:07 -04:00
swung0x48 777f706ca2 [MG_Pipe] (Disaggregated): P5f fm - retain texture staging without buffer backend ops 2026-09-19 22:42:07 -04:00
swung0x48 2d507d5bd4 [MG_IntegrationTest] (Disaggregated): P5f fm - cover bufferless draw and layered copies under role split 2026-09-19 22:41:47 -04:00
swung0x48 6a138a5221 [MG_Backend] (Disaggregated): P5f fm - fence remaining buffer debt and preserve native transfer layouts 2026-09-19 22:40:04 -04:00
swung0x48 fec49a54d8 [MG_Backend, MG_IntegrationTest] (Disaggregated): P5f fm - apply bufferless draws and compute from server records 2026-09-19 22:34:28 -04:00
swung0x48 a6223c6509 [MG_Backend] (Disaggregated): P5f fm - order wire image writes and preserve implicit alpha 2026-09-19 22:34:04 -04:00
swung0x48 d9fc45bf4c [MG_Backend] (Disaggregated): P5f fm - use shared image access constant 2026-09-19 22:32:57 -04:00
swung0x48 f37380d0dc [MG_Backend] (Disaggregated): P5f fm - resolve uniform descriptors from server records 2026-09-19 22:32:10 -04:00
swung0x48 2abc561721 p5f fm: cover GPU texture writes and view subresources 2026-09-19 22:29:36 -04:00
swung0x48 277d1a07f0 [MG_Test] (Disaggregated): P5f fm - pin server program overlays and identities 2026-09-19 22:29:33 -04:00
swung0x48 867c5c5efd [MG_Backend] (Disaggregated): P5f fm - expose archive stage and capture-mode queries 2026-09-19 22:27:51 -04:00
swung0x48 31795675f1 p5f fm: build Vulkan samplers from server-owned values 2026-09-19 22:27:43 -04:00
swung0x48 62bf26bf8c [MG_Pipe] (Disaggregated): P5f fm - admit registered server object consumers independently of buffer ops 2026-09-19 22:27:03 -04:00
swung0x48 6ae5944831 [MG_Backend] (Disaggregated): P5f fm - build Magma programs from server archive views 2026-09-19 22:26:23 -04:00
swung0x48 a6283f40f2 [MG_Backend, MG_Impl] (Disaggregated): P5f fm - map texture view attachments through wire identities 2026-09-19 22:23:05 -04:00
swung0x48 4b3afe7840 [MG_Backend] (Disaggregated): P5f fm - retain blit scissor clipping across wire arm 2026-09-19 22:20:53 -04:00
swung0x48 911cc74a57 [MG_Backend, MG_Impl, MG_Remote, CI] (Disaggregated): P5f fm - connect family records and preserve GPU texture writes 2026-09-19 22:18:24 -04:00
swung0x48 20bbf9647e [MG_Backend, MG_IntegrationTest] (Disaggregated): P5f fm - carry framebuffer copies and exercise Magma wire verbs 2026-09-19 22:11:38 -04:00
swung0x48 4593719a3c [MG_Backend] (Disaggregated): P5f fm - share native depth readback and retain masked clear behavior 2026-09-19 22:01:44 -04:00
swung0x48 036c3a3d5e [MG_Backend, MG_Pipe, MG_Remote] (Disaggregated): P5f fm - route framebuffer verbs through server records 2026-09-19 22:00:14 -04:00
swung0x48 418c765c58 [Docs, MG_IntegrationTest] (Disaggregated): P5f f1 report - the census ratchet's first version (6 pairs), CONTRACT-P5E section 3.2 marked landed, and the gate numbers 2026-09-19 10:39:40 -04:00
swung0x48 cfcc12f73a [MG_Backend, MG_Impl, MG_Remote, MG_Test, MG_IntegrationTest, CI] (Disaggregated): P5f f1 - the dual-block rehearsal: per-role PipeInputs, the MOBILEGL_IPC_ROLE_SPLIT_STATE knob, and the named-Fatal arm that makes the red a census 2026-09-19 09:59:33 -04:00
swung0x48 e75e00cb7a [Docs] (Disaggregated): P5f f0 - the eight-way read-only census reports
Statics, reverse channel, Magma cross-role sites, EGL control plane,
registry rekey, build/gate mechanics, the 15 BARRIER_PULLED fields'
carrier rulings, and the dual-block mechanism's design recon.
2026-09-19 09:08:56 -04:00
swung0x48 8b68b92c76 [Docs] (Disaggregated): P5f section 1 - the pointer fact, and one draw's full lifecycle through gPipeInputs
The section explained what gPipeInputs IS and what breaks under spawn, but not the one fact
that decides the shape of the fix, and not how a call actually reaches the driver through it.
Both are now in the document rather than only in the conversation that found them.

- THE POINTER FACT, now stated first because everything else follows from it: several
  BARRIER_PULLED fields do not hold values, they hold pointers into client-owned objects.
  PipeFill.cpp:274 fills m_textureUnitBase with `&ctx.GetTextureUnitObject(0)` - a raw base
  into the frontend's array - and :245 fills m_programForDraw with a SharedPtr<ProgramObject>.
  PipeInputs.h:669 dereferences it as `m_textureUnitBase[unit]`. PipeFill.cpp:2591-2592 says
  the same of the shader-buffer field: "four raw bases into the frontend's binding-point
  table".
  The consequence gets its own paragraph in 1.4, because it is the step most likely to be got
  wrong: this CANNOT be fixed by moving the block into shared memory. Mapping the same pages
  into both processes does not make a client heap address meaningful in the server, and a
  SharedPtr's refcount does not cross at all. The 15 fields each need a different SOURCE, not
  a shared location.

- NEW 1.2, one draw end to end: glBindTexture marks a tracker bit and sends nothing, because
  push only happens at a verb boundary; glDrawArrays enters MGPipeValidateForVerb
  (PipeFill.cpp:3347) whose four steps are barrier decision, dirty walk, emission (records,
  carrying handles), and the residual fill - which is where BARRIER_PULLED happens; the record
  goes on SEG_CMD; the apply thread dispatches to the backend; PrepareForDraw reads either a
  record-carried handle against the server's own tables, or gPipeInputs; then the real driver
  call. Plus the field lifetime: stamped with verb N's serial, read during verb N's apply,
  Fatal{UnmigratedPipeInput} if read at verb N+1 without a refill - one verb, never longer.

- The same example carries the Espryt/Magma split concretely: the texture binding reaches
  Espryt as a record with a handle (P5e retired GetTextureUnitObject for it) and reaches Magma
  through gPipeInputs into the client's array. That is FieldOwnership.def's own
  "P5e (Espryt unbarriered), P7 (Magma)" made legible, and it is why section 2.1's table has
  eight rows in that state.

Sections renumbered 1.1-1.4. Doc citation lint: 129 citations, 0 problems.
2026-09-19 06:02:28 -04:00
swung0x48 465656843b [Docs] (Disaggregated): P5f - every piece of state on the wire, and P6 is blocked until it is
P6's premise is that it is "only a transport swap". That premise was bought by P5c and has
expired. Measured on this head, the two roles still share state directly, so a spawned server
would have no source for it. P5f is the phase that makes the premise true, and P6 does not
start before it.

WHAT THE MEASUREMENT FOUND

- FieldOwnership.def still carries 21 BARRIER_PULLED rows over 15 distinct fields. That class
  is defined as "the server answers by reading a value the client's residual fill left in THE
  SINGLE SHARED gPipeInputs while the verb barrier holds both threads apart". Eight of those
  fields were retired by P5e for Espryt's unbarriered path only - Magma has not moved at all.
  The strict lane measures 10 live <field>@<verb> pairs today.
- gPipeInputs (MG_Backend/MGPipe/PipeInputs.h:835) is a plain process global,
  `inline PipeInputs& gPipeInputs = *new PipeInputs();` - not a shm segment. The client fills
  it (MG_Impl/Pipe/PipeFill.cpp), the backend reads it. Under spawn the two processes have
  DIFFERENT objects, the 15 BARRIER_PULLED fields have no filler in the server's copy, and
  every read is Fatal{UnmigratedPipeInput}. MG_Impl is not in the server, so "let the server
  fill it" is not available either. The header says this itself at :279 and :902.
- The twelve Server* EGL forwarders do not use the wire at all: they post a function pointer
  plus a stack-local void* through a one-slot mailbox (ServerLoop.cpp:533-568, :645). The
  SurfaceOp / SurfaceReply / WindowKind schema is defined in protocol.fbs and unused.
- Process-level statics with per-context semantics (g_syncedRenderStateParameters,
  ScopedDefaultUnpackState::s_synced) - and the full list is unknown, because this defect class
  is structurally invisible to inproc.
- MGPipeFrontendKeyedRegistryScope is still live at ~12 sites in DirectGLES.cpp, carrying
  P3b/P4b's debt: the registry is still keyed by frontend address / lifetime id.

THE SCOPE RULE

P5f takes the cross-process-blocking subset of P3b/P4b/P7/P8/P9 and nothing else. One test:
does it still hold in another address space? No -> P5f. Yes but slow or ugly -> it stays with
the phase that owns it. So Magma's nine fields and its direct writes into client storage come
here; content-addressed CSO, internal shader baking and the fixed-width rewrite stay P7's. The
reverse channel's asynchrony and ordering stay P9's; only the parts that touch client memory
move. Class C is NOT P5f's - a named refusal behaves identically in two processes.

THE CENTRAL MECHANISM: A TWO-BLOCK REHEARSAL

P5c set the same rule (rule E) and checked it by AUDIT - a human reading 59 lines. P5f checks
it by MACHINE: give each role its own PipeInputs under inproc, and its own copy of every
per-context static, behind a knob. Anything that depends on the two being the same object
becomes Fatal{UnmigratedPipeInput, "<Field>@<Verb>"} with the field and verb named.

That rehearses the process split's SEMANTICS without a second process. It matters because
today "the server read the value the client filled" and "the server read the value a record
carried" are indistinguishable at runtime - which is exactly what P6 would discover on day
one. The package order puts the mechanism (f1) BEFORE the migrations deliberately: let the red
appear first and let it be the worklist, rather than having each package declare itself done
and then looking for a criterion.

Exit gate: the two-block lane green; strict-expected-markers.txt EMPTY with its two-sided
ratchet still armed; zero BARRIER_PULLED rows; rsp reading zero per frame; Magma judged by the
same criteria as Espryt. The negative control is that turning the two-block knob OFF must move
at least one named case from green to red - otherwise the mechanism proves nothing, which is
ID-122's lesson.

ALSO IN THIS COMMIT

- ROADMAP gains the P5f row and the IPC track becomes P5e -> P5f -> P6; P6's status cell
  becomes "blocked on P5f".
- README and CURRENT_STAGE_PROGRESS gain the same, plus the file-map entry.
- Both P6 documents gain a blocked banner naming what is not true yet.

Doc citation lint: 124 citations across docs/Disaggregated/*.md, 0 problems.
2026-09-19 05:32:38 -04:00
swung0x48 7f1d2134c3 [Docs] (Disaggregated): P6 contract draft rewritten in concise wording, 269 -> 181 lines, same rows 2026-09-19 04:39:12 -04:00
swung0x48 e125b75655 [Docs] (Disaggregated): P6 plan rewritten in concise wording, 282 -> 124 lines, same content 2026-09-18 23:40:26 -04:00
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