mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
108 lines
4.8 KiB
C++
108 lines
4.8 KiB
C++
// MobileGL - MobileGL/MG_IntegrationTest/Harness/P4aSeamPeek.cpp
|
|
// Copyright (c) 2026 MobileGL-Dev
|
|
// Licensed under the GNU Lesser General Public License v3.0:
|
|
// https://www.gnu.org/licenses/gpl-3.0.txt
|
|
// https://www.gnu.org/licenses/lgpl-3.0.txt
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
// End of Source File Header
|
|
|
|
#include "P4aSeamPeek.h"
|
|
|
|
#if !defined(__ANDROID__)
|
|
#include <MG_Pipe/MGPipe.h>
|
|
#if MOBILEGL_PIPE_PUSH
|
|
#include <MG_Pipe/PipeApply.h>
|
|
#include <MG_State/GLState/Core.h>
|
|
#include <MG_Backend/DirectGLES/Managers.h>
|
|
#include <MG_Backend/DirectGLES/DirectGLES.h>
|
|
#define MGITEST_P4A_SEAM_PEEK_LIVE 1
|
|
#endif
|
|
#endif
|
|
|
|
namespace MGITest {
|
|
|
|
#if defined(MGITEST_P4A_SEAM_PEEK_LIVE)
|
|
namespace {
|
|
namespace MGP = MobileGL::MG_Pipe;
|
|
namespace MGB = MobileGL::MG_Backend::DirectGLES;
|
|
|
|
// "Is Espryt the backend running" - the same test PipeApplyPeek.cpp makes through a twin:
|
|
// on Magma no ES entry point was ever resolved and every member of g_GLESFuncs is null.
|
|
// It is asked BEFORE SamplerSubsystemEnabled(), which is Espryt's own latch and must not
|
|
// be resolved on a process whose backend is not Espryt.
|
|
bool EsprytIsRunning() { return MGB::g_GLESFuncs.glBindSampler != nullptr; }
|
|
} // namespace
|
|
|
|
bool PeekEsprytSamplerHandleArmIsLive(bool* outLive) {
|
|
if (outLive == nullptr) return false;
|
|
if (!EsprytIsRunning()) return false;
|
|
*outLive = MGB::SamplerSubsystemEnabled();
|
|
return true;
|
|
}
|
|
|
|
bool PeekEsprytFramebufferHandleArmIsLive(bool* outLive) {
|
|
if (outLive == nullptr) return false;
|
|
if (!EsprytIsRunning()) return false;
|
|
*outLive = MGB::FramebufferSubsystemEnabled();
|
|
return true;
|
|
}
|
|
|
|
bool PeekPipeShaderImageWindow(PipeShaderImageWindowPeek* out) {
|
|
if (out == nullptr) return false;
|
|
const MGP::MGPipeApplierState& applier = MGP::MGPipeApplier();
|
|
out->Start = static_cast<unsigned>(applier.ShaderImageStart);
|
|
out->Count = static_cast<unsigned>(applier.ShaderImageCount);
|
|
out->Serial = static_cast<unsigned long long>(applier.ShaderImagesSerial);
|
|
return true;
|
|
}
|
|
|
|
bool PeekEsprytUnitSampler(unsigned unit, unsigned glSamplerName, EsprytUnitSamplerPeek* out) {
|
|
if (out == nullptr) return false;
|
|
if (!EsprytIsRunning()) return false;
|
|
if (!MobileGL::MG_State::pGLContext) return false;
|
|
const MGP::MGPipeApplierState& applier = MGP::MGPipeApplier();
|
|
if (unit >= applier.BoundSamplerStates.size() || unit >= MGB::SamplerImpl::g_boundSamplersCache.size()) {
|
|
return false;
|
|
}
|
|
*out = EsprytUnitSamplerPeek{};
|
|
|
|
// Espryt's own binding shadow: every glBindSampler this backend issues routes through it
|
|
// (BackendSamplerObject::Bind / UnbindSampler), so it IS what the driver holds.
|
|
if (MGB::SamplerImpl::BackendSamplerObject* const bound = MGB::SamplerImpl::g_boundSamplersCache[unit]) {
|
|
out->BoundSamplerId = static_cast<unsigned>(bound->GetBackendSamplerId());
|
|
}
|
|
|
|
const MGP::MGPipeHandle cso = applier.BoundSamplerStates[unit];
|
|
out->CsoHandleSlot = static_cast<unsigned>(cso.Slot);
|
|
out->CsoHandleGen = static_cast<unsigned>(cso.Gen);
|
|
out->UnitInsideWindow = unit >= applier.SamplerStateStart &&
|
|
unit - applier.SamplerStateStart < applier.SamplerStateCount;
|
|
// The twin AT THE CSO HANDLE, asked of the same table Espryt asks (FindByHandle): a null
|
|
// here with a live handle is the F-4 shape - a content-addressed handle looked up in a
|
|
// table that only ever held identity-minted slots.
|
|
if (!MGP::MGPipeHandleIsNull(cso)) {
|
|
if (auto* const slot = MGB::SamplerImpl::g_backendSamplerObjects.FindByHandle(cso); slot && *slot) {
|
|
out->CsoTwinSamplerId = static_cast<unsigned>((*slot)->GetBackendSamplerId());
|
|
}
|
|
}
|
|
|
|
// And the twin keyed on the frontend OBJECT, which is what the pre-handle program pass
|
|
// used to mint and bind, so a scenario can say which of the two the driver holds.
|
|
const auto& object = MobileGL::MG_State::pGLContext->GetSamplerObject(
|
|
static_cast<MobileGL::Uint>(glSamplerName));
|
|
if (object) {
|
|
if (auto* const slot = MGB::SamplerImpl::g_backendSamplerObjects.Find(object.get()); slot && *slot) {
|
|
out->IdentityTwinSamplerId = static_cast<unsigned>((*slot)->GetBackendSamplerId());
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
#else
|
|
bool PeekEsprytSamplerHandleArmIsLive(bool*) { return false; }
|
|
bool PeekEsprytFramebufferHandleArmIsLive(bool*) { return false; }
|
|
bool PeekPipeShaderImageWindow(PipeShaderImageWindowPeek*) { return false; }
|
|
bool PeekEsprytUnitSampler(unsigned, unsigned, EsprytUnitSamplerPeek*) { return false; }
|
|
#endif
|
|
|
|
} // namespace MGITest
|