- Counters::Binds was declared, documented as one of the three numbers P13's capacity retune
reads, and incremented nowhere: the retune would have read a permanent zero, and the unit
tests counted binds in a local of their own
- counted in Acquire, which has exactly one caller and is followed by a bind_render_state
every time, so the count cannot drift from the emitter forgetting to tick it
- TrackerWalk drives the tracker and the cache DIRECTLY rather than through
MGPipeValidateForVerb: the validate point reaches the library's one process-wide tracker, and
a unit test that asserts on a shared singleton fails the moment ctest runs the suite in
parallel. The three lines of emission logic it reproduces are the same three lines.
- BlendToggleReusesTwoCsos is the Blaze3D shape the whole "push at validate, not in the
setter" decision was made for: 32 enable/draw/disable/draw pairs mint exactly TWO CSOs, bind
64 times and hit 62. A per-setter design would show up here as 64 mints.
- ViewportDoesNotMintACso is the regression RenderState.h records: 16 glViewports mint nothing,
never move the pipeline version, and each sends exactly chunk D0 - not the other seven.
- WrapAroundRePushesButNeverMisses drives m_version past 65535 and asserts every one of 70000
changes fired. The alternating value deliberately never touches the default: a setter that
early-outs would otherwise make the first iteration a false miss and hide a real one.
- AggregateGenerationCatchesABoundTextureMoving is the first test of the direction the P1
verify comparator cannot see - it compares object-class fields by identity only, so a bound
texture whose content moved looks unchanged to it. The bit fires and then settles, so it is a
shutter and not a stuck flag.
- ANaNPatchLevelEqualsItselfAndDoesNotFireForever: a NaN outer level is a legal
glPatchParameterfv value, float equality says it differs from itself and a byte compare says
it does not. That is why the shutter is a memcmp.
- ThePixelPackShutterIsAByteCompareOfThePackHalfOnly asserts an UNPACK write does not move the
pack shutter, which is the half that deliberately has no carrier.
- HashCollisionDoesNotAliasTwoStates needed a seam and got one: MGPipeCsoCache::s_hashForTest,
null in every real build, one never-taken branch on a path that runs only when the pipeline
version moved. Without it the memcmp confirm is unreachable code that nothing can prove is
doing anything, and what it stops - two different render states on one CSO - is silent wrong
pixels with no gate that can see it.
- ContentAddressingOffMintsEveryTime pins that bit 63 really changes mint/reuse behaviour, so
the negative control cannot rot into a dead switch.
- The set-hash suppressor is exercised on all seven slots even though P2 wires one, including
the reserved-zero contract: a computed hash of 0 is remapped to 1 so it is never confused
with "never emitted".
- MG_Impl/Pipe/CsoCache.h: 64 entries, LRU, hash -> probe -> MEMCMP -> handle. The memcmp is
not optional: a bare 64-bit hash equality would let a collision alias two different render
states onto one CSO, which is silent wrong pixels with no gate that can see it, and Mesa's
cso_cache memcmps for exactly that reason. It runs only when the pipeline version moved, so
never in the steady state. Eviction emits delete_render_state and frees the client slot.
- kMGPipeBehaviourNoCsoContentAddressing (bit 63) turns off the PROBE and the handle reuse,
not the records: every pipeline-version change then mints, binds and evicts, which is the
whole-block content addressing the design is measured against.
- The validate point's step 3: bind_render_state when the pipeline version moved (12 bytes, no
hashing, no blob when the cache hits), set_dynamic_state when m_version moved, carrying only
the dynamic chunks that differ from the tracker's staging mirror. An EMPTY chunk mask still
sends the 32-byte header, because the version is what Magma's dynamic tail gates on and it
moved.
- The residual fill now skips a field a P2 call supplies, driven by the generated
kMGPipeFieldEmittedBy[] and gated per subsystem on the runtime MOBILEGL_PIPE_PUSH bitmask, so
the bitmask is a true per-subsystem A/B. THE STAMP IS UNCHANGED: a stamp says "this verb
published this field", which is as true of an emitted field as of a copied one, and
withholding it would abort every backend read of the fields the migration just took over.
- PipeStats::RecordDrawPayloadBytes has been implemented, unit-tested and called by nothing
since P0. This is its first emitter.
- A field that reaches PipeInputs only through MGPipeDeriveRenderStateFields is skipped only
when that derivation is really there. It is package A's and is a declared stub on the
p2/contract tag this branch starts from, so rather than hard-code which branch this is, the
filler probes once: a sentinel in a scratch block, the mirror cleared, the derivation run,
the answer latched. It stays useful after A lands - if the derivation is ever deleted the
filler degrades to PULLING those fields rather than rendering a default.
- integration-verify, 818 entries, green: the comparator re-reads every field from the live
context at every backend read, so "the assembled block equals the live context" is now
proven rather than asserted, and the entry compare has stopped being a tautology.