[Fix] (MG_State): allocate program and shader names from one shared name space

GL 3.3 core 2.11 puts program and shader names in one name space: a shader
name passed where a program is expected must fail with INVALID_OPERATION,
and vice versa. Two independent IndexGenerators handed out colliding names
(shader 2 and program 2 could coexist), so CheckProgramNameValidity resolved
a shader handle to an unrelated linked program and the error checks in
KHR-GL30.get_uniform_tests.get_uniform were silently swallowed - the case
only ever passed because the collided program happened to reject the queried
location. One shared generator keeps the names disjoint; the per-kind object
tables are unchanged.
This commit is contained in:
BZLZHH
2026-08-08 01:25:37 -04:00
parent 867fe3e0ef
commit 81bcbd6c14
2 changed files with 9 additions and 7 deletions
@@ -11,7 +11,7 @@
namespace MobileGL::MG_State::GLState {
Uint ProgramState::CreateProgram() {
Uint programId = 0;
m_programIndexGenerator.Generate(1, &programId);
m_programShaderNameGenerator.Generate(1, &programId);
EnsureIndexAvail(programId, m_programObjects);
auto programObject = MakeShared<ProgramObject>(programId);
if (programObject == nullptr) return 0;
@@ -43,7 +43,7 @@ namespace MobileGL::MG_State::GLState {
// that were flagged with glDeleteShader while still attached.
const Vector<SharedPtr<ShaderObject>> attachedShaders = programObject->GetAttachedShaders();
programObject.reset();
m_programIndexGenerator.Delete(program);
m_programShaderNameGenerator.Delete(program);
for (const auto& shader : attachedShaders) {
const Uint shaderName = shader->GetExternalIndex();
if (CheckIndexAvail(shaderName, m_shaderObjects) && m_shaderObjects[shaderName] == shader) {
@@ -77,7 +77,7 @@ namespace MobileGL::MG_State::GLState {
Uint ProgramState::CreateShader(ShaderStage stage) {
Uint shaderId = 0;
m_shaderIndexGenerator.Generate(1, &shaderId);
m_programShaderNameGenerator.Generate(1, &shaderId);
EnsureIndexAvail(shaderId, m_shaderObjects);
auto shaderObject = MakeShared<ShaderObject>(stage, shaderId);
if (shaderObject == nullptr) return 0;
@@ -121,7 +121,7 @@ namespace MobileGL::MG_State::GLState {
if (shaderObject == nullptr || !shaderObject->GetDeleteStatus()) return;
if (ShaderHasGLVisibleAttachment(shaderObject)) return;
shaderObject.reset();
m_shaderIndexGenerator.Delete(shader);
m_programShaderNameGenerator.Delete(shader);
}
Bool ProgramState::ValidateShaderObject(Uint shader) const {
@@ -52,10 +52,12 @@ namespace MobileGL::MG_State::GLState {
vec.resize(idx + 1);
}
IndexGenerator<Uint> m_programIndexGenerator;
// Programs and shaders share one GL name space (GL 3.3 core 2.11: a shader
// name passed where a program is expected must be recognized as a shader and
// rejected with INVALID_OPERATION, and vice versa). One generator for both
// object kinds keeps the names disjoint; the object tables stay separate.
IndexGenerator<Uint> m_programShaderNameGenerator;
Vector<SharedPtr<ProgramObject>> m_programObjects;
IndexGenerator<Uint> m_shaderIndexGenerator;
Vector<SharedPtr<ShaderObject>> m_shaderObjects;
SharedPtr<ProgramObject> m_currentProgram;