mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
[Fix] (Espryt): unbind the sampler on every touched unit the pushed window does not describe instead of leaving an earlier draw's object on it
This commit is contained in:
@@ -4486,14 +4486,38 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
// Declines - falls through to the frontend walk - until the set has arrived, and the
|
// Declines - falls through to the frontend walk - until the set has arrived, and the
|
||||||
// COUNT says so rather than the serial (MGPipeApplierReset advances serials whether or
|
// COUNT says so rather than the serial (MGPipeApplierReset advances serials whether or
|
||||||
// not anything was emitted).
|
// not anything was emitted).
|
||||||
|
// P4a decline-site S1: M - the mask says this family is not switched on; stays silent
|
||||||
|
// at the verification round (becomes D's SamplerSubsystemEnabled()).
|
||||||
if (EsprytDrawSamplerHandlesEnabled()) {
|
if (EsprytDrawSamplerHandlesEnabled()) {
|
||||||
const auto& st = MG_Pipe::MGPipeApplier();
|
const auto& st = MG_Pipe::MGPipeApplier();
|
||||||
|
// P4a decline-site S2: S - flips to loud-once-then-the-frontend-walk at the
|
||||||
|
// verification round; a draw that touches units with no bind_sampler_states ever
|
||||||
|
// received is a seam defect once bit 11 is on and C has landed.
|
||||||
if (st.SamplerStateCount != 0) {
|
if (st.SamplerStateCount != 0) {
|
||||||
for (Int unit = 0; unit <= maxTouchedUnit; ++unit) {
|
for (Int unit = 0; unit <= maxTouchedUnit; ++unit) {
|
||||||
const Uint32 index = static_cast<Uint32>(unit);
|
const Uint32 index = static_cast<Uint32>(unit);
|
||||||
// Outside the received window there is no answer to replay: the var-tail
|
// P4a decline-site S3: the OUT-OF-WINDOW UNBIND (MAJOR-2, fixed here); no
|
||||||
// window IS the bound, and entries outside it are not cleared.
|
// flip remains at the verification round, only the A8 measurement below.
|
||||||
|
//
|
||||||
|
// A UNIT THE RECORD DOES NOT DESCRIBE IS UNBOUND, NOT SKIPPED. The var-tail
|
||||||
|
// window IS the bound for RECORD RETENTION - entries outside it are not
|
||||||
|
// cleared in the applier - but this loop is not reading records, it is
|
||||||
|
// writing DRIVER state, and for a driver binding "no record" means "no
|
||||||
|
// sampler object", which is exactly what the pre-handle arm's
|
||||||
|
// `else { UnbindSampler(unit); }` below says and why it was written: a
|
||||||
|
// sampler object left on the unit by an earlier draw keeps being applied,
|
||||||
|
// and on a multisample texture - which takes no sampler object at all - the
|
||||||
|
// draw is rejected outright. `continue` here reintroduced that defect on
|
||||||
|
// the new arm for every unit below SamplerStateStart or above the window,
|
||||||
|
// which is the same smaller-window direction DEV-3 refused.
|
||||||
|
//
|
||||||
|
// A8 again: nothing in the contract pins the window to cover
|
||||||
|
// [0, maxTouchedUnit]. If package C documents that it does, this branch
|
||||||
|
// becomes unreachable and can be asserted rather than executed; until then
|
||||||
|
// it is load-bearing, and the verification round measures
|
||||||
|
// (SamplerStateStart, SamplerStateCount) against maxTouchedUnit to say so.
|
||||||
if (index < st.SamplerStateStart || index - st.SamplerStateStart >= st.SamplerStateCount) {
|
if (index < st.SamplerStateStart || index - st.SamplerStateStart >= st.SamplerStateCount) {
|
||||||
|
SamplerImpl::UnbindSampler(unit);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const MG_Pipe::MGPipeHandle sampler = st.BoundSamplerStates[index];
|
const MG_Pipe::MGPipeHandle sampler = st.BoundSamplerStates[index];
|
||||||
@@ -4501,6 +4525,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
SamplerImpl::UnbindSampler(unit);
|
SamplerImpl::UnbindSampler(unit);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// P4a decline-site S4: M - a live handle whose twin does not exist yet is
|
||||||
|
// left alone and deliberately NOT cached as a miss: the program pass
|
||||||
|
// creates the twin later in the same draw and its Bind moves the shadow
|
||||||
|
// row, which re-opens this memo. Parity with ResolveUnitSamplerBackend's
|
||||||
|
// null path; stays silent at the verification round.
|
||||||
if (auto* slot = SamplerImpl::g_backendSamplerObjects.FindByHandle(sampler);
|
if (auto* slot = SamplerImpl::g_backendSamplerObjects.FindByHandle(sampler);
|
||||||
slot && *slot) {
|
slot && *slot) {
|
||||||
(*slot)->Bind(unit);
|
(*slot)->Bind(unit);
|
||||||
|
|||||||
Reference in New Issue
Block a user