mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-13 06:38:31 +09:00
[Refactor] (Espryt): read the applier's framebuffer records through one accessor, carry D-K2's fourth row into the temporary latches and tick the declining epoch arm as a miss
This commit is contained in:
@@ -201,7 +201,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
// beside ResolveResourceSubsystemArm / ResolveVertexInputSubsystemArm in Managers.cpp -
|
// beside ResolveResourceSubsystemArm / ResolveVertexInputSubsystemArm in Managers.cpp -
|
||||||
// which is package D's file for the whole phase, so the draw-path package cannot write
|
// which is package D's file for the whole phase, so the draw-path package cannot write
|
||||||
// them. It is landed BEFORE D, so it carries its own bit tests until those latches exist;
|
// them. It is landed BEFORE D, so it carries its own bit tests until those latches exist;
|
||||||
// at the rebase every one of these becomes a call to D's, which additionally
|
// at the rebase every one of these is DELETED and its callers call D's PUBLIC WRAPPERS -
|
||||||
|
// FramebufferSubsystemEnabled() / TextureResourceSubsystemEnabled() /
|
||||||
|
// SamplerSubsystemEnabled() / ProgramSubsystemEnabled() (Managers.h, beside the four
|
||||||
|
// Resolve<Family>SubsystemArm() resolvers; the WRAPPER holds the `static const` latch, so
|
||||||
|
// the resolver is never the thing to call) - which additionally
|
||||||
//
|
//
|
||||||
// * LOGS each dependency refusal with one MGLOG_E naming BOTH bits, and
|
// * LOGS each dependency refusal with one MGLOG_E naming BOTH bits, and
|
||||||
// * reaches PipeSubsystemArmVerdict::NoArm and STOPS with the named
|
// * reaches PipeSubsystemArmVerdict::NoArm and STOPS with the named
|
||||||
@@ -210,20 +214,32 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
// arrays, the twin's cheap-gate trio, UnitSamplerLookupMemo's WeakPtr rows and
|
// arrays, the twin's cheap-gate trio, UnitSamplerLookupMemo's WeakPtr rows and
|
||||||
// g_programTwinLookupMemo are all pre-handle arms).
|
// g_programTwinLookupMemo are all pre-handle arms).
|
||||||
//
|
//
|
||||||
// The dependency DIRECTIONS are copied here verbatim, so a mask that half-runs is refused
|
// The dependency DIRECTIONS are copied here, so a mask that half-runs is refused in the
|
||||||
// in the meantime too and the A/B is not silently wrong; the refusal log and the stop are
|
// meantime too and the A/B is not silently wrong; the refusal log and the stop are D's and
|
||||||
// D's and are deliberately not duplicated here, because two writers of one diagnostic is
|
// are deliberately not duplicated here, because two writers of one diagnostic is how the
|
||||||
// how the two drift.
|
// two drift.
|
||||||
|
//
|
||||||
|
// D-K2 HAS FOUR ROWS, NOT THREE (ID-15). The brief's table said "bit 10 without bit 11 is
|
||||||
|
// fine"; that is wrong for P4a as built - MGPTextureParams::BuiltinSampler is a SamplerCso
|
||||||
|
// handle, only bit 11 mints sampler CSOs, and a null there is Fatal. So BIT 10 REQUIRES BIT
|
||||||
|
// 11 as well, which makes the texture-resource and sampler latches the same predicate by
|
||||||
|
// construction. D's mirror comment (esprytobj Managers.h ~631) still states the refuted
|
||||||
|
// sentence out loud and is D's own rework item; nothing here may copy it forward. The row
|
||||||
|
// is spelled as a RAW BIT TEST rather than as a call to the sampler latch, because the two
|
||||||
|
// latches would otherwise initialise each other.
|
||||||
//
|
//
|
||||||
// Latched once per process for the reason Managers.h gives for the other two: the two arms
|
// Latched once per process for the reason Managers.h gives for the other two: the two arms
|
||||||
// keep their state in different places, so an answer that changed mid-run would strand
|
// keep their state in different places, so an answer that changed mid-run would strand
|
||||||
// everything already built against the previous one.
|
// everything already built against the previous one.
|
||||||
static Bool EsprytDrawTextureResourceHandlesEnabled() {
|
static Bool EsprytDrawTextureResourceHandlesEnabled() {
|
||||||
// Bit 10 requires bit 7: a buffer texture's BufferForTexBuffer names a Buffer handle
|
// Bit 10 requires bit 7: a buffer texture's BufferForTexBuffer names a Buffer handle
|
||||||
// and only bit 7 puts twins in that table (D-K2).
|
// and only bit 7 puts twins in that table (D-K2 row 3).
|
||||||
|
// Bit 10 requires bit 11 (D-K2 row 4, ID-15): MGPTextureParams::BuiltinSampler is a
|
||||||
|
// SamplerCso handle and only bit 11 mints those.
|
||||||
static const Bool enabled =
|
static const Bool enabled =
|
||||||
(MG_Config::Features.PipePush & MG_Pipe::kMGPipeSubsystemTextureResources) != 0 &&
|
(MG_Config::Features.PipePush & MG_Pipe::kMGPipeSubsystemTextureResources) != 0 &&
|
||||||
(MG_Config::Features.PipePush & MG_Pipe::kMGPipeSubsystemResources) != 0;
|
(MG_Config::Features.PipePush & MG_Pipe::kMGPipeSubsystemResources) != 0 &&
|
||||||
|
(MG_Config::Features.PipePush & MG_Pipe::kMGPipeSubsystemSamplers) != 0;
|
||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,6 +267,24 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
(MG_Config::Features.PipePush & MG_Pipe::kMGPipeSubsystemPrograms) != 0;
|
(MG_Config::Features.PipePush & MG_Pipe::kMGPipeSubsystemPrograms) != 0;
|
||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// THE ONE PLACE THIS FILE ASKS THE APPLIER "which framebuffer record describes this
|
||||||
|
// binding". Six reads used to spell `MGPipeApplier().DrawFramebuffer` / `.ReadFramebuffer`
|
||||||
|
// inline; they go through here instead, for exactly one reason.
|
||||||
|
//
|
||||||
|
// ID-19 turns the applier's framebuffer state into a PER-OBJECT table keyed by the
|
||||||
|
// framebuffer handle, with `BoundFramebuffer[Draw|Read]` holding the bound handles, so that
|
||||||
|
// the DSA entry points (BlitNamedFramebuffer, the four ClearNamedFramebuffer*) can be
|
||||||
|
// handed a record for a framebuffer that is bound to neither binding. Wire v3 keeps
|
||||||
|
// `DrawFramebuffer` / `ReadFramebuffer` as ACCESSORS OF THOSE NAMES resolving through the
|
||||||
|
// bound handle, precisely so this package keeps its shape. If they land as member functions
|
||||||
|
// rather than as members, this one function grows a pair of parentheses and nothing else in
|
||||||
|
// this file moves; if the accessor can answer "no record for the bound handle", that answer
|
||||||
|
// arrives here as a null Fbo, which is already what every caller treats as a decline.
|
||||||
|
static const MG_Pipe::MGPFramebufferState& BoundFramebufferRecord(FramebufferTarget target) {
|
||||||
|
const auto& st = MG_Pipe::MGPipeApplier();
|
||||||
|
return target == FramebufferTarget::Draw ? st.DrawFramebuffer : st.ReadFramebuffer;
|
||||||
|
}
|
||||||
#endif // MOBILEGL_PIPE_PUSH
|
#endif // MOBILEGL_PIPE_PUSH
|
||||||
|
|
||||||
static Bool IsDualSourceBlendFactor(BlendFactor v) {
|
static Bool IsDualSourceBlendFactor(BlendFactor v) {
|
||||||
@@ -278,8 +312,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
// RECORDED HERE ON PURPOSE: this pair of file-static SharedPtrs is the largest surviving
|
// RECORDED HERE ON PURPOSE: this pair of file-static SharedPtrs is the largest surviving
|
||||||
// MG_State-type usage anywhere under MG_Backend/DirectGLES, and its owner is P3b/P4b - so
|
// MG_State-type usage anywhere under MG_Backend/DirectGLES, and its owner is P3b/P4b - so
|
||||||
// the include-graph gate at P13 meets a known item rather than a surprise. The purity
|
// the include-graph gate at P13 meets a known item rather than a surprise. The purity
|
||||||
// gates are unaffected either way: they grep for pGLContext under MG_Backend and for an
|
// gates are unaffected either way: they grep MG_Backend for the pull arm's live-GLContext
|
||||||
// MG_State type inside MGPipeResourceOps, and this is neither.
|
// pointer token (G13 - deliberately not spelled here, because that grep is a BARE TOKEN
|
||||||
|
// grep and a comment naming it is a hit) and for an MG_State type inside
|
||||||
|
// MGPipeResourceOps, and this is neither.
|
||||||
SamplerImpl::BackendSamplerObject* GetRawDepthFetchSampler() {
|
SamplerImpl::BackendSamplerObject* GetRawDepthFetchSampler() {
|
||||||
if (!g_rawDepthFetchSamplerState) {
|
if (!g_rawDepthFetchSamplerState) {
|
||||||
g_rawDepthFetchSamplerState = MakeShared<MG_State::GLState::SamplerObject>(0);
|
g_rawDepthFetchSamplerState = MakeShared<MG_State::GLState::SamplerObject>(0);
|
||||||
@@ -1849,6 +1885,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
// meet except with vanishing probability - and a collision costs a spare rebuild.
|
// meet except with vanishing probability - and a collision costs a spare rebuild.
|
||||||
static Bool UnitBindingsEpochFromRecords(Uint64& out) {
|
static Bool UnitBindingsEpochFromRecords(Uint64& out) {
|
||||||
const auto& st = MG_Pipe::MGPipeApplier();
|
const auto& st = MG_Pipe::MGPipeApplier();
|
||||||
|
// P4a decline-site T2: S - flips to MGLOG_E_ONCE-then-decline at the verification
|
||||||
|
// round. Once bits 10/11 are on and B/C have landed, a draw that reaches here
|
||||||
|
// with neither window ever received is a seam defect, not a transitional state;
|
||||||
|
// the gate tick below (MINOR-4) is what makes the decline countable in the
|
||||||
|
// meantime.
|
||||||
if (st.SamplerViewCount == 0 && st.SamplerStateCount == 0) return false;
|
if (st.SamplerViewCount == 0 && st.SamplerStateCount == 0) return false;
|
||||||
// Local, because the tracker's MGPipeMixShutter lives in MG_Impl and no backend
|
// Local, because the tracker's MGPipeMixShutter lives in MG_Impl and no backend
|
||||||
// translation unit may reach for it.
|
// translation unit may reach for it.
|
||||||
@@ -1861,6 +1902,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
|
|
||||||
static Uint64 CurrentUnitBindingsEpoch(Int maxTouchedUnit) {
|
static Uint64 CurrentUnitBindingsEpoch(Int maxTouchedUnit) {
|
||||||
#if MOBILEGL_PIPE_PUSH
|
#if MOBILEGL_PIPE_PUSH
|
||||||
|
// P4a decline-site T1: M - the mask says this family is not switched on; stays
|
||||||
|
// silent at the verification round (becomes D's SamplerSubsystemEnabled()).
|
||||||
if (EsprytDrawSamplerHandlesEnabled()) {
|
if (EsprytDrawSamplerHandlesEnabled()) {
|
||||||
Uint64 epochFromRecords = 0;
|
Uint64 epochFromRecords = 0;
|
||||||
if (UnitBindingsEpochFromRecords(epochFromRecords)) {
|
if (UnitBindingsEpochFromRecords(epochFromRecords)) {
|
||||||
@@ -1872,6 +1915,17 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
}
|
}
|
||||||
return epochFromRecords;
|
return epochFromRecords;
|
||||||
}
|
}
|
||||||
|
// MINOR-4. THE RECORD ARM'S DECLINE IS TICKED AS A MISS, and it has to be:
|
||||||
|
// the walk arm below ticks the SAME gate with its own hit/miss, so without
|
||||||
|
// this a fully declining tree reports the walk memo's high hit rate on
|
||||||
|
// Gate::EsprytUnitBindingsEpoch and the verification round's "hit rate goes to
|
||||||
|
// 100%" cannot tell "the record arm engaged" from "the walk arm's memo hit".
|
||||||
|
// With it, every declining call contributes at least one miss, so 100% means
|
||||||
|
// exactly one thing.
|
||||||
|
if (MG_Util::PipeStats::Enabled()) {
|
||||||
|
MG_Util::PipeStats::CountGate(MG_Util::PipeStats::Gate::EsprytUnitBindingsEpoch,
|
||||||
|
/*hit=*/false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
const Uint64 contextId = MGB_CTX->GetTextureContextId();
|
const Uint64 contextId = MGB_CTX->GetTextureContextId();
|
||||||
@@ -2064,8 +2118,13 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
|
|
||||||
Bool recordKeyed = false;
|
Bool recordKeyed = false;
|
||||||
Uint64 contentHash = 0;
|
Uint64 contentHash = 0;
|
||||||
|
// P4a decline-site F8 (read list): K - not a behavioural decline but a memo-KEY
|
||||||
|
// selection. Both key shapes are correct and are held in separate fields, so a
|
||||||
|
// process that runs the version key before the first emission and the ContentHash
|
||||||
|
// key after it never compares one against the other. No flip at the verification
|
||||||
|
// round.
|
||||||
if (EsprytDrawFramebufferHandlesEnabled()) {
|
if (EsprytDrawFramebufferHandlesEnabled()) {
|
||||||
const auto& record = MG_Pipe::MGPipeApplier().ReadFramebuffer;
|
const auto& record = BoundFramebufferRecord(FramebufferTarget::Read);
|
||||||
if (!MG_Pipe::MGPipeHandleIsNull(record.Fbo)) {
|
if (!MG_Pipe::MGPipeHandleIsNull(record.Fbo)) {
|
||||||
recordKeyed = true;
|
recordKeyed = true;
|
||||||
contentHash = record.ContentHash;
|
contentHash = record.ContentHash;
|
||||||
@@ -2208,8 +2267,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
#if MOBILEGL_PIPE_PUSH
|
#if MOBILEGL_PIPE_PUSH
|
||||||
Bool fboRecordKeyed = false;
|
Bool fboRecordKeyed = false;
|
||||||
Uint64 fboContentHash = 0;
|
Uint64 fboContentHash = 0;
|
||||||
|
// P4a decline-site F8 (draw list): K - a memo-KEY selection, not a decline; see
|
||||||
|
// the read list's F8 note above. No flip at the verification round.
|
||||||
if (EsprytDrawFramebufferHandlesEnabled()) {
|
if (EsprytDrawFramebufferHandlesEnabled()) {
|
||||||
const auto& drawRecord = MG_Pipe::MGPipeApplier().DrawFramebuffer;
|
const auto& drawRecord = BoundFramebufferRecord(FramebufferTarget::Draw);
|
||||||
if (!MG_Pipe::MGPipeHandleIsNull(drawRecord.Fbo)) {
|
if (!MG_Pipe::MGPipeHandleIsNull(drawRecord.Fbo)) {
|
||||||
fboRecordKeyed = true;
|
fboRecordKeyed = true;
|
||||||
fboContentHash = drawRecord.ContentHash;
|
fboContentHash = drawRecord.ContentHash;
|
||||||
|
|||||||
Reference in New Issue
Block a user