mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-09 12:48:32 +09:00
[Refactor] (Espryt): take the sampler parameters and the program artefacts from the applier instead of the frontend objects
This commit is contained in:
@@ -11206,6 +11206,40 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
ReseedShaderStorageBlockBindings(m_backendProgramId, *stateProgramObject);
|
||||
m_syncedLinkVersion = stateProgramObject->GetLinkVersion();
|
||||
m_syncedImageUnitVersion = stateProgramObject->GetImageUnitVersion();
|
||||
#if MOBILEGL_PIPE_PUSH
|
||||
// P4a (D-B3): the ShaderCso record's Serial, stamped in the same breath as the two
|
||||
// frontend versions it replaces. GetSyncedShaderCsoSerial() beside
|
||||
// GetSyncedLinkVersion()/GetSyncedImageUnitVersion() is what the draw path's
|
||||
// nine-clause rebuild condition reads on the handle arm; the clause COUNT does not
|
||||
// shrink, its inputs move (D-H5).
|
||||
//
|
||||
// WHAT DOES *NOT* MOVE, and it is a design statement rather than an omission: the
|
||||
// ARTEFACTS. D-H3 rules that in monolith all seven MGPBlobRefs are declared with
|
||||
// Size 0 - "this record does not declare its blob" - and the LinkArtifacts /
|
||||
// SpirvArtifacts ride beside the record through the entry point's companion
|
||||
// pointers, so the applier stores the DESCRIPTOR and the identity and the server
|
||||
// reads the frontend's own archive. That is what keeps the codec off the monolith
|
||||
// hot path entirely, and it is why every artefact read above is still a read of
|
||||
// stateProgramObject. The verify build is where the codec is exercised, by
|
||||
// serialising, deserialising and field-comparing before storing.
|
||||
if (ProgramSubsystemEnabled()) {
|
||||
// MONOLITH GLUE: the ShaderCso handle of a program this backend still arrives
|
||||
// holding. The reader hides the composite band, so a program-pipeline composite
|
||||
// - which the server must never learn is one - resolves through the same call.
|
||||
const MG_Pipe::MGPipeHandle cso = g_backendProgramObjects.HandleOf(stateProgramObject.get());
|
||||
const auto* record = PipeShaderCsoRecordForHandle(cso);
|
||||
if (record != nullptr) {
|
||||
m_syncedShaderCsoSerial = record->Serial;
|
||||
} else {
|
||||
// NOT a fall-back and not a silent zero: a stamped 0 would make every later
|
||||
// serial compare fire for ever, which is the safe direction but hides the
|
||||
// missing record. Name it and leave the memo where it was.
|
||||
MGLOG_E_ONCE("MGPipe: program %u has no shader-CSO applier record on the handle "
|
||||
"arm, so its synced serial cannot be stamped (handle {%u, %u})",
|
||||
stateProgramObject->GetExternalIndex(), cso.Slot, cso.Gen);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
m_isInitialized = true;
|
||||
MGLOG_D("Program sync completed. backend ID %u", m_backendProgramId);
|
||||
@@ -11431,6 +11465,57 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
return;
|
||||
}
|
||||
|
||||
// P4a (D-F1): a SamplerObject is a pure 100-byte value with no driver-side per-object
|
||||
// binding state, so its CSO is CONTENT-ADDRESSED on the client at capacity 256 and
|
||||
// two identical samplers share one record. What that means here is that the record's
|
||||
// server-owned Serial, not the frontend object's version, is what says the values
|
||||
// moved - and that the values themselves cross byte for byte INCLUDING
|
||||
// borderColorForm, which is why all four border comparands below are still compared.
|
||||
//
|
||||
// The whole arm choice is a preprocessor #if/#else so the PULL build's text is the
|
||||
// pre-P4a text token for token (D-P).
|
||||
#if MOBILEGL_PIPE_PUSH
|
||||
const SamplerParameters* pushedParams = nullptr;
|
||||
if (SamplerSubsystemEnabled()) {
|
||||
// MONOLITH GLUE: the SamplerCso handle of an object this backend still arrives
|
||||
// holding. Under a real split it rides in the payload, and every path P4a
|
||||
// switches over already carries it - this is for the paths that do not.
|
||||
const MG_Pipe::MGPipeHandle cso = g_backendSamplerObjects.HandleOf(stateSamplerObject.get());
|
||||
const auto* record = PipeSamplerCsoRecordForHandle(cso);
|
||||
if (record == nullptr) {
|
||||
MGLOG_E_ONCE("MGPipe: sampler %u has no applier record on the handle arm, so its "
|
||||
"parameters cannot be pushed (handle {%u, %u})",
|
||||
stateSamplerObject->GetExternalIndex(), cso.Slot, cso.Gen);
|
||||
return;
|
||||
}
|
||||
if (m_isInitialized && m_syncedSamplerSerial != 0 && m_syncedSamplerSerial == record->Serial) {
|
||||
MGLOG_D("Sampler parameters have not changed for sampler ID: %u, skipping sync.",
|
||||
stateSamplerObject->GetExternalIndex());
|
||||
return;
|
||||
}
|
||||
m_syncedSamplerSerial = record->Serial;
|
||||
pushedParams = &record->Params;
|
||||
} else {
|
||||
#if !MOBILEGL_PIPE_LEGACY_MEMOS
|
||||
// UNREACHABLE: ResolveSamplerSubsystemArm stops at its first call when the bit is
|
||||
// clear and the pre-handle arm is not compiled. Kept, and kept loud.
|
||||
MGLOG_E_ONCE("MGPipe: the sampler subsystem bit is clear and "
|
||||
"MOBILEGL_PIPE_LEGACY_MEMOS=0 removed the pre-handle sampler-version "
|
||||
"memo, so this configuration has no arm at all");
|
||||
return;
|
||||
#else
|
||||
Uint currentSamplerVersion = stateSamplerObject->GetVersion();
|
||||
if (m_isInitialized && m_syncedSamplerVersion == currentSamplerVersion) {
|
||||
MGLOG_D("Sampler parameters have not changed for sampler ID: %u, skipping sync.",
|
||||
stateSamplerObject->GetExternalIndex());
|
||||
return;
|
||||
}
|
||||
|
||||
m_syncedSamplerVersion = currentSamplerVersion;
|
||||
pushedParams = &stateSamplerObject->GetAllSamplerParameters();
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
Uint currentSamplerVersion = stateSamplerObject->GetVersion();
|
||||
if (m_isInitialized && m_syncedSamplerVersion == currentSamplerVersion) {
|
||||
MGLOG_D("Sampler parameters have not changed for sampler ID: %u, skipping sync.",
|
||||
@@ -11439,11 +11524,16 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
}
|
||||
|
||||
m_syncedSamplerVersion = currentSamplerVersion;
|
||||
#endif
|
||||
|
||||
MGLOG_D("Syncing sampler with backend ID %u to backend for state ID %u", m_backendSamplerId,
|
||||
stateSamplerObject->GetExternalIndex());
|
||||
|
||||
#if MOBILEGL_PIPE_PUSH
|
||||
const SamplerParameters& samplerParams = *pushedParams;
|
||||
#else
|
||||
const auto& samplerParams = stateSamplerObject->GetAllSamplerParameters();
|
||||
#endif
|
||||
|
||||
#define SYNC_SAMPLER_PARAM_IF_CHANGED(internalName, glName, type) \
|
||||
if (m_cacheSamplerParameters.internalName != samplerParams.internalName) { \
|
||||
|
||||
@@ -2254,6 +2254,22 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// stale as one built before a relink - while the sampler half, which really is
|
||||
// re-issued per draw, needs nothing of the sort.
|
||||
Uint32 GetSyncedImageUnitVersion() const { return m_syncedImageUnitVersion; }
|
||||
#if MOBILEGL_PIPE_PUSH
|
||||
// P4a (D-B3, D-H5): the ShaderCso record's Serial this backend program was built
|
||||
// from. It is what the draw path's nine-clause rebuild condition reads on the handle
|
||||
// arm INSTEAD OF the two frontend versions above - one server-owned counter that
|
||||
// moves on every create_shader_state the applier applies to this handle, including a
|
||||
// RE-create on the same handle, which is how a relink travels (Gen moves only on slot
|
||||
// reuse, never on a respecify).
|
||||
//
|
||||
// THE CLAUSE COUNT DOES NOT SHRINK, and a brief that treated create_shader_state as
|
||||
// self-contained would produce a per-draw rebuild: the other eight inputs - the draw
|
||||
// FBO's snorm/unorm clamp masks, the fragColor broadcast count, the storage-block
|
||||
// binding signature, the atomic-counter set, the live image formats and the patch
|
||||
// parameters - are all still specialised at the verb, from state this backend holds.
|
||||
// 0 means "never stamped", which is a guaranteed miss (applier serials start at 1).
|
||||
Uint64 GetSyncedShaderCsoSerial() const { return m_syncedShaderCsoSerial; }
|
||||
#endif
|
||||
// Whether the (unit, bound format) pairs this program's FORMAT-LESS image uniforms
|
||||
// resolve to are still the ones its ESSL was generated against.
|
||||
//
|
||||
@@ -2353,6 +2369,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
BufferImpl::UboRingAllocation m_globalUboRingAllocation;
|
||||
Uint32 m_syncedLinkVersion = ~0u;
|
||||
Uint32 m_syncedImageUnitVersion = ~0u;
|
||||
#if MOBILEGL_PIPE_PUSH
|
||||
// P4a's replacement for the two above on the handle arm; see GetSyncedShaderCsoSerial.
|
||||
// Push-only, so the pull build's object is byte-for-byte the pre-P4a one (D-P).
|
||||
Uint64 m_syncedShaderCsoSerial = 0;
|
||||
#endif
|
||||
// Image units addressed by the program's FORMAT-LESS image uniforms, and the digest
|
||||
// of the (unit, format) pairs the generated ESSL baked. Empty/0 for every program
|
||||
// that declares a format on all of its images, which is the overwhelming majority -
|
||||
@@ -2466,6 +2487,19 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
Bool m_isInitialized = false;
|
||||
SamplerParameters m_cacheSamplerParameters;
|
||||
Uint16 m_syncedSamplerVersion = 0;
|
||||
#if MOBILEGL_PIPE_PUSH
|
||||
// P4a (D-B3): the SamplerCso record's Serial at the last completed sync. It replaces
|
||||
// m_syncedSamplerVersion, which stays beside it because the pre-handle arm compiles
|
||||
// under MOBILEGL_PIPE_LEGACY_MEMOS through P3a/P4a (ARCHITECTURE.md:369).
|
||||
//
|
||||
// The two are not interchangeable and that is the point: the frontend version is per
|
||||
// OBJECT, while the serial is per CONTENT-ADDRESSED CSO, and two frontend samplers
|
||||
// with identical parameters share one CSO and therefore one serial - so under the
|
||||
// handle arm the second of them costs no driver call at all.
|
||||
//
|
||||
// Push-only, so the pull build's object is byte-for-byte the pre-P4a one (D-P).
|
||||
Uint64 m_syncedSamplerSerial = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
void UnbindSampler(Uint unit);
|
||||
|
||||
Reference in New Issue
Block a user