mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 10:03:23 +09:00
[Fix, Test] (Magma, MG_Test): cover the {slot, gen} generation in a unit test that forces a real slot reuse, and stop claiming the ABA lanes do
- 55d2af9b claimed - in its message, in MagmaPipeArms.h, in VertexInputStateFactory.cpp and
in MG_IntegrationTest/CMakeLists.txt - that the AbaControlHandles lane defeats the
GENERATION in {slot, gen}. It does not, and no lane of that shape can. Magma's mint has no
death notification (nothing in MG_Backend/DirectVulkan consumes NotifyStateObjectDestroyed)
and returns a slot only through OnFrameBoundary's age sweep, kSweepInterval 256 /
kRetireAgeBoundaries 1024; HandleRecycleScenario issues five frame boundaries, so the
replacement VAO acquires against an empty free list and gets a BRAND-NEW slot at Gen 1
(measured: redVao slot=2 gen=1, greenVao slot=3 gen=1). The knob-off FRESH verdict there is
decided by the SLOT alone, and deleting ++m_entries[index].Gen leaves all 32 HandleRecycle
entries green - re-measured this round.
- What the lane does defeat is the object identity that SELECTS the slot, which IS the key the
handle arm ships, and that is what the three code sites now say. The two requirements are
mutually exclusive for the pixel-visible memo: a genuine slot reuse needs >= 1024 idle
boundaries after the dead object's last draw, which necessarily puts the two draws in
different frames, and ResolvedVertexBindings - the only memo carrying a GPU slice rather
than a layout - declines across frames by design.
- So the generation is covered where it IS expressible. MG_Test/Pipe/MagmaPipeIdentityTest.cpp
drives the mint's real retire -> reuse (1280 boundaries, with a keep-alive object holding the
first allocatable slot so the reuse is not the slot the control aliases onto) and asserts
four things: the retired slot comes back with Gen+1; with the knob OFF a memo stamped at
{slot, gen=N} is NOT served at {slot, gen=N+1}; with the knob ON it IS, out of one uncleared
and unclaimed entry; and a live object keeps its slot, its generation and its memo across two
sweeps, so the generation cannot be "fixed" by bumping it on every acquisition.
- The claim rule itself moves into MagmaPipeArms.h as MagmaPipeClaimSlotMemos so the suite
exercises production code rather than a copy of it. VertexInputStateFactory::MemosFor is now
one call to it and is otherwise unchanged, on both the knob-on and the knob-off path.
- Load-bearing, measured: with ++m_entries[index].Gen commented out, ctest -L unit in
build-push goes 1563/1566 - three of the four new cases red, one of them naming the inherited
0xDEAD payload out of the same slot - while ctest -R HandleRecycle stays 32/32. Restored, all
four pass in build-push and build-verify and skip visibly in the pull build, so the ctest name
sets stay identical (G2).
This commit is contained in:
@@ -98,22 +98,16 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
// does this, and no two live VAOs can share an entry however large the working set is.
|
||||
// There is no probe in front of it because the mint itself is one - a one-entry memo
|
||||
// hit for every acquisition after this draw's first, and a hash probe otherwise.
|
||||
if (MagmaPipeAbaControlDefeatsIdentity()) {
|
||||
// Negative control C: one entry for every VAO, claimed without the Owner compare,
|
||||
// which is precisely "the slot was recycled and Gen did not move". The replacement
|
||||
// therefore inherits the dead VAO's content hash and its resolved-entry pointer -
|
||||
// the two facts the generation is the only thing protecting.
|
||||
return m_vaoMemos[kMagmaPipeAbaControlSlotIndex];
|
||||
}
|
||||
VaoBackendMemos& memos = m_vaoMemos[MagmaPipeSlotIndex(handle)];
|
||||
if (!(memos.Owner == handle)) {
|
||||
// A slot whose Gen moved because the identity table recycled it for a different
|
||||
// object. Claim it, contents cleared - never inherited, which is the whole point
|
||||
// of keying on the generation.
|
||||
memos = VaoBackendMemos{};
|
||||
memos.Owner = handle;
|
||||
}
|
||||
return memos;
|
||||
//
|
||||
// The claim rule - the slot picks the entry, the whole handle (Gen included) decides
|
||||
// whose it is - and negative control C's defeat of it are MagmaPipeArms.h's
|
||||
// MagmaPipeClaimSlotMemos, so that the unit suite which drives a REAL slot reuse
|
||||
// (MG_Test/Pipe/MagmaPipeIdentityTest.cpp) exercises this code and not a copy of it.
|
||||
// What the control defeats HERE is the identity that SELECTS the entry: every VAO
|
||||
// collapses onto one, handed back uncleared, so the replacement inherits the dead
|
||||
// VAO's content hash and its resolved-entry pointer. The GENERATION half is the unit
|
||||
// suite's business, for the reason MagmaPipeAbaControlDefeatsIdentity spells out.
|
||||
return MagmaPipeClaimSlotMemos(m_vaoMemos, handle);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user