From 81bcbd6c1469e7d7fb1a648a7fa7dc313583a8cc Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Sat, 8 Aug 2026 01:25:37 -0400 Subject: [PATCH] [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. --- MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp | 8 ++++---- MobileGL/MG_State/GLState/ProgramState/ProgramState.h | 8 +++++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp b/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp index 2aeb76e7..bf2fcd48 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp @@ -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(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> 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(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 { diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramState.h b/MobileGL/MG_State/GLState/ProgramState/ProgramState.h index 5fbd4553..50d580b8 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramState.h +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramState.h @@ -52,10 +52,12 @@ namespace MobileGL::MG_State::GLState { vec.resize(idx + 1); } - IndexGenerator 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 m_programShaderNameGenerator; Vector> m_programObjects; - - IndexGenerator m_shaderIndexGenerator; Vector> m_shaderObjects; SharedPtr m_currentProgram;