diff --git a/MobileGL/MG_Impl/Pipe/FramebufferEmit.h b/MobileGL/MG_Impl/Pipe/FramebufferEmit.h index e4161a02..d583a416 100644 --- a/MobileGL/MG_Impl/Pipe/FramebufferEmit.h +++ b/MobileGL/MG_Impl/Pipe/FramebufferEmit.h @@ -400,7 +400,9 @@ namespace MobileGL::MG_Pipe { void ResetCounters() { m_emissions = m_refusals = 0; } - void ResetForTest() { + // A session that replaced an ended one (MGPipeForgetEndedSession), and a unit fixture: + // the latches and the counters, and the build memo and last states beside them. + void ForgetSession() { Reset(); ResetCounters(); for (auto& memo : m_buildMemo) diff --git a/MobileGL/MG_Impl/Pipe/PipeFill.cpp b/MobileGL/MG_Impl/Pipe/PipeFill.cpp index 2fd7d8d3..d3917968 100644 --- a/MobileGL/MG_Impl/Pipe/PipeFill.cpp +++ b/MobileGL/MG_Impl/Pipe/PipeFill.cpp @@ -3415,13 +3415,13 @@ namespace MobileGL::MG_Pipe { MGPipeTrackerInstance().Reset(); // The texture emitter's records and its owed uploads belong to the ended server; its // sampler references go back to the cache before the cache is emptied. - MGPipeTextureEmitterInstance().ResetForTest(); + MGPipeTextureEmitterInstance().ForgetSession(); MGPipeSamplerEmitterInstance().Reset(); - MGPipeSamplerCsoCacheInstance().ResetForTest(); + MGPipeSamplerCsoCacheInstance().ForgetSession(); MGPipeCsoCacheInstance().Reset(); MGPipeSetHashSuppressorInstance().InvalidateAll(); MGPipeVertexInputEmitterInstance().Reset(); - MGPipeFramebufferEmitterInstance().ResetForTest(); + MGPipeFramebufferEmitterInstance().ForgetSession(); MGPipeImageEmitterInstance().Reset(); MGPipeProgramEmitterInstance().Reset(); MGPipeShaderBufferEmitterInstance().Reset(); diff --git a/MobileGL/MG_Impl/Pipe/SamplerEmit.h b/MobileGL/MG_Impl/Pipe/SamplerEmit.h index 39e1add7..338be842 100644 --- a/MobileGL/MG_Impl/Pipe/SamplerEmit.h +++ b/MobileGL/MG_Impl/Pipe/SamplerEmit.h @@ -151,7 +151,7 @@ namespace MobileGL::MG_Pipe { // never shrinks back. Uint64 OverCapacityMints = 0; // A RELEASE THIS CACHE COULD NOT ACCOUNT FOR. UnknownReleases: the handle names no - // entry here (a stale handle from before a ResetForTest, a handle of another kind + // entry here (a stale handle from before a ForgetSession, a handle of another kind // passed by mistake, a handle whose entry was already evicted). UnderflowedReleases: // the entry was found with a count already 0. Both are contract violations by a // HOLDER and are counted rather than absorbed, because the pin they steal is @@ -189,11 +189,12 @@ namespace MobileGL::MG_Pipe { // named for it proves something else. It hashes nothing and simply uses the hash it is // given; production code has no reason to call it. // - // THE THREE MEMBERS A CONSUMER MUST NOT CALL are this one, ResetForTest() (which frees - // every slot the cache holds and drops their publication latches) and ResetCounters(). - // Package B's seam is Acquire / Release / RefCountOf / RecordIsPublished / Size / - // GetCounters and nothing else - the class is public because it is header-only, not - // because all nine members are for callers. + // The members a consumer must not call are this one and ResetCounters(); ForgetSession() + // (which frees every slot the cache holds and drops their publication latches) belongs to + // the end of a session (MGPipeForgetEndedSession) and to unit fixtures. Package B's seam + // is Acquire / Release / RefCountOf / RecordIsPublished / Size / GetCounters and nothing + // else - the class is public because it is header-only, not because all nine members are + // for callers. MGPipeHandle AcquireWithForcedHashForTest(const SamplerParameters& params, Uint64 forcedHash, Uint64& payloadBytes) { SamplerParameters canon; @@ -255,8 +256,8 @@ namespace MobileGL::MG_Pipe { return false; } - // A unit test's fixture, and a session that replaced an ended one (MGPipeForgetEndedSession: - // the fresh server holds none of these records). NOT called from the validate point's + // A session that replaced an ended one (MGPipeForgetEndedSession: the fresh server holds + // none of these records), and a unit test's fixture. NOT called from the validate point's // FreshlyPrimed arm: MGPipeApplierReset is a make-current and does NOT drop object // records, so a sampler CSO the applier holds outlives a context switch. Dropping the // cache there would leak the applier's record and re-mint a value it already has. @@ -265,7 +266,7 @@ namespace MobileGL::MG_Pipe { // delete_sampler_state behind them, so a latch left standing would make a future death // helper - on the recycled slot at the same generation - emit a delete for a record // that never existed, which is the refusal the applier counts. - void ResetForTest() { + void ForgetSession() { for (const Entry& entry : m_entries) { MGPipeNoteHandleUnpublished(MGPipeKind::SamplerCso, entry.Cso); MGPipeSlots().Free(MGPipeKind::SamplerCso, entry.Cso); diff --git a/MobileGL/MG_Impl/Pipe/TextureEmit.h b/MobileGL/MG_Impl/Pipe/TextureEmit.h index a1588c24..dec00b3f 100644 --- a/MobileGL/MG_Impl/Pipe/TextureEmit.h +++ b/MobileGL/MG_Impl/Pipe/TextureEmit.h @@ -1154,16 +1154,16 @@ namespace MobileGL::MG_Pipe { m_deadResolves = 0; } - // A unit fixture's per-case reset, and the reset of a session that replaced an ended one - // (MGPipeForgetEndedSession: the fresh server holds none of these records). See - // MGPipeResourceTracker::ResetForTest for the rule this restates: a texture handle and - // the applier record it names are SHARE-GROUP OBJECT STATE, so nothing here is - // per-context and no re-publication path exists or may exist. - // Moves whenever the handle table below is dropped (ResetForTest), so a memo that skipped + // ForgetSession is the reset of a session that replaced an ended one + // (MGPipeForgetEndedSession: the fresh server holds none of these records), and a unit + // fixture's per-case reset. See MGPipeResourceTracker::ResetForTest for the rule this + // restates: a texture handle and the applier record it names are SHARE-GROUP OBJECT + // STATE, so nothing here is per-context and no re-publication path exists or may exist. + // Moves whenever the handle table below is dropped (ForgetSession), so a memo that skipped // NoteTextureBoundAs / AcquireTexture for handles it already noted knows to note again. Uint64 TableEpoch() const { return m_tableEpoch; } - void ResetForTest() { + void ForgetSession() { ++m_tableEpoch; // EVERY REFERENCE THIS EMITTER OWES IS GIVEN BACK FIRST. A case that dropped the // table without releasing would pin cache entries for the rest of the process and diff --git a/MobileGL/MG_Test/Pipe/FramebufferEmitTest.cpp b/MobileGL/MG_Test/Pipe/FramebufferEmitTest.cpp index fdc7de2d..efdc2b75 100644 --- a/MobileGL/MG_Test/Pipe/FramebufferEmitTest.cpp +++ b/MobileGL/MG_Test/Pipe/FramebufferEmitTest.cpp @@ -248,8 +248,8 @@ namespace { kMGPipeSubsystemTextureResources | kMGPipeSubsystemSamplers; m_previousContext = MG_State::pGLContext.Take(); MG_State::pGLContext = MakeUnique(); - MGPipeFramebufferEmitterInstance().ResetForTest(); - MGPipeTextureEmitterInstance().ResetForTest(); + MGPipeFramebufferEmitterInstance().ForgetSession(); + MGPipeTextureEmitterInstance().ForgetSession(); MGPipeSetHashSuppressorInstance().InvalidateAll(); // The applier is a process singleton and its object records outlive a case; with both // families' wired constants set the emissions actually land, so a case must start @@ -259,8 +259,8 @@ namespace { MGPipeApplierReleaseObjectRecords(); } ~FramebufferScope() { - MGPipeFramebufferEmitterInstance().ResetForTest(); - MGPipeTextureEmitterInstance().ResetForTest(); + MGPipeFramebufferEmitterInstance().ForgetSession(); + MGPipeTextureEmitterInstance().ForgetSession(); MGPipeSetHashSuppressorInstance().InvalidateAll(); MGPipeApplierReset(); MGPipeApplierReleaseObjectRecords(); @@ -1345,7 +1345,7 @@ TEST(FramebufferEmit, TheBuildMemoReNotesBindBitsAfterTheTextureTableIsDropped) << "the attachment's RENDER_TARGET bit was never noted"; // A dropped table (a replaced session) forgets the sticky bits; the next build must note them again. - MGPipeTextureEmitterInstance().ResetForTest(); + MGPipeTextureEmitterInstance().ForgetSession(); MGPipeSetHashSuppressorInstance().InvalidateAll(); Framebuffers().EmitFramebufferState(Ctx()); EXPECT_NE(MGPipeTextureEmitterInstance().TextureBindMask(handle) & kMGPipeBindRenderTarget, 0) diff --git a/MobileGL/MG_Test/Pipe/ImageEmitTest.cpp b/MobileGL/MG_Test/Pipe/ImageEmitTest.cpp index b7cfaba7..800fd042 100644 --- a/MobileGL/MG_Test/Pipe/ImageEmitTest.cpp +++ b/MobileGL/MG_Test/Pipe/ImageEmitTest.cpp @@ -581,7 +581,7 @@ void main() { imageStore(img, ivec2(0), vec4(1.0)); } // Nothing produced the bit before the fix round. TEST(ImageEmit, AnImageBoundTextureIsMarkedShaderImageBoundAtTheBind) { EmitterScope scope; - MGPipeTextureEmitterInstance().ResetForTest(); + MGPipeTextureEmitterInstance().ForgetSession(); const GLuint name = MakeImageTexture(); const auto& texture = Ctx().GetTextureObject(name); ASSERT_TRUE(texture); diff --git a/MobileGL/MG_Test/Pipe/SamplerEmitTest.cpp b/MobileGL/MG_Test/Pipe/SamplerEmitTest.cpp index 3d400911..4e7431b7 100644 --- a/MobileGL/MG_Test/Pipe/SamplerEmitTest.cpp +++ b/MobileGL/MG_Test/Pipe/SamplerEmitTest.cpp @@ -543,7 +543,7 @@ namespace { static void Clear() { MGPipeSamplerEmitterInstance().Reset(); MGPipeSamplerEmitterInstance().ResetCounters(); - MGPipeSamplerCsoCacheInstance().ResetForTest(); + MGPipeSamplerCsoCacheInstance().ForgetSession(); MGPipeSamplerCsoCacheInstance().ResetCounters(); MGPipeSetHashSuppressorInstance().InvalidateAll(); } @@ -729,7 +729,7 @@ namespace { // The ordinary path, for completeness: two states that differ in ONE field never share // a handle and never reach the confirm at all. - Cache().ResetForTest(); + Cache().ForgetSession(); Cache().ResetCounters(); const MGPipeHandle plainFirst = Cache().Acquire(first, payload); const MGPipeHandle plainSecond = Cache().Acquire(second, payload); @@ -1193,7 +1193,7 @@ namespace { // Nothing produced the bit before the fix round. TEST(SamplerEmit, AResolvedSamplerViewMarksItsTextureAsSamplerBound) { EmitterScope scope; - MGPipeTextureEmitterInstance().ResetForTest(); + MGPipeTextureEmitterInstance().ForgetSession(); namespace GL = MobileGL::MG_Impl::GLImpl; const Uint program = MakeSamplerProgram(); GLint linked = 0; diff --git a/MobileGL/MG_Test/Pipe/TextureEmitTest.cpp b/MobileGL/MG_Test/Pipe/TextureEmitTest.cpp index 3fdafb7d..86ef101f 100644 --- a/MobileGL/MG_Test/Pipe/TextureEmitTest.cpp +++ b/MobileGL/MG_Test/Pipe/TextureEmitTest.cpp @@ -233,7 +233,7 @@ namespace { kMGPipeSubsystemResources | kMGPipeSubsystemTextureResources | kMGPipeSubsystemSamplers; m_previousContext = MG_State::pGLContext.Take(); MG_State::pGLContext = MakeUnique(); - MGPipeTextureEmitterInstance().ResetForTest(); + MGPipeTextureEmitterInstance().ForgetSession(); // AND THE APPLIER IS A PROCESS SINGLETON, so its object records outlive a case. With // kMGPipeWiredTextureSubsystem flipped the emitter's calls actually LAND, and a case // that inherited the previous one's records would assert against state it did not @@ -245,7 +245,7 @@ namespace { MGPipeApplierReleaseObjectRecords(); } ~TextureScope() { - MGPipeTextureEmitterInstance().ResetForTest(); + MGPipeTextureEmitterInstance().ForgetSession(); MGPipeApplierReset(); MGPipeApplierReleaseObjectRecords(); MG_State::pGLContext.reset();