mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-10 13:18:31 +09:00
79 lines
4.3 KiB
C++
79 lines
4.3 KiB
C++
// MobileGL - MobileGL/MG_Util/ShaderTranspiler/CompileEnv.h
|
|
// Copyright (c) 2025-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
|
|
|
|
#pragma once
|
|
#include <Includes.h>
|
|
#include <Config.h>
|
|
#include <MG_Backend/BackendObject.h>
|
|
|
|
namespace MobileGL::MG_Util::ShaderTranspiler {
|
|
// everything outside (stage, source) this reads - advertised extensions and backend limits -
|
|
// so the transformation is a pure function of its three arguments and can run on a worker
|
|
// thread.
|
|
//
|
|
// Why it exists (P1): every one of those reads is a reach-back into
|
|
// MG_Backend::pActiveBackendObject / gBackendFunctionsTable, and one of them
|
|
// (GL_MAX_COMPUTE_WORK_GROUP_SIZE) is a *real driver call* that on the DirectGLES
|
|
// backend silently no-ops off the context thread - which would turn a perfectly legal
|
|
// `local_size_z` into COMPILE_STATUS=FALSE the moment compilation moved to a worker.
|
|
// Snapshotting the whole set once per context, on the GL thread, removes every
|
|
// reach-back at once and makes the pipeline a pure function of (stage, source, env).
|
|
//
|
|
// Lifetime: captured lazily on first use by GLState::GLContext::GetCompileEnv(), and
|
|
// RE-captured if the active backend object changes. Immutable once published; held by
|
|
// value/`SharedPtr<const CompileEnv>` so a worker can never observe a torn update.
|
|
//
|
|
// Memo-hazard rule: `fingerprint` hashes every member above it and is part of the P0b
|
|
// ShaderPreprocessCache key, so a memo computed against one env can never be returned
|
|
// against another. ADDING A FIELD HERE MEANS ADDING IT TO ComputeFingerprint().
|
|
struct CompileEnv {
|
|
// --- compute limits: the ONLY former real-driver read in the pipeline ---
|
|
// GL_MAX_COMPUTE_WORK_GROUP_SIZE, already max()'d with the frontend minimum.
|
|
Uint maxComputeWorkGroupSize[3] = {1024, 1024, 64};
|
|
// GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, likewise.
|
|
Uint64 maxComputeWorkGroupInvocations = 1024;
|
|
|
|
// --- backend identity + limits ---
|
|
// Unknown means "no backend was active at capture time". Every consumer keeps the
|
|
// exact no-backend fallback it had before: extensions read as advertised, limits
|
|
// read as the frontend defaults.
|
|
BackendType backend = BackendType::Unknown;
|
|
MG_Backend::DynamicBackendParameters params{}; // by value, never by reference
|
|
Vector<GLExtension> advertisedExtensions;
|
|
|
|
Uint64 fingerprint = 0; // set by CaptureCompileEnv()
|
|
|
|
Bool HasBackend() const { return backend != BackendType::Unknown; }
|
|
// Matches the historical rule exactly: with no active backend every extension counts
|
|
// as advertised, because the frontend then has nothing to gate against.
|
|
Bool IsExtensionAdvertised(GLExtension extension) const {
|
|
if (!HasBackend()) return true;
|
|
return std::find(advertisedExtensions.begin(), advertisedExtensions.end(), extension) !=
|
|
advertisedExtensions.end();
|
|
}
|
|
};
|
|
|
|
// Hashes every semantically relevant member. Public so a test can assert that two
|
|
// different envs really do produce different P0b cache keys.
|
|
Uint64 ComputeCompileEnvFingerprint(const CompileEnv& env);
|
|
|
|
// GL thread only: this is where the GL_MAX_COMPUTE_WORK_GROUP_SIZE queries live now.
|
|
SharedPtr<const CompileEnv> CaptureCompileEnv();
|
|
|
|
// The env a context-less caller gets: exactly what CaptureCompileEnv() would produce
|
|
// with no active backend. Used by the unit tests that drive the transpiler directly and
|
|
// by the internal shader objects that compile before any context exists.
|
|
const SharedPtr<const CompileEnv>& GetDefaultCompileEnv();
|
|
|
|
// The env of the current GL context, or GetDefaultCompileEnv() when there is none.
|
|
// GL thread only (it may trigger a capture). This is the compatibility shim for the
|
|
// handful of entry points that still resolve their env implicitly; the pipeline itself
|
|
// always takes an explicit `const CompileEnv&`.
|
|
const SharedPtr<const CompileEnv>& GetCurrentCompileEnv();
|
|
} // namespace MobileGL::MG_Util::ShaderTranspiler
|